javascript - 交互 JS,在 viewboxed svg 中拖动 svg 元素?

标签 javascript svg interact.js

我的问题是,当我拖动元素时,元素在光标后面很远,所以看起来可能是比例问题?

screen grab of the weird movement

代码:

    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);
            });
        });

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

我的 svg 初始化 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 摘要是在重新查询以获取新的 xy 属性之后发生的吗?

最佳答案

这个问题的发生是因为 SVG 的内部设置在宽度和高度上设置为 1024 像素,但以不同的尺寸显示,在这种情况下较小,因此从拖动应用的平移按比例缩小并且元素似乎比光标慢。

为了解决这个问题,您需要相应地缩放平移向量。获得比例因子的一种方法 sxsy可能是:

  1. 查询结果边界框bb svg 的 getClientBoudingRect
  2. sx = bb.width / 1024 // (original size), same for sy

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

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

a应该代表sxd sy .

编辑

我已经设置了一个 fiddle here这显示了基本方法。总而言之,解决方案是向量的矩阵变换,而要解决的难题是找到正确的矩阵。由于任何 svg 元素都可能有自己的变换,或者作为组的子元素,可能会从其父元素获得变换,因此使用根 <svg> 是不够的的C当前T转换M矩阵。这就是为什么每个 SVGElement实现 SVGLocatable接口(interface),什么使您能够从根获得转换 <svg>SVGElement (getCTM),或者,文档到 SVGElement (getScreenCTM())。相反的方向由那些矩阵的逆来描述。 ( 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 变换等。您越具体,意味着您越了解要转换的元素,精度就越高。

关于javascript - 交互 JS,在 viewboxed svg 中拖动 svg 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38420786/

相关文章:

javascript - 调用 onClick 函数并将元素的 data-* 属性中的值传递给它

javascript - 如何使用 JavaScript 访问字典中的本地对象?

html - 是否可以使用 CSS 代码为 SVG 过滤器的不透明度设置动画?

javascript - 如何在 pdfmake 和 html2pdfmake 中处理 SVG 和 canvas

javascript - 使用 svg.js 将元素添加到现有组

javascript - Interact.js - 使用句柄移动 iframe

aurelia - 使用 aurealia-interactjs 进行拖动克隆

javascript - 如何从 sqlalchemy jsonify 对象?

javascript - 仅加载一次interact.js

JavaScript - 如何从另一个函数停止一个函数的工作