如何实现放大缩小的效果 · Issue #278 · spritejs/spritejs · GitHub
Skip to content

如何实现放大缩小的效果 #278

Open

Description

@2ming

查阅了文档api,都没有发现相关的方法。
需求:想以画布的某个点为中心,放大缩小

Activity

  1. akira-cn commented on Aug 18, 2023

    @akira-cn
    Contributor

    直接transform layer元素就行了吧

  2. 2ming commented on Aug 18, 2023

    @2ming
    Author

    我试一下,其实我是想实现一个画板的类似功能,需要放大,缩小,拖动元素,大概写了一些,感觉不太方便
    layer上面有一个scale属性,可以放大缩小,但是放大或者缩小后的元素pos偏移的x,y有点对应不上,我按照放大的比例去做一个计算还是有些问题

    下面是我简单写的一个实例

    import * as spritejs from "spritejs";
    const { Scene, Path, Group, SpriteSvg } = spritejs;
    
    export function drawScene(container, options = {}) {
      //获取容器的宽高
      const { width, height } = container.getBoundingClientRect();
      debugger;
      const scene = new Scene({
        container,
        mode: "stickyTop",
        width,
        height,
        ...options,
      });
      const layer = scene.layer({
        // handleEvent: false,
      });
    
      const background = new Group({
        width,
        height,
      });
      layer.append(background);
      const eventStore = {
        //当前按住的按键
        keyCode: null,
        //当前选中元素
        parts: null,
        scale: 1,
        //鼠标按下的位置
        offsetX: 0,
        offsetY: 0,
        mouseX: 0,
        mouseY: 0,
        moveEvt: null
      };
    
      layer.attr({
        scale: [1, 1],
        // bgcolor: "white",
        borderWidth: 1,
      });
    
      function getViewport(val) {
        return val*eventStore.scale
      }
                          
      scene.addEventListener("mousedown", (evt) => {
        const { target, x, y } = evt;
        eventStore.mouseX = x;
        eventStore.mouseY = y;
        console.log(evt);
        if (target.attributes.type == "path") {
          eventStore.parts = evt.target;
        }
      });
      // document.addEventListener("mouseup", (evt) => {
    
      // })
      document.addEventListener("mouseup", (evt) => {
        const { mouseX, mouseY, keyCode, offsetX, offsetY, moveEvt} = eventStore;
        const { x, y } = moveEvt || {};
        console.log("====================");
        //重置选中元素
        eventStore.parts = null;
    
        //记录画布偏移的位置
        if ((mouseX || mouseY) && keyCode == 32) {
          
          eventStore.offsetX =offsetX + x - mouseX;
          eventStore.offsetY =offsetY + y - mouseY;
          background.attr({
            pos: [eventStore.offsetX, eventStore.offsetY],
          });
    
        }
        eventStore.keyCode = null;
    
        //重置鼠标的位置
        eventStore.mouseX = 0;
        eventStore.mouseY = 0;
      });
    
      scene.addEventListener("mousemove", (evt) => {
        const { x, y } = evt;
        const { mouseX, mouseY, offsetX, offsetY } = eventStore;
    
        if (eventStore.keyCode == 32 && mouseX && mouseY) {
          eventStore.moveEvt = evt;
          background.attr({
            // scale: [1, 1],
            pos: [offsetX + x - mouseX, offsetY + y - mouseY],
            // x: offsetX + x - mouseX,
            // y: offsetY + y - mouseY
          });
          // scene.attr({
          //   scale: [1, 1],
          //   pos: [eventStore.offsetX, eventStore.offsetY]
          // });
          // layer.getOffsetPosition(offsetX + x - mouseX, offsetY + y - mouseY)
        } else if (eventStore.parts) {
          // evt.stopPropagation();
          eventStore.parts.attr("pos", [x - offsetX, y - offsetY]);
        }
      });
    
      document.addEventListener("keydown", (evt) => {
        evt.preventDefault();
        const { keyCode } = evt;
        eventStore.keyCode = keyCode;
        eventStore.parts = null
      });
    
      document.addEventListener("keyup", (evt) => {
        evt.preventDefault();
        eventStore.keyCode = null;
        //重置鼠标的位置
        eventStore.mouseX = 0;
        eventStore.mouseY = 0;
      });
      document.addEventListener("wheel", (evt) => {
        evt.preventDefault();
        if (eventStore.keyCode == 32){                                                                         
          console.log(eventStore.scale, evt)
          eventStore.scale += evt.deltaY * -0.001;
          eventStore.offsetX = evt.deltaY * -0.001;
          eventStore.offsetY = evt.deltaY * -0.001;
      
          // Restrict scale
          eventStore.scale = Math.min(Math.max(0.125, eventStore.scale), 4);
          console.log(eventStore.scale)
          background.attr({
            scale: [eventStore.scale, eventStore.scale],
          });
        }
      });
    
      return {
        layer: background,
        scene,
      };
    }
  3. akira-cn commented on Nov 6, 2023

    @akira-cn
    Contributor

    你先设置anchor属性或者transform-origin 属性,然后再缩放,transform-origin 就是缩放的原点,这个和css操作dom元素是一样的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions