Snap.svg 缩放时拖动
Snap.svg Drag while Zoomed
当我在缩放(缩放)的对象上使用 drag() 时,对象会根据比例移动,例如,如果将比例设置为 3 -- 那么鼠标每移动 1px 就会成倍增加3.
鼠标移动 20 个左右像素后,这种行为是完全不能接受的。
这是错误还是我做错了什么?
var g = s.g();
g.transform("scale(3)");
var rect = g.rect(20,20,40,40);
var circle = g.circle(60,150,50);
var move = function(dx,dy) {
this.attr({
transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy]
});
}
var start = function() {
this.data('origTransform', this.transform().local );
}
var stop = function() {
console.log('finished dragging');
}
rect.drag(move, start, stop );
circle.drag(move, start, stop );
参见 http://jsfiddle.net/mje8knLf/1/ 处的 fiddle(只需拖动其中一个形状)
TIA!
尝试:transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx/3, dy/3]
.
基本实现:-
Scale
是全局变量(也可以是FLOAT)
- 所有
dx
和 dy
运动除以 Scale
sidenote:所有元素都可以拖出盒子。您可能想在边缘周围实施一些移动限制。
为此,我们需要考虑出现在所有外部元素上的现有转换。
这是我不久前做的一个插件来帮助解决这个问题。
主要是dragMove函数。我们找到应用的现有其他变换(Snap 中有 3 种类型的元素变换矩阵,localMatrix、diffMatrix、globalMatix),并将其反转以获得我们想要应用的矩阵以允许现有效果。 (如果有些情况diffMatrix不行,看看globalMatrix)。
然后使用它,我们可以在新的拖动量上使用 y() 和 x(),找到它在新坐标 space.
中的值
Snap.plugin( function( Snap, Element, Paper, global ) {
Element.prototype.altDrag = function() {
this.drag( dragMove, dragStart, dragEnd );
return this;
}
var dragStart = function ( x,y,ev ) {
this.data('ot', this.transform().local );
}
var dragMove = function(dx, dy, ev, x, y) {
var tdx, tdy;
var snapInvMatrix = this.transform().diffMatrix.invert();
snapInvMatrix.e = snapInvMatrix.f = 0;
tdx = snapInvMatrix.x( dx,dy ); tdy = snapInvMatrix.y( dx,dy );
this.transform( "t" + [ tdx, tdy ] + this.data('ot') );
}
var dragEnd = function() {
}
});
这里我使用的是svg-pan-zoom.js来实现SVG的平移和缩放,非常好用。
我正在使用 snap.svg
var svgElement;
var panZoomPlan;
function setPanZoom(){
svgElement = document.querySelector('svg');
panZoomPlan = svgPanZoom(svgElement);
panZoomPlan.setMinZoom(0.1);
panZoomPlan.setMaxZoom(50);
panZoomPlan.setZoomScaleSensitivity(0.2);
panZoomPlan.disableDblClickZoom();
}
function set_draggable(svg_element) {
var shape = plan.select("#" + svg_element);
shape.drag(dragNode, dragStart, dragStop);
}
var dragStart = function() {
panZoomPlan.disablePan();
panZoomPlan.disableZoom();
this.isDragged = false;
var node_id = this.node.id;
this.data('origTransform', this.transform().local );
}
var dragNode = function(dx,dy) {
this.isDragged = true;
realZoom = panZoomPlan.getSizes().realZoom;
var rdx = dx/realZoom;
var rdy = dy/realZoom;
this.attr({
transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [rdx, rdy]
});
event.preventDefault();
}
var dragStop = function() {
panZoomPlan.enablePan();
panZoomPlan.enableZoom();
if (!this.isDragged) {
return;
}
//update scene elements data
var node_id = this.node.id;
Nodes_dict[node_id].x += Nodes_dict[node_id].rdx;
Nodes_dict[node_id].y += Nodes_dict[node_id].rdy;
}
希望对以后看到这个问题的用户有所帮助。
当我在缩放(缩放)的对象上使用 drag() 时,对象会根据比例移动,例如,如果将比例设置为 3 -- 那么鼠标每移动 1px 就会成倍增加3.
鼠标移动 20 个左右像素后,这种行为是完全不能接受的。
这是错误还是我做错了什么?
var g = s.g();
g.transform("scale(3)");
var rect = g.rect(20,20,40,40);
var circle = g.circle(60,150,50);
var move = function(dx,dy) {
this.attr({
transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy]
});
}
var start = function() {
this.data('origTransform', this.transform().local );
}
var stop = function() {
console.log('finished dragging');
}
rect.drag(move, start, stop );
circle.drag(move, start, stop );
参见 http://jsfiddle.net/mje8knLf/1/ 处的 fiddle(只需拖动其中一个形状)
TIA!
尝试:transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx/3, dy/3]
.
基本实现:-
Scale
是全局变量(也可以是FLOAT)- 所有
dx
和dy
运动除以Scale
sidenote:所有元素都可以拖出盒子。您可能想在边缘周围实施一些移动限制。
为此,我们需要考虑出现在所有外部元素上的现有转换。
这是我不久前做的一个插件来帮助解决这个问题。
主要是dragMove函数。我们找到应用的现有其他变换(Snap 中有 3 种类型的元素变换矩阵,localMatrix、diffMatrix、globalMatix),并将其反转以获得我们想要应用的矩阵以允许现有效果。 (如果有些情况diffMatrix不行,看看globalMatrix)。
然后使用它,我们可以在新的拖动量上使用 y() 和 x(),找到它在新坐标 space.
中的值Snap.plugin( function( Snap, Element, Paper, global ) {
Element.prototype.altDrag = function() {
this.drag( dragMove, dragStart, dragEnd );
return this;
}
var dragStart = function ( x,y,ev ) {
this.data('ot', this.transform().local );
}
var dragMove = function(dx, dy, ev, x, y) {
var tdx, tdy;
var snapInvMatrix = this.transform().diffMatrix.invert();
snapInvMatrix.e = snapInvMatrix.f = 0;
tdx = snapInvMatrix.x( dx,dy ); tdy = snapInvMatrix.y( dx,dy );
this.transform( "t" + [ tdx, tdy ] + this.data('ot') );
}
var dragEnd = function() {
}
});
这里我使用的是svg-pan-zoom.js来实现SVG的平移和缩放,非常好用。 我正在使用 snap.svg
var svgElement;
var panZoomPlan;
function setPanZoom(){
svgElement = document.querySelector('svg');
panZoomPlan = svgPanZoom(svgElement);
panZoomPlan.setMinZoom(0.1);
panZoomPlan.setMaxZoom(50);
panZoomPlan.setZoomScaleSensitivity(0.2);
panZoomPlan.disableDblClickZoom();
}
function set_draggable(svg_element) {
var shape = plan.select("#" + svg_element);
shape.drag(dragNode, dragStart, dragStop);
}
var dragStart = function() {
panZoomPlan.disablePan();
panZoomPlan.disableZoom();
this.isDragged = false;
var node_id = this.node.id;
this.data('origTransform', this.transform().local );
}
var dragNode = function(dx,dy) {
this.isDragged = true;
realZoom = panZoomPlan.getSizes().realZoom;
var rdx = dx/realZoom;
var rdy = dy/realZoom;
this.attr({
transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [rdx, rdy]
});
event.preventDefault();
}
var dragStop = function() {
panZoomPlan.enablePan();
panZoomPlan.enableZoom();
if (!this.isDragged) {
return;
}
//update scene elements data
var node_id = this.node.id;
Nodes_dict[node_id].x += Nodes_dict[node_id].rdx;
Nodes_dict[node_id].y += Nodes_dict[node_id].rdy;
}
希望对以后看到这个问题的用户有所帮助。