Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
2ming opened this issue Aug 16, 2023 · 3 comments
Open

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

2ming opened this issue Aug 16, 2023 · 3 comments

Comments

@2ming
Copy link

2ming commented Aug 16, 2023

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

@akira-cn
Copy link
Contributor

直接transform layer元素就行了吧

@2ming
Copy link
Author

2ming commented Aug 18, 2023

我试一下,其实我是想实现一个画板的类似功能,需要放大,缩小,拖动元素,大概写了一些,感觉不太方便
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,
  };
}

@akira-cn
Copy link
Contributor

akira-cn commented Nov 6, 2023

你先设置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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants