问题是关于新发布的Element.drag中Snap.svg的onstart事件处理程序。
下面代码的目的是为svg对象上的拖动(onstart / onstop)的开始和停止注册事件处理程序。
var s = Snap(800,600);
var bigCircle = s.circle(300,150,100);
bigCircle.drag(null,
function(){
console.log("Move started");
},
function(){
console.log("Move stopped");
}
);
控制台消息在拖动开始和停止时工作正常,但是null会覆盖默认的onmove函数 - 导致不会发生实际的拖动。如何传递“我不想弄乱默认情况”的内容?
(注意:我更喜欢通过赋值来注册事件处理程序,比如熟悉的onClick,但这是另一回事。)
注意几小时后添加: Raphael.js文档和示例提供了一些线索。至少现在我知道如何为onmove传递一个适当的函数来提供默认的移动行为:
var s = Snap(800,600);
var bigCircle = s.circle(300,150,100);
start = function() {
this.ox = parseInt(this.attr("cx"));
this.oy = parseInt(this.attr("cy"));
console.log("Start move, ox=" + this.ox + ", oy=" + this.oy);
}
move = function(dx, dy) {
this.attr({"cx": this.ox + dx, "cy": this.oy + dy});
}
stop = function() {
this.ox = parseInt(this.attr("cx"));
this.oy = parseInt(this.attr("cy"));
console.log("Stop move, ox=" + this.ox + ", oy=" + this.oy);
}
bigCircle.drag(move, start, stop);
答案 0 :(得分:8)
我不确定我是否误解了你究竟想要的东西......难道你不想实施阻力吗?
所以例如......
var s = Snap(400,400);
var bigCircle = s.circle(150, 150, 100);
var moveFunc = function (dx, dy, posx, posy) {
this.attr( { cx: posx , cy: posy } ); // basic drag, you would want to adjust to take care of where you grab etc.
};
bigCircle.drag( moveFunc,
function(){
console.log("Move started");
},
function(){
console.log("Move stopped");
}
);
答案 1 :(得分:7)
这里有一个如何使用SnapSVG进行拖动的示例:http://svg.dabbles.info/snaptut-drag.html
var s = Snap("#svgout");
var rect = s.rect(20,20,40,40);
var circle = s.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 );
答案 2 :(得分:2)
在使用snap.js挣扎了几个小时后,我终于发现了svg.js及其可拖动的插件,它更容易使用它:
var draw = SVG('svg');
var circle = draw.circle(10).attr({cx:30,cy:30,fill:'#f06'});
circle.dragend = function(delta, event) {
alert(this.attr('cx'))
}
circle.draggable();
所以,我切换到svg.js ......
答案 3 :(得分:1)
eve.on方法对我来说不起作用,所以我做了一些探索并设法重新创建了onmove函数。另外两个(onstart和onend)显然不需要特定的代码:
var S = Snap(300,300);
var bigCircle = S.circle(150, 150, 100);
bigCircle.drag(onDragMove, onDragStart, onDragEnd);
var ddx = 0;
var ddy = 0;
var dxDone = 0;
var dyDone = 0;
function onDragMove (dx, dy, posx, posy) {
dx = dx + dxDone; // dx and dy reset to 0 for some reason when this function begins
dy = dy + dyDone; // retain the last move's position as the starting point
this.attr( { transform: 't'+dx+','+dy } );
ddx = dx;
ddy = dy;
console.log('moving...');
};
function onDragStart(x,y,e) {
console.log('start!');
};
function onDragEnd(e) {
dxDone = ddx;
dyDone = ddy;
console.log('end!');
};
但请注意,这只应用于一次拖动一个对象。如果您需要为另一个对象进行自定义拖动,则必须在复制之后重命名函数(即onDragStart2)和在它们之外声明的四个变量(即ddx2)。
此外,'转换'我传递的字符串格式(tx,y)来自我在执行console.log之后发现的内容(this.attr(' transform'))。我还不熟悉matrix(),所以这种方式似乎更容易。
希望这有帮助!
答案 4 :(得分:0)
我无法使用自定义处理程序拖动组元素,s.drag()使其成为可能。所以我进一步搜索发现它可能。
文档:
附加拖动事件后触发:drag.start。在开始时,拖动。在>结束并拖动。移动。一举一动。当元素被拖过另一个元素时> drag.over。火也是。
解决方案:
s.drag();
eve.on("snap.drag.start." + s.id, function () {
console.log('cool');
});
eve.on("snap.drag.move." + s.id, function () {
console.log('cooler');
});
eve.on("snap.drag.end." + s.id, function () {
console.log('way cool');
});
eve未记录在snapsvg上,它可用于raphael。我不知道这是正确的方法还是黑客攻击。
答案 5 :(得分:0)
尝试一下
var paper = Snap("#main");
var object = paper.circle(300,150,100)
object .attr({
stroke: "#000",
strokeWidth: 10,
strokeLinecap:"round"
});
var move1 = function(dx,dy, posx, posy) {
this.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('dragging done');
}
object.drag(move1, start, stop );