Перетаскивание в Raphael.jsВ этом пример, мы создадим реализацию простых методов перетаскивания для набора элементов Raphael.js. Рафаель содержит метод для перетаскивания одного элемента, но в нем нет методов для набора элементов.

Нам нужно добавить функцию, которая будет добавлена всем созданным set'ам и будет вызвана при перетаскивании элементов из них. Чтобы функция была доступна у всех созданных наборов, нормальным путем бы было добавление ее в прототипы объекта set Raphael.set.prototype, но если вы попробуете так сделать, то увидите, что это не работает. Raphael скрывает прототипы внутри себя, и чтобы добавить прототип к набору нужно просто объявить метод у объекта Raphael.st:

Raphael.st.draggable = function() {

};

Внутри этого метода мы напишем логику перемещения элементов набора по холсту. Для начала создадим несколько переменных обработчики основных событий перетаскивания (захват, перемещение, отпускание):

Raphael.st.draggable = function() {
    var me = this,
        lx = 0,
        ly = 0,
        ox = 0,
        oy = 0,
        moveFnc = function(dx, dy) {},
        startFnc = function() {},
        endFnc = function() {};

    this.drag(moveFnc, startFnc, endFnc);
};

Мы установили переменную me, содержащую ссылку на набор. Это нужно потому, что Raphael, будет вызывать метод drag для каждого конкретного элемента, а нам нужно перемещать элементы вместе. Координаты (lx, ly) - это изменение положения мыши в данный момент времени, а (ox, oy) - это положение мыши в момент захвата объектов. И наконец мы добавили методом drag обработчики для всех элементов набора. set сам пробежит по всем своим элементам и вызовет эти обработчики у них.

Raphael создаст обработчики на события mousedown (захват), mouseup (отпускание) и mousemove (перемещение). Они передаются в метод drag. Когда событие срабатывает для единичного элемента набора, наша draggable используя me, позволит произвести перетаскивание всего набора скопом. Напишем функцию, которая будет началом перетаскивания startFnc. Ее функционал невелик, она не делает ничего:

startFnc = function() {},

Так как на старте трансформация всегда будет равна 0, то и делать на старте ничего не нужно.

Функция перемещения, другое дело. Она очень важна. Она получает разницу в координатах в (dx, dy). Эти два значения нужны для текущей трансформации.

moveFnc = function(dx, dy) {
    lx = dx + ox;  // изменяем значение трансформации по x
    ly = dy + oy;  // делаем тоже самое для y
    me.transform('t' + lx + ',' + ly);
}

Запомните, мы получили изменение x и y с момента начала перетаскивания. В начале они были равны 0. Трансформация представляется в виде строки tx,y, t. Она подается в метод transform. Значения lx и ly до момента отпускания содержат координаты изменения всех элементов набора. После окончания перетаскивания (отпускания), нужно сохранить это значение в ox,oy:

endFnc = function() {
    ox = lx;
    oy = ly;
}

Это гарантирует, что при следующем перемещении, предыдущие изменения будут учтены. Если этого не сделать, то все элементы набора переместятся в начальную позицию.

Что получилось в результате

Raphael.st.draggable = function() {
  var me = this,
      lx = 0,
      ly = 0,
      ox = 0,
      oy = 0,
      moveFnc = function(dx, dy) {
          lx = dx + ox;
          ly = dy + oy;
          me.transform('t' + lx + ',' + ly);
      },
      startFnc = function() {},
      endFnc = function() {
          ox = lx;
          oy = ly;
      };

  this.drag(moveFnc, startFnc, endFnc);
};

Сейчас, все что нам нужно сделать - это создание холста, создание набора и добавление нескольких элементов в него.

var paper = Raphael(document.getElementById('canvas'));
var mySet = paper.set();

mySet.push(paper.circle(550, 150, 50).attr('fill', 'red'));
mySet.push(paper.circle(550, 150, 40).attr('fill', 'white'));
mySet.push(paper.circle(550, 150, 30).attr('fill', 'red'));
mySet.push(paper.circle(550, 150, 20).attr('fill', 'white'));
mySet.push(paper.circle(550, 150, 10).attr('fill', 'red'));

mySet.draggable()

В результате, вы увидите, как все круги будут перемещаться вместе с любым, который вы захватите мышкой.

Удивительно и удобно, не правда ли?!)

 

Цель на экране - очень простой пример. Вы моежет двигать более сложные элементы svg. Как полигоны так и линии. raphael очень прост и удобен в работе с svg графикой. Работать с ним также просто, как firewall купить и защитить свой компьютер от всякого вредоносного хлама, коим полон интернет

Рассказать друзьям

Добавить комментарий


Защитный код
Обновить