We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
通过鼠标滚轮来缩放 canvas ,通过鼠标拖拽 canvas 。
这个需求的讨论来源于 Stack Overflow 上的问题 Zoom Canvas to Mouse Cursor ,作者使用了 SVG 的 createSVGMatrix 来记录 canvas 变换的矩阵,从而完善了缩放和拖拽的效果,这个思路引起了我的兴趣,这里对源码进行些分析。
在线例子 源码
canvas 的 translate、 scale 方法可以自由移动缩放画布,但是无法记录当前的变换状态,导致不能在绘制 canvas 时再使用 translate、 scale 方法等;并且不能获取 canvas 点击事件在矩阵变换后的位置。所以作者对每次变换进行记录,解决了变换状态丢失的问题。
trackTransforms 在源码中的位置:
125 | function trackTransforms(ctx){ ...... 178 | }
trackTransforms 先利用 SVG 对象的 createSVGMatrix 创建了矩阵,这个矩阵保存着所有 canvas 的缩放、倾斜和移动:
var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg'); var xform = svg.createSVGMatrix();
对 canvas 中变换相关的方法进行修改,使每次造成 canvas 变换的操作也对矩阵造成了相应的变换。这样一来就可以通过矩阵记录当前的变换状态,即:变换前的点 -> 矩阵 -> 变换后的点。矩阵的具体计算方法见MDN文档:
var scale = ctx.scale; ctx.scale = function(sx,sy){ xform = xform.scaleNonUniform(sx,sy); return scale.call(ctx,sx,sy); }; var rotate = ctx.rotate; ctx.rotate = function(radians){ xform = xform.rotate(radians*180/Math.PI); return rotate.call(ctx,radians); }; var translate = ctx.translate; ctx.translate = function(dx,dy){ xform = xform.translate(dx,dy); return translate.call(ctx,dx,dy); }; var transform = ctx.transform; ctx.transform = function(a,b,c,d,e,f){ var m2 = svg.createSVGMatrix(); m2.a=a; m2.b=b; m2.c=c; m2.d=d; m2.e=e; m2.f=f; xform = xform.multiply(m2); return transform.call(ctx,a,b,c,d,e,f); }; var setTransform = ctx.setTransform; ctx.setTransform = function(a,b,c,d,e,f){ xform.a = a; xform.b = b; xform.c = c; xform.d = d; xform.e = e; xform.f = f; return setTransform.call(ctx,a,b,c,d,e,f); };
var pt = svg.createSVGPoint(); ctx.transformedPoint = function(x,y){ pt.x=x; pt.y=y; return pt.matrixTransform(xform.inverse()); }
比如作用在 canvas 上的点击事件的位置,可以通过矩阵变换对应到变换后的绘图上的位置。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
需求
通过鼠标滚轮来缩放 canvas ,通过鼠标拖拽 canvas 。
这个需求的讨论来源于 Stack Overflow 上的问题 Zoom Canvas to Mouse Cursor ,作者使用了 SVG 的 createSVGMatrix 来记录 canvas 变换的矩阵,从而完善了缩放和拖拽的效果,这个思路引起了我的兴趣,这里对源码进行些分析。
在线例子
源码
源码分析
整体思路
canvas 的 translate、 scale 方法可以自由移动缩放画布,但是无法记录当前的变换状态,导致不能在绘制 canvas 时再使用 translate、 scale 方法等;并且不能获取 canvas 点击事件在矩阵变换后的位置。所以作者对每次变换进行记录,解决了变换状态丢失的问题。
实现 trackTransforms
trackTransforms 在源码中的位置:
创建矩阵保存变换状态
trackTransforms 先利用 SVG 对象的 createSVGMatrix 创建了矩阵,这个矩阵保存着所有 canvas 的缩放、倾斜和移动:
修改变换相关的方法
对 canvas 中变换相关的方法进行修改,使每次造成 canvas 变换的操作也对矩阵造成了相应的变换。这样一来就可以通过矩阵记录当前的变换状态,即:变换前的点 -> 矩阵 -> 变换后的点。矩阵的具体计算方法见MDN文档:
通过矩阵获取变换后的点的坐标
比如作用在 canvas 上的点击事件的位置,可以通过矩阵变换对应到变换后的绘图上的位置。
其他实现此需求的JS库
The text was updated successfully, but these errors were encountered: