【缩放】实现svg以鼠标为焦点缩放

一、缩放原理
viewBox="x, y, width, height"// x:左上角横坐标,y:左上角纵坐标,width:宽度,height:高度

以鼠标为焦点缩放 = 以原点为焦点缩放 + 位移。利用svg的属性viewbox:x,y控制位移,width,height控制缩放。

在当前视窗内,改变viewBox的width与height即可实现以左上角为原点的缩放,故只需计算以左上角为焦点缩放后和以鼠标位置为焦点缩放后两个原点的偏移量即可。后文不再赘述scale与viewbox的关系。

二、计算偏移量(缩放前后的原点偏移量)
  1. 得到当前缩放倍数下x、y轴鼠标位置与原点的距离:获取鼠标位置和画布原点位置,并做差值再除以当前缩放倍数。
const x = ($event.clientX - CANVAS_LEFT) / this.transform.scale;

const y = ($event.clientY - CANVAS_TOP) / this.transform.scale;
  1. 分别得到x、y轴缩放后鼠标位置与新原点的距离:原距离 / 缩放前倍数 * 缩放后倍数

以鼠标位置为基准计算新原点位置

  1. 得到偏移量:2与1做差即得到两个原点的偏移量

  2. 为viewBox赋值

三、伪代码示例
// 按住ctrl后,不能通过滚轮使页面滚动

if ($event.ctrlKey || $event.metaKey) {
  $event.preventDefault();
  $event.stopPropagation();
  let preScale = Math.max(this.transform.scale, 0.5);
  if ($event.deltaY < 0 && ($event.ctrlKey || $event.metaKey) && this.transform.scale < 2) {
    preScale = this.transform.scale;
    this.transform.scale = this.transform.scale + 0.02;
  }

  if ($event.deltaY > 0 && ($event.ctrlKey || $event.metaKey) && this.transform.scale >= 0.5) {
    preScale = this.transform.scale;
    this.transform.scale = this.transform.scale - 0.02;

  }

  const x = ($event.clientX - CANVAS_LEFT) / this.transform.scale;  // 鼠标位置与左上角在画布中的距离
  const y = ($event.clientY - CANVAS_TOP) / this.transform.scale;

  const offsetX = x * (this.transform.scale - preScale) / preScale;  // 得到偏移量
  const offsetY = y * (this.transform.scale - preScale) / preScale;


  this.transform.translateX += offsetX;
  this.transform.translateY += offsetY;
  // 进行scale与translate到viewBox的换算和赋值
  this.handleTransform();

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • @(HTML5)[canvas与SVG] [TOC] 十一 、SVG HTML体系中,最常用的绘制矢量图的技术是S...
    踏浪free阅读 4,635评论 0 2
  • 使用XML描述的矢量文件W3C标准(1.1):http://www.w3.org/TR/SVG11/浏览器支持情况...
    没汁帅阅读 6,084评论 0 16
  • SVG 可伸缩矢量图形(Scalable Vector Graphics) 使用 XML 格式定义图像 是w3c的...
    小樓me阅读 960评论 0 1
  • CSS参考手册 一、初识CSS3 1.1 CSS是什么 CSS3在CSS2.1的基础上增加了很多强大的新功能。目前...
    没汁帅阅读 3,781评论 1 13
  • 上次介绍了svg的“建筑材料”,这次来介绍“装饰材料” svg可以通过自己本身的属性或者css样式来改变样子。 目...
    c44fce2e629a阅读 296评论 0 0