Подтвердить что ты не робот

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);
4b9b3361

Ответ 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. я не знаю, что это правильный способ или взломать.