Interact JS,在viewboxed svg中拖动svg元素? [英] Interact JS, Drag svg elements inside viewboxed svg?

查看:85
本文介绍了Interact JS,在viewboxed svg中拖动svg元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是,当我拖动元素时,元素远远落后于光标,所以看起来它可能是比率问题?

My problem, when I drag elements, the element is far behind the cursor, so it looks like it's a ratio issue potentially?

代码:

    interact('.element', {
        context: '.lipstick__plane'
    })
        .draggable({
            snap: {
                targets: [
                    interact.createSnapGrid({x: 10, y: 10})
                ],
                range: Infinity
            },
            inertia: true,
            restrict: {
                restriction: '#lipstick__plane__main',
                elementRect: {top: 0, left: 0, bottom: 1, right: 1},
                endOnly: true
            }
        })
        .on('dragmove', function (event) {
            $scope.$apply(function () {
                var target = event.target,
                    x = (parseFloat(target.getAttribute('x')) || 0) + ((1020 / window.outerWidth) * event.dx),
                    y = (parseFloat(target.getAttribute('y')) || 0) + ((1020 / window.outerHeight) * event.dy);

                var indx = event.target.getAttribute('data-index');

                _.set($scope.stage.elements[indx], 'meta.XCord', x);
                _.set($scope.stage.elements[indx], 'meta.YCord', y);
            });
        });

我在那里潜水,这让它更接近光标,但我可能整天都在尝试数字很长...

I am diving there, which got it closer to the cursor, but i could be trying numbers all day long...

我的svg init块:

My svg init block:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024" width="1024px" height="1024px" xml:space="preserve" id="lipstick__plane__main">

我认为有一件事可能是个问题,但我对此表示怀疑,是Angular摘要发生了在重新查询后得到新的 x y 属性?

One thing I do think could be a problem, but i doubt it, is that the Angular digest happens after a requery to get the new x and y attribute?

推荐答案

这个问题发生了,因为SVG的内部设置被设置为1024像素的宽度和高度,但显示的是不同的尺寸,在这种情况下更小,所以应用按比例缩小拖动的平移,元素看起来比光标慢。

This problem comes to happen since the inner setup of the SVG is set to 1024 Pixel in width and Height, but displayed in a different Size, smaller in this case, so the applied translation from the drag is scaled down and the element appears to be slower than the cursor.

要解决此问题,您需要相应地缩放平移向量。获得缩放因子 sx sy 的一种方法可能是:

To address this, you need to scale the translation vector accordingly. One way to gain the scaling factors sx and sy could be:


  1. 查询svg的结果边界框 bb getClientBoudingRect

  2. sx = bb.width / 1024 //(原始大小),同样适用于sy

  1. query the resulting bounding box bb of the svg by getClientBoudingRect
  2. sx = bb.width / 1024 // (original size), same for sy

或者,如果您可以访问 svg 元素,则可以使用 .getScreenCTM()获取转换矩阵。这应该是这样的:

Or, if you can access the svg element you can use .getScreenCTM() to get the transformation matrix. Which should look like this:

| a  c  e |
| b  d  f |
| 0  0  1 |

a 应代表 sx d sy

编辑

我设置了一个小提琴这里显示了基本方法。总而言之,解决方案是向量的矩阵变换,要解决的难题是找到正确的矩阵。由于任何svg元素可能有自己的变换,或者作为组的子节点,可能从其父节点获得变换,因此使用根< svg> '是不够的。 s C urrent T 变形 M atrix。这就是为什么每个 SVGElement 实现 SVGLocatable 接口,使您能够从根< svg> 转换为 SVGElement (getCTM),或者,文档到 SVGElement (getScreenCTM())。通过这些矩阵的逆来描述相反的方向。 (对SO的解释

I have setup a little fiddle here which shows the basic approach. All in all, the solution is a matrix transformation of a vector and the puzzle to solve is to find the right matrix. Since any svg element may have its own transform, or as child of a group, may gain transform from its parents, it is not sufficient to use the root <svg>'s Current Transformation Matrix. That is why each SVGElement implements the the SVGLocatable Interface, what enables you to gain the transform from the root <svg> to the SVGElement (getCTM), or, the document to the SVGElement (getScreenCTM()). The opposite direction is described by the inverse of those matrices. (explanation on SO)

let svg   = document.querySelector('svg'),
    e     = svg.querySelector('.myelement'),
    ctm   = e.getScreenCTM(),
    point = svg.createSVGPoint(),
    point2;

point.x = …;
point.y = …;

point2 = point.matrixTransform(ctm);

总结:使用转换矩阵应该是首选方式,因为它(至少应该)考虑所有变换,可以通过css应用于svg,如旋转,3d变换等。你越具体,意味着你想要变换的元素越多,精度就越高。

To conclude: Using the transformation matrix should be the preferred way, since it will (at least should) take all transformations into account, which could be applied to the svg by css, like rotations, 3d transforms and so on. The more specific you are, meaning the more you know the element you would like to transform, the higher the precision will be.

这篇关于Interact JS,在viewboxed svg中拖动svg元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆