【发布时间】:2017-12-28 08:27:10
【问题描述】:
tl;博士 我将如何使用返回的 CTM:
var ctm = canvas.rawNode.getScreenCTM();
修改屏幕坐标中的dx, dy 向量,使其位于世界坐标中?即{ dx: 1, dy: 0} 应该变成{ dx: 3.6, dy: 0} 给定上面的 SVG 示例,其中 viewBox 0 0 1800 1800 在一个 500 像素宽的窗口中。
我认为以下方法会起作用:
var ctm = canvas.rawNode.getScreenCTM();
// Turn this into a dojox/gfx/matrix Matrix2D
var ctmm = new matrix.Matrix2D({xx: ctm.a, xy: ctm.b, dx: ctm.c,
yx: ctm.d, yy: ctm.e, dy: ctm.f});
// Invert this
var itm = matrix.invert(ctmm);
// Multiply screen coords by transform matrix
var worldshift = matrix.multiplyPoint(itm, shift.dx, shift.dy);
console.log('ctm ', ctm, ', shift ', shift, ' became worldshift ', worldshift);
shift.dx = worldshift.x;
shift.dy = worldshift.y;
但是itm 充满了 NaN 和 Infinity。
CodePen 示例的长版本问题
我知道这背后的基本数学原理,但发现自己在尝试使用矩阵变换时遇到了困难。文档似乎避免了这个主题。情况是:
- SVG 节点具有定义世界坐标的 viewBox,例如 0,0 到 1800,1800
- SVG 节点位于将其缩放到窗口的文档中 大小,大约 500px 宽所以 SVG 中的世界坐标(1800 x 1800 单位) 不要将 1:1 映射到屏幕坐标。每个像素跨度为 1800/500 = 3.6 世界单位
-
dojox/gfx/Moveable 使用 dojox/gfx/Mover
onMouseMove函数传递它在屏幕中移动的数量 坐标:this.host.onMove(this, {dx: x - this.lastX, dy: y - this.lastY});
最后一个参数作为shift 参数传递给dojox/gfx/Moveable.onMoving,可能是例如{ dx: 1, dy: 0 } 如果鼠标向右移动了一个像素。
如果我们愚蠢地允许框架将其应用于被拖动形状的平移变换,则其位置与鼠标坐标不完全匹配:https://codepen.io/neekfenwick/pen/RxpoMq(这在 dojox 演示中工作正常,因为它们的 SVG 坐标系与屏幕坐标系 1:1)。
我在http://grokbase.com/t/dojo/dojo-interest/08anymq4t9/gfx-constrainedmoveable 找到了一些灵感,其中 Eugene 说“在你的对象上覆盖 onMoving 并修改“shift”对象,使其永远不会将形状移动到指定边界之外。”,这似乎是修改 @ 的好点987654335@ 对象,所以我接下来的尝试声明了一种新类型的dojox/gfx/Moveable 并覆盖onMoving。
我尝试使用矩阵转换来获取 SVG 的 Screen CTM(它位于 { a, b, c, d, e, f } 的对象中),并使用直接矩阵运算将其用作 dojox/gfx Matrix2D ({ xx, xy, dx, yx, yy, dy })。目的是修改shift 对象以在将其用于形状的变换矩阵之前将屏幕单位转换为世界单位,但发现自己很困惑。一开始,CTM 似乎有一个大约 50 的大 dy,这立即使形状从屏幕底部射出。这是我最近一次非常混乱和失败的尝试:https://codepen.io/neekfenwick/pen/EoWNOb
我可以手动获取 CTM 的 x 和 y 比例值并将它们应用于 shift 对象:https://codepen.io/neekfenwick/pen/KZWapa
如何使用Matrix2D.invert() 和Matrix2D.multiplyPoint() 等矩阵运算来获取 SVG 的坐标系,生成一个转换矩阵以将屏幕坐标转换为世界坐标,并将其应用于 dx,dy鼠标移动过?
【问题讨论】:
标签: svg matrix draggable coordinate-transformation dojox.gfx