Javascript 交互JS,拖动viewboxed svg中的svg元素?
我的问题是,当我拖动元素时,元素远远落后于光标,所以它看起来可能是一个比率问题 守则:Javascript 交互JS,拖动viewboxed svg中的svg元素?,javascript,svg,interact.js,Javascript,Svg,Interact.js,我的问题是,当我拖动元素时,元素远远落后于光标,所以它看起来可能是一个比率问题 守则: interact('.element', { context: '.lipstick__plane' }) .draggable({ snap: { targets: [ interact.createSnapGrid({x: 10, y: 10})
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初始化块:
<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">
有一件事我确实认为可能是个问题,但我对此表示怀疑,那就是角度摘要是在重新查询以获得新的
x
和y
属性之后发生的。这个问题是因为SVG的内部设置在宽度和高度上设置为1024像素,但显示的大小不同,在这种情况下更小,因此,从拖动中应用的平移将按比例缩小,并且元素似乎比光标慢
要解决这个问题,需要相应地缩放平移向量。获得缩放因子sx
和sy
的一种方法可以是:
getClientBoudingRect
sx=bb.width/1024/(原始尺寸),与sy相同
svg
元素,则可以使用.getScreenCTM()
获取转换矩阵。应该是这样的:
| a c e |
| b d f |
| 0 0 1 |
a
应表示sx
和d
sy
编辑
我已经设置了一个小小提琴,它显示了基本的方法。总之,解是向量的矩阵变换,而要解决的难题是找到正确的矩阵。由于任何svg元素都可能有自己的变换,或者作为一个组的子元素,可能从其父元素获得变换,因此使用根
的CT变换M矩阵是不够的。这就是为什么每个SVGElement
都实现了接口,使您能够获得从根
到SVGElement
(getCTM),或者从文档到SVGElement
(getScreenCTM())的转换。相反的方向由这些矩阵的逆矩阵来描述。()
总结:使用转换矩阵应该是首选方法,因为它将(至少应该)考虑所有转换,这些转换可以通过css应用于svg,如旋转、3d转换等。您越具体,意味着您越了解要转换的元素,精度就越高。因为您的SVG是缩放的,所以您的鼠标坐标与SVG坐标不是1:1。因此,您需要将鼠标/屏幕坐标转换为SVG坐标,以获得拖动对象的正确位置 有关如何进行转换,请参见此问题
您是否检查了svg中是否应用了任何转换?看起来翻译是按比例缩放的,有转换的包装组可能会导致什么…嗯,包装div应用了
width:calc(100vw-200px)
,还有display:block;宽度:100%;高度:自动代码>到svg元素本身。然后这是一个缩放问题。尝试一下svg,它的大小为1024像素,应该可以工作。如果是这种情况,您应该使用屏幕转换矩阵来缩放翻译向量这里是屏幕上的svgcopy+paste,outerHTML
@philipp这很有意义,但是我需要svg缩放到正确的宽度,有没有办法运行dx
,dy
通过一个算法可能??一旦我有了这个缩放向量,我是否将它用作鼠标移动时的x+=sx
和y+=sy
坐标?
let svg = document.querySelector('svg'),
e = svg.querySelector('.myelement'),
ctm = e.getScreenCTM(),
point = svg.createSVGPoint(),
point2;
point.x = …;
point.y = …;
point2 = point.matrixTransform(ctm);