dojox.gfx.Moveable将屏幕坐标转换为世界坐标以进行拖动

问题描述 投票:0回答:1

TL; dr我如何使用返回的CTM:

var ctm = canvas.rawNode.getScreenCTM();

修改屏幕坐标中的dx, dy矢量,使其处于世界坐标中?在qzxswpoi应该成为{ dx: 1, dy: 0},给出上面的SVG示例,其中viewBox { dx: 3.6, dy: 0}在500px宽的窗口中。

我认为以下内容可行:

0 0 1800 1800

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; 充满了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,其itm函数在屏幕坐标中传递它移动的量: this.host.onMove(this,{dx:x - this.lastX,dy:y - this.lastY});

最后一个论点作为onMouseMove论证传递给dojox/gfx/Moveable.onMoving,可能是例如{dx:1,dy:0}如果鼠标向右移动一个像素。

如果我们愚蠢地允许框架将其应用于被拖动的形状的平移变换,则其位置与鼠标坐标不完全匹配:shift(这在dojox演示中工作正常,因为它们的SVG坐标系与屏幕坐标系1匹配: 1)。

我在https://codepen.io/neekfenwick/pen/RxpoMq找到了一些灵​​感,其中Eugene说“覆盖onMoving你的对象并修改”shift“对象,所以它永远不会移动到指定边界之外的形状。”,这似乎是修改http://grokbase.com/t/dojo/dojo-interest/08anymq4t9/gfx-constrainedmoveable对象的好点,所以我的下一个尝试声明一种新类型的shift并覆盖dojox/gfx/Moveable

我已经尝试使用矩阵变换来获得SVG的屏幕CTM(它出现在onMoving的一个对象中)并使用直接矩阵运算将其用作{ a, b, c, d, e, f } dojox/gfxMatrix2D)。目的是修改{ xx, xy, dx, yx, yy, dy }对象,在将屏幕单位用于形状的变换矩阵之前将其转换为世界单位,但发现自己非常困惑。首先,CTM似乎有一个大约50的大dy,它立即使形状从屏幕底部射出。这是我最近非常混乱和破碎的尝试:shift

我可以手动获取CTM的x和y比例值并将它们应用到shift对象:https://codepen.io/neekfenwick/pen/EoWNOb

如何使用https://codepen.io/neekfenwick/pen/KZWapaMatrix2D.invert()等矩阵运算来获取SVG的坐标系,产生一个转换矩阵,从屏幕坐标转换为世界坐标,并将其应用于鼠标移动的dx,dy?

svg matrix draggable coordinate-transformation dojox.gfx
1个回答
0
投票

我得到了一个工作的例子,只从Matrix2D.multiplyPoint()中获取ad,只填充DOMMatrixxxyy元素:Matrix2D

https://codepen.io/neekfenwick/pen/mpWgrO

这样,红色圆圈与鼠标光标同步移动。

看起来我在使用 var MyMoveable = declare(Moveable, { onMoving: function(/* dojox/gfx/Mover */ mover, /* Object */ shift){ // console.log('mover ', mover, ' shift ', shift); // shift comes in screen coordinates // Get the Screen Coordinate Transform Matrix var ctm = canvas.rawNode.getScreenCTM(); // Turn this into a dojox/gfx/matrix Matrix2D var ctmm = new matrix.Matrix2D({xx: ctm.a, yy: ctm.d}); // 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); // Replace the shift dx,dy vector with the transformed coordinates shift.dx = worldshift.x; shift.dy = worldshift.y; } }); 属性时过于热心,试图使用所有元素来填充我的DOMMatrixxyyx等元素,以用作在鼠标移动向量上使用的变换矩阵的基础。我发现文档Matrix2D相当难以遵循,因为它没有在网格中布置矩阵元素所以我认为a,b,c,d,e,f只是简单地布置在3x3网格中:

https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix

然而,文档的“3D Equivalent”部分表明它实际上是某种4x4矩阵(这里我使用?对于未指定的元素,我不确定默认值是什么):

{ a, b, c,
  d, e, f,
  0, 0, 1 }

所以我仍然很困惑,但至少有一个使用{ a, b, ?, ?, c, d, ?, ?, ?, ?, ?, ?, e, f, ?, ? } 操作的解决方案。

我还尝试过使用纯SVG操作来创建SVGPoint并使用DOMMatrix操作对其进行转换,但转换矩阵的偏移量为100或200,我放弃了它:Matrix2D

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.