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

2022-03-17 00:00:00 geometry zooming p5.js javascript

我正在尝试缩放鼠标位置,比如在Google地图上。它有点管用,但它会将我想要放大的点移到与原图匹配的任何地方,然后当我在那个点上放大时,它就可以很好地工作。我想我需要将这一点翻译回鼠标,但我不确定如何准确地做到这一点。

这是我画之前的代码:

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

这是我缩放的时间:

  event.preventDefault();
  zoomLocation = {
    x: zoomLocation.x + (mouseX - zoomLocation.x) / zoom,
    y: zoomLocation.y + (mouseY - zoomLocation.y) / zoom
  };
  zoom -= zoomSensitivity * event.delta;
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);
  }
}
body {
  margin: 0
}

button {
  outline: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/addons/p5.dom.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>


解决方案

您正在寻找的是Affine Transformation的应用程序。下面是一个示例,在此示例中,我在Google地图类型缩放效果的鼠标指针位置以增量方式应用变换+缩放:Zoom Effect in p5.js Web Editor。

这是一篇很好的媒体文章,解释了为什么这样做:Zooming at the Mouse Coordinates with Affine Transformations

这是另一篇很好的文章,从数学上解释了它是如何达到效果的:Affine Transformations — Pan, Zoom, Skew

相关文章