2010-11-19 2 views
17

Возможно ли иметь возможность перетаскивать объекты, отличные от кругов и прямоугольников, вокруг страницы с помощью Raphael js?Создание путей и изображений, перетаскиваемых в Raphael js

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

Вот код

<script> 
    window.onload = function() { 
     var R = Raphael(0, 0, "100%", "100%"), 
      r = R.circle(100, 100, 50).attr({fill: "hsb(0, 1, 1)", stroke: "none", opacity: .5}), 
      g = R.circle(210, 100, 50).attr({fill: "hsb(.3, 1, 1)", stroke: "none", opacity: .5}), 
      b = R.circle(320, 100, 50).attr({fill: "hsb(.6, 1, 1)", stroke: "#fff", "fill-opacity": 0, "stroke-width": 0.8, opacity: .5}), 
      p = R.path("M 250 250 l 0 -50 l -50 0 l 0 -50 l -50 0 l 0 50 l -50 0 l 0 50 z") .attr({fill: "hsb(.8, 1, 1)", stroke: "none", opacity: .5}); 
     var start = function() { 
      this.ox = this.attr("cx"); 
      this.oy = this.attr("cy"); 
      this.animate({r: 70, opacity: .25}, 500, ">"); 
     }, 
     move = function (dx, dy) { 
      this.attr({cx: this.ox + dx, cy: this.oy + dy}); 
     }, 
     up = function() { 
      this.animate({r: 50, opacity: .5}, 500, ">"); 
     }; 
     R.set(r, g, b, p).drag(move, start, up); 
    }; 
</script> 

ответ

1

Я экспериментировал с этим некоторое время назад, и получил это работает, используя следующий подход:

  • Добавить изначально скрытый, стилизованную, абсолютным позиционированием DIV с прозрачный фон и подходящий стиль оформления на вашей странице, а использование jQuery/UI делает его перетаскиваемым.
  • Добавьте событие click для каждого из элементов Rapahel/SVG, которые вы хотите перетащить, и в этом случае добавьте код, чтобы изменить размер и переместить div над элементом, который только что щелкнул, а затем сделать его видимым.
  • Добавить код в div, который обновляет положение элемента Рафаэля при его перетаскивании.

Я продлил это, чтобы добавить изменение размера возможностей, и это тоже работали хорошо, но идти вперед, было бы здорово, чтобы увидеть перетаскивать и изменять размеры возможностей (в идеале правильно интегрировать в библиотеку, а не с помощью JQuery), встроенный в Рафаэль , поскольку эти функции открывали бы целую кучу возможностей для разработчиков в браузере с использованием чистого Raphael.

1

Попробуйте это для кругов. Я считаю, что атрибуты Circles отличаются от изображений, текста и т. Д.

var start = function() { 
     this.ox = this.attr("x"); 
     this.oy = this.attr("y"); 
     this.animate({r: 70, opacity: .25}, 500, ">"); 
    }, 
    move = function (dx, dy) { 
     this.attr({x: this.ox + dx, y: this.oy + dy}); 
    }, 
    up = function() { 
     this.animate({r: 50, opacity: .5}, 500, ">"); 
    }; 
0

Это не так сложно, если вы понимаете обычные функции перетаскивания, которые дал вам Крис Батлер. Я использую это:

var start = function() { 
    //storing original coordinates 
    this.xSource = this.attrs.path[0][1]; 
    this.ySource = this.attrs.path[0][2]; 
    this.xDest = this.attrs.path[1][1]; 
    this.yDest = this.attrs.path[1][2]; 
    this.attr({opacity: 0.5}); 
    }, 
    move = function (dx, dy) { 
    //move will be called with dx and dy 
    var xS = this.xSource+dx; 
    var xD = this.xDest+dx; 
    var yS = this.ySource+dy; 
    var yD = this.yDest+dy; 
    this.attr({path: "M"+ xS +" "+ yS +"L"+ xD +" "+yD}); 
    }, 
    drag = function(){ 
    this.node.drag(this.move,this.start,this.up); 
    }; 

Вы также можете узнать, какой вид фигуры вы перетаскиваете в функциях с this.type, так что вы можете сделать эти функции работают для всех рода фигур.

13

Ключ здесь (который я нашел) состоит в том, чтобы преобразовать значения дельта х и у в значения пересылки, которые понимает объект пути.

http://www.nathancolgate.com/post/2946823151/drag-and-drop-paths-in-raphael-js

Эффективно тот же подход:

var paper = Raphael(10, 50, 320, 200); 

var tri = paper.path("M0 0L0 20L25 10L0 0Z").attr("fill", "#ff0"); 
var rex = paper.rect(10, 20, 50, 50).attr("fill", "#ff0"); 

var start = function() { 
    this.odx = 0; 
    this.ody = 0; 
    this.animate({"fill-opacity": 0.2}, 500); 
}, 
move = function (dx, dy) { 
    this.translate(dx - this.odx, dy - this.ody); 
    this.odx = dx; 
    this.ody = dy; 
}, 
up = function() { 
    this.animate({"fill-opacity": 1}, 500); 
}; 

tri.drag(move, start, up); 
rex.drag(move, start, up); 
+0

Спасибо. Но есть ли способ узнать окончательное (абсолютное) положение фигур? – Yako

+0

Yako, вы можете использовать getBBox() – Dan

+0

перевод устарел, см. Мой ответ для этого с преобразованием –

1

Я бы порекомендовал вам raphael.draggable библиотека, которая делает трюк для вас. Я использовал его с помощью приложения карты, которое позволяет пользователю использовать масштабирование по карте, а затем перетащить его.

У меня была проблема с этой библиотекой в ​​IE8, потому что в событиях функции, ссылающихся на mousedown, mousemove и т. Д. IE выдает исключение, сообщая пользователю, что event равно null. Вы можете решить эту проблему, заменив event на e и добавив e = e || event в скрипт raphael.draggable.js. Это исправление не влияет на другие браузеры.

Таким образом, метод MouseMove в startDragger является:

function startDragger() { 
    document.onmousemove = function(e) { 
    e = e || event 
    if (paper.draggable.current()) { 
     var transX = e.clientX - lastDragX; 
     var transY = e.clientY - lastDragY; 

     paper.draggable.current().translate(transX, transY); 
     lastDragX = e.clientX; 
     lastDragY = e.clientY; 
    } 
    }; 
} 

И по ссылке: https://github.com/mephraim/raphael.draggable

Надежда это может помочь вам.

0

В случае, если кто-либо еще ищет решение, вот плагин, который масштабирует, поворачивает и перетаскивает все фигуры, включая пути.

https://github.com/ElbertF/Raphael.FreeTransform

3

Как переводить является устаревшим в Рафаэль, я изменил ответ Натана работать с преобразованием:

var paper = Raphael(10, 50, 320, 200); 

var tri = paper.path("M0 0L0 20L25 10L0 0Z").attr("fill", "#ff0"); 

var start = function() { 
    this.lastdx ? this.odx += this.lastdx : this.odx = 0; 
    this.lastdy ? this.ody += this.lastdy : this.ody = 0; 
    this.animate({"fill-opacity": 0.2}, 500); 
}, 
move = function (dx, dy) { 
    this.transform("T"+(dx+this.odx)+","+(dy+this.ody)); 
    this.lastdx = dx; 
    this.lastdy = dy; 
}, 
up = function() { 
    this.animate({"fill-opacity": 1}, 500); 
}; 

tri.drag(move, start, up); 

Я относительно новым для Рафаэля и придумал это путем проб и ошибка, поэтому у кого-то есть объяснение, почему это работает, или более чистый способ сделать это;)

+0

вот скрипка http://jsfiddle.net/ycqdkgmu/ – danyamachine

+0

Пробовал приведенный выше ответ с помощью этой строки пути: '' M25 370 L10 370 L10 411 L25 411 L25 370 L61 370 L61 411 L25 411 «Это не работает. Интересно, почему? – kittu

Смежные вопросы