Snap.svg - обработчик события перетаскивания
Вопрос о обработчике событий onstart для Element.drag в недавно объявленном Snap.svg.
Целью приведенного ниже кода является регистрация обработчиков событий для начала и остановки перетаскивания (onstart/onstop) на объекте svg.
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");
}
);
Сообщения консоли работают нормально при перетаскивании и остановке перетаскивания, но нуль переопределяет функцию onmove по умолчанию - в результате фактическое перетаскивание не происходит. Как передать что-то, что говорит: "Я не хочу возиться со стандартным 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);
Ответы
Ответ 1
Я не уверен, что я не понимаю, что вы точно хотите... разве вы не хотите реализовать перетаскивание?
Итак, например...
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");
}
);
JSBin здесь http://jsbin.com/akoCAkA/1/edit?html,js,output
Ответ 2
Ниже приведен пример перетаскивания с помощью 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 );
Ответ 3
После нескольких часов работы с 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...
Ответ 4
Метод 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 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), после их дублирования.
Кроме того, формат строки 'transform', который я передал (tx, y), пришел из того, что я нашел после выполнения console.log(this.attr('transform')). Я еще не знаком с матрицей(), поэтому этот способ казался проще.
Надеюсь, это поможет!
Ответ 5
Я не могу перетаскивать элементы группы с помощью пользовательских обработчиков, s.drag() делает это возможным. Таким образом, я искал, что нашел его возможным.
Документация:
Вызывается дополнительное событие после событий перетаскивания: drag.start. на старте, drag.end. on > end и drag.move. на каждом шагу. Когда элемент перетаскивается над другим элементом > 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');
});
Ева не зарегистрирована на snapsvg, она доступна на raphael. я не знаю, что это правильный способ или взломать.