图形编辑器:场景坐标、视口坐标以及它们之间的转换

开发 前端
视口坐标是场景坐标平移并缩放后的结果,所以视口转场景,需要除以 Zoom 再加上偏移值。在图形编辑器中,会有相当多的坐标系转换逻辑,这两个坐标系的关系需要好好消化理解。

大家好,我是前端西瓜哥。

图形编辑器的坐标系有两种。

一个是场景(scene)坐标系,一个是 视口(viewport)坐标系。视口就是场景的一个子区域。

图片

假设我们的视口的原点,离场景原点的坐标水平和垂直距离分别为 scrollX 和 scrollY。

先 不考虑缩放,假设我们在视口坐标上的某个地方点击了一下,这个坐标是 ​​(x, y)​​。这个坐标在场景坐标系中,就是:

const sceneX = scrollX + x;
const sceneY = scrollY + y;
  • 1.
  • 2.

挺简单。

视口坐标转换为场景坐标

下面我们引入画布缩放,即画布可以缩小和放大,对应的一个比例值 zoom。

视口中的某个坐标 (x, y) 在场景坐标系,则是 :

function viewportCoordsToSceneCoords(x, y, scrollX, scrollY, zoom) {
  return {
  x: scrollX + x / zoom,
  y: scrollY + y / zoom
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

之所以要用 x 除以 zoom,是因为此时视口中展示的是缩放后的图形,里面的坐标都是缩放后的值。所以需要先转换为 zoom 值为 1 对应的真实值。

场景坐标转换为视口坐标

然后我们反过来,如何从场景坐标 (x, y) 转换为视口坐标?将前面的公式做等式变换即可:

function sceneCoordsToViewportCoords(x, y, scrollX, scrollY, zoom) {
  return {
  x: (x - scrollX) * zoom,
  y: (y - scrollY) * zoom
  };
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

我们通常是使用按键加滚轮的方式让画布以光标为中心进行缩放,或按按钮进行缩放,

为了让缩放后的场景还能对上缩放前光标的位置,我们需要计算缩放后的 scrollX 和 scrollY,进行校准。

核心思路是 保持缩放前点到视口左上角距离(视口坐标系)相同。

function calScrollVal(cx, cy, prevZoom, zoom, scrollX, scrollY) {
  // 先计算目标点的场景坐标(这里 cx 和 cy 是基于视口坐标系的)
  const { x: sceneX, y: sceneY } = viewportCoordsToSceneCoords(cx, cy, prevZoom, scrollX, scrollY);
  // 缩放后画布缩放比变成了 zoom,距离视口左上角的距离变成了 cx / zoom
  // 减去这个距离,就是新的 scrollX 了。
  const newScrollX = sceneX - cx / zoom;
  const newScrollY = sceneY - cy / zoom;

  return {
    x: newScrollX,
    y: newScrollY
  };
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

再说点别的。

可能会有这么一种情况,就是实际的视口区域的原点坐标有一些偏移,偏移了 offsetX 和 offsetY,见下图。

图片

我们只需要将前面代码中的 scrollX 变成 (scrollX + offsetX),scrollY 变成 (scrollY + offsetY),其他不变。

就这些了。

总结一下,视口坐标是场景坐标平移并缩放后的结果,所以视口转场景,需要除以 zoom 再加上偏移值。在图形编辑器中,会有相当多的坐标系转换逻辑,这两个坐标系的关系需要好好消化理解。

责任编辑:姜华 来源: 前端西瓜哥
相关推荐

2023-02-02 14:07:00

图形编辑器Canvas

2023-10-10 16:04:30

图形编辑器格式转换

2023-10-19 10:12:34

图形编辑器开发缩放图形

2023-01-18 08:30:40

图形编辑器元素

2023-02-01 09:21:59

图形编辑器标尺

2023-04-07 08:02:30

图形编辑器对齐功能

2023-09-26 07:39:21

2023-08-31 11:32:57

图形编辑器contain

2023-04-10 08:45:44

图形编辑器排列移动功能

2023-09-07 08:24:35

图形编辑器开发绘制图形工具

2023-02-06 16:59:57

Canvas编辑器

2023-10-08 08:11:40

图形编辑器快捷键操作

2023-05-09 08:15:32

图形编辑器撤销重做功能

2023-09-11 09:02:31

图形编辑器模块间的通信

2024-01-08 08:30:05

光标图形编辑器开发游标

2023-02-09 07:02:30

图形编辑器修改图形

2023-03-03 10:24:51

2023-08-28 08:10:50

Hex图形编辑器

2023-06-12 08:22:56

图形编辑器工具

2024-11-27 09:02:01

文本编辑canvas图形编辑器
点赞
收藏

51CTO技术栈公众号