JS图形编辑器场景坐标视口坐标的相互转换

 更新时间:2023年01月16日 10:09:51   作者:西瓜  
这篇文章主要为大家介绍了JS图形编辑器之场景坐标视口坐标的相互转换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

图形编辑器坐标系

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

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

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

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

const sceneX = scrollX + x;
const sceneY = scrollY + y;

挺简单。

视口坐标转换为场景坐标

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

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

function viewportCoordsToSceneCoords(x, y, scrollX, scrollY, zoom) {
  return {
  x: scrollX + x / zoom,
  y: scrollY + y / zoom
  }
}

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

场景坐标转换为视口坐标

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

function sceneCoordsToViewportCoords(x, y, scrollX, scrollY, zoom) {
  return {
  x: (x - scrollX) * zoom,
  y: (y - scrollY) * zoom
  };
}

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

为了让缩放后的场景还能对上缩放前光标的位置,我们需要计算缩放后的 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
  };
}

再说点别的。

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

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

就这些了。

总结一下,视口坐标是场景坐标平移并缩放后的结果,所以视口转场景,需要除以 zoom 再加上偏移值。在图形编辑器中,会有相当多的坐标系转换逻辑,这两个坐标系的关系需要好好消化理解,更多关于JS场景视口坐标转换的资料请关注脚本之家其它相关文章!

相关文章

  • 微信小程序 按钮滑动的实现方法

    微信小程序 按钮滑动的实现方法

    这篇文章主要介绍了微信小程序 按钮滑动的实现方法的相关资料,希望通过本文能帮助到大家实现这样的功能,需要的朋友可以参考下
    2017-09-09
  • JavaScript的模块化开发框架Sea.js上手指南

    JavaScript的模块化开发框架Sea.js上手指南

    Sea.js的目的是追求简单的代码书写和组织方式,Sea.js并没有过多功能而是主要对前端程序的部署结构作出约束,下面我们就来看一下JavaScript的模块化开发框架Sea.js上手指南:
    2016-05-05
  • 微信小程序 loading(加载中提示框)实例

    微信小程序 loading(加载中提示框)实例

    这篇文章主要介绍了微信小程序 loading(加载中提示框)实例的相关资料,需要的朋友可以参考下
    2016-10-10
  • JavaScript专题之underscore防抖实例学习

    JavaScript专题之underscore防抖实例学习

    这篇文章主要为大家介绍了JavaScript专题之underscore防抖实例学习,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • JavaScript Broadcast Channel API使用学习

    JavaScript Broadcast Channel API使用学习

    这篇文章主要为大家介绍了JavaScript的api学习之Broadcast Channel API使用方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • rollup输出的6种格式详解

    rollup输出的6种格式详解

    这篇文章主要为大家介绍了rollup输出的6种格式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 微信小程序 后台登录(非微信账号)实例详解

    微信小程序 后台登录(非微信账号)实例详解

    这篇文章主要介绍了微信小程序 后台登录(非微信账号)实例详解的相关资料,需要的朋友可以参考下
    2017-03-03
  • 微信小程序 摇一摇抽奖简单实例实现代码

    微信小程序 摇一摇抽奖简单实例实现代码

    这篇文章主要介绍了微信小程序 摇一摇抽奖简单实例实现代码的相关资料,这里实现摇一摇抽奖的功能,需要的朋友可以参考下
    2017-01-01
  • JavaScript Dom对象的操作

    JavaScript Dom对象的操作

    这篇文章主要介绍了JavaScript Dom对象的操作,文张以浏览器网页就是一个Dom树形结构做为核心,然后根据核心进行更新Dom节点、获得Dom节点、删除一个Dom节点、添加一个新的节点操作,下面文章是详细内容,需要的朋友可以参考以下
    2021-11-11
  • 前端通过JavaScript创建修改CAD图形详情

    前端通过JavaScript创建修改CAD图形详情

    这篇文章介绍JavaScript创建修改CAD图形,创建修改CAD图形,一般是基于AutoCAD进行二次开发,ObjectARX是AutoDesk公司针对AutoCAD平台上的二次开发而推出的一个开发软件包,它提供了以C++为基础的面向对象的开发环境及应用程序接口,能真正快速的访问AutoCAD图形数据库
    2021-10-10

最新评论