前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >图形工具的另一种以光标为中心缩放实现

图形工具的另一种以光标为中心缩放实现

作者头像
前端西瓜哥
发布2023-08-18 13:26:01
2410
发布2023-08-18 13:26:01
举报

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

最近有读者咨询我一个缩放问题。

应该是他要给项目做缩放功能,然后看到了 我图形编辑器缩放的文章,想要跟着我文章的思路移植到他的项目上。

但他搞不定,来找我。我给他搞定了,然后就有了这篇文章。

他给了我一个最小实现 demo。

我看了下,他用的是 zrender 渲染器(ECharts 的底层渲染器)。

和我之前写的文章不同的是,他用了 zrender 提供的 group 元素,给它设置了 xy 和 scale。然后绘制的元素都放在这个容器元素下。

我之前写的文章呢,没有这个 group 的概念,是给所有的坐标去乘一个视图矩阵,做坐标系的转换,能够正确落在适口矩形的新的位置。

这个 group 就有点像视口,虽然底层思路是一样的,但实现细节有很大不同。

移动

首先是拖拽移动画布的逻辑,变得简单了,直接 dx dy 加到 goup 的 x y 上就行了,不用除以 scale。

画布坐标转 group 下的坐标

画布坐标是缩放后坐标,转为 group 下的坐标,要先减去 group.x 或 group.y,然后除以 scale,得到缩放前的坐标。

代码语言:javascript
复制
const xInGroup = (x - group.x) / scale;
const yInGroup = (y - group.y) / scale;

光标缩放

然后是重点,缩放逻辑。

和我之前写的文章一样,要点还是:你原来在 group 的哪个相对位置进行缩放的,缩放后也得在那个位置

你要改 group 的 xy。

打个比方,假设这个点原来在相对 group 宽和高的四分之一处,假设 group 的 x y 是 (0, 0),宽高是 12 和 20,那点坐标就是 (3, 5)。

先不改变 group 的 xy,缩放为原来的 2 倍,点跑到了哪里?(6, 10)。

我们要让它表现为是以这个点进行缩放的,那我们就得把这个点移动对上原来的位置,于是让 group 的 x y 分别移动 -3 -5。

上面动图左上角矩形宽高就是要求的相对位移 dx 和 dy。

把图画出来,就好理解了。

我们要求的是这个图中的绿色向量。

列个式子算一下:

代码语言:javascript
复制
const dx 
  = -(scale / prevScale * (cx -group.x) - (cx - group.x))
  = -((cx - group.x) * (scale / prevScale - 1))
  = (cx - group.x) * (1 - scale / prevScale)
   
// dy 同理
const dy 
  = (cy - group.y) * (1 - scale / prevScale)

代码:

代码语言:javascript
复制
zr.on("mousewheel", function (e) {
  const prevScale = scale;

  scale < 0.2 ? (scale = 0.2) : scale;
  scale += e.wheelDelta > 0 ? 0.1 : -0.1;

  const dx = (e.offsetX - group.x) * (1 - scale / prevScale);
  const dy = (e.offsetY - group.y) * (1 - scale / prevScale);

  group.attr({
    scaleX: scale,
    scaleY: scale,
    x: group.x + dx,
    y: group.y + dy
  });
});

演示:

线上示例 demo:

https://codesandbox.io/s/vm8fh4?file=/src/index.ts

这位读者他用了特有的 origin 属性。这个 origin 可以用来指定 group 的缩放中心。

如果用 origin,你还是要改 xy 的,跑不了,别想太多。不仅如此,逻辑还更复杂了,毕竟又引入了新事物。不建议用。

如果你用 svg 方案,也是同理。

这里给一个 svg.js 的缩放在线示例:

https://codesandbox.io/s/vsylk4?file=/src/index.ts

结尾

缩放的要点在于,两个坐标系转换关系,要多画图推导推导。

我是前端西瓜哥,关注我,学习更多前端可视化和图形编辑器知识。

相关阅读,

图形编辑器开发:缩放至适应画布

图形编辑器开发:以光标为中心缩放画布

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

图形编辑器开发:最基础但却复杂的选择工具

图形编辑器:工具管理和切换

图形编辑器:底层设计

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端西瓜哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 移动
  • 画布坐标转 group 下的坐标
  • 光标缩放
  • 结尾
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档