在鼠标位置放大 p5.js(包括 jsfiddle)

Kys*_*lox 7 javascript geometry zooming p5.js

我正在尝试缩放鼠标位置,就像谷歌地图上所说的那样。它有点有效,但它改变了我想要放大的点,无论它与原始点匹配。然后,当我放大该点时,它工作得很好。我想我需要将点转换回鼠标,但我不确定如何准确地做到这一点。

这是我绘制之前的代码:

  translate(zoomLocation.x, zoomLocation.y);
  scale(zoom);
  translate(-zoomLocation.x, -zoomLocation.y);
  drawGrid();
Run Code Online (Sandbox Code Playgroud)

这是我缩放时的情况:

  event.preventDefault();
  zoomLocation = {
    x: zoomLocation.x + (mouseX - zoomLocation.x) / zoom,
    y: zoomLocation.y + (mouseY - zoomLocation.y) / zoom
  };
  zoom -= zoomSensitivity * event.delta;
Run Code Online (Sandbox Code Playgroud)

  translate(zoomLocation.x, zoomLocation.y);
  scale(zoom);
  translate(-zoomLocation.x, -zoomLocation.y);
  drawGrid();
Run Code Online (Sandbox Code Playgroud)
  event.preventDefault();
  zoomLocation = {
    x: zoomLocation.x + (mouseX - zoomLocation.x) / zoom,
    y: zoomLocation.y + (mouseY - zoomLocation.y) / zoom
  };
  zoom -= zoomSensitivity * event.delta;
Run Code Online (Sandbox Code Playgroud)
let colors = {
  background: 0,
  gridLines: "white"
};

let nVariables = 4;

let zoom = 1;
let zoomLocation = {
  x: 0,
  y: 0
};
let zoomSensitivity = 0.0002;

function draw() {
  translate(zoomLocation.x, zoomLocation.y);
  scale(zoom);
  translate(-zoomLocation.x, -zoomLocation.y);
  drawGrid();


  stroke("blue");
  ellipse(zoomLocation.x + (mouseX - zoomLocation.x) / zoom, zoomLocation.y + (mouseY - zoomLocation.y) / zoom, 10, 10);

  stroke("red");
  ellipse(zoomLocation.x, zoomLocation.y, 10, 10);

}

function setup() {
  zoomLocation = {
    x: 0,
    y: windowHeight / 2
  }
  createCanvas(windowWidth, windowHeight);
}

function mouseWheel(event) {
  event.preventDefault();
  let oldZoom = zoom;
  zoomLocation = {
    x: zoomLocation.x + (mouseX - zoomLocation.x) / zoom,
    y: zoomLocation.y + (mouseY - zoomLocation.y) / zoom
  };
  zoom -= zoomSensitivity * event.delta;
}

function drawGrid() {
  let nCells = 2 ** nVariables;
  if (nCells > 2048) {
    if (!window.confirm(`You are about to create ${nCells} cells. This might lag your browser. Are you sure?`)) {
      return;
    }
  }
  background(colors.background);
  let gridWidth = windowWidth - 2;
  let gridHeight = min(gridWidth / nCells, windowHeight / 2 - 2);
  let gridY = windowHeight / 2;
  stroke(colors.gridLines);
  line(0, gridY, gridWidth, gridY);
  line(0, gridY + gridHeight, gridWidth, gridY + gridHeight);
  for (let i = 0; i < nCells + 1; i++) {
    line(i * (gridWidth / nCells), gridY, i * (gridWidth / nCells), gridY + gridHeight)
  }

  let curveHeight = 2;

  let drawVariable = (n) => {
    let p1 = {
      x: 1 / (2 ** (n + 1)) * gridWidth,
      y: gridY
    };
    let c1 = {
      x: p1.x,
      y: p1.y + gridWidth / (2 ** n) * curveHeight
    };
    let p2 = {
      y: p1.y
    };
    let c2 = {
      y: c1.y
    };;
    noFill();
    stroke("red");
    if (n == 0) {
      p2.x = gridWidth;
      c2.x = p2.x;
      c1.y = c2.y = p1.y + gridWidth / 2 * curveHeight;
      curve(c1.x, c1.y, p1.x, p1.y, p2.x, p2.y, c2.x, c2.y);
      return;
    }
    for (let i = 3; i < 2 ** (n + 1); i += 2) {
      p2.x = i / (2 ** (n + 1)) * gridWidth
      c2.x = p2.x;
      if ((i - 3) % 4 == 0) {
        curve(c1.x, c1.y, p1.x, p1.y, p2.x, p2.y, c2.x, c2.y);
      } else {
        p1.x = p2.x;
        c1.x = c2.x;
      }
    }
  };

  for (let i = 0; i < nVariables; i++) {
    drawVariable(i);
  }
}
Run Code Online (Sandbox Code Playgroud)

heo*_*noc 3

您正在寻找的是仿射变换的应用程序。下面是一个示例,我在鼠标指针位置逐步应用变换来变换 + 缩放,以实现 Google 地图类型的缩放效果:p5.js Web Editor 中的缩放效果

\n

这是一篇很好的中等文章,解释了为什么它有效:Zooming at the Mouse Coords with Affine Transformations

\n

这是另一篇好文章,其中有一些关于如何实现效果的数学解释:仿射变换 \xe2\x80\x94 平移、缩放、倾斜

\n