Создание путей и изображений, перетаскиваемых в 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
Ключ здесь (который я нашел) заключается в преобразовании дельтах x и y в значения трансляции, которые понимает объект пути.
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);
Ответ 2
Поскольку перевод устарел в Рафаэле, я изменил ответ Натана на работу с преобразованием:
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);
Я относительно новичок в Рафаэле и придумал это посредством проб и ошибок, поэтому у кого-то есть объяснение, почему это работает, или более чистый способ сделать это;)
Ответ 3
Я экспериментировал с этим несколько лет назад и получил его работу, используя следующий подход:
- Добавьте первоначально скрытый, стилизованный, абсолютно позиционированный div с прозрачным фоном и подходящим стилем для вашей страницы, а использование jQuery/UI сделает его перетаскиваемым.
- Добавьте событие click для каждого из элементов Rapahel/SVG, которые вы хотите перетащить, и в этом случае добавьте код, чтобы изменить размер и переместить div над элементом, который только что щелкнул, а затем сделать его видимым.
- Добавить код в div, который обновляет положение элемента Рафаэля при его перетаскивании.
Я добавил это, чтобы добавить возможности изменения размера, и это также сработало хорошо, но в будущем было бы замечательно видеть возможности перетаскивания, удаления и изменения размера (идеально правильно интегрированные в библиотеку, а не с помощью jQuery), встроенные в Raphael, поскольку эти функции открывали бы целый ряд возможностей для разработчиков в браузере с использованием чистого Raphael.
Ответ 4
Попробуйте это для не-кругов. Я считаю, что атрибуты 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, ">");
};
Ответ 5
Я бы порекомендовал вам библиотеку raphael.draggable, которая делает трюк для вас. Я использовал его с помощью приложения карты, которое позволяет пользователю использовать масштабирование по карте и затем перетащить его.
У меня возникла проблема с этой библиотекой в IE8, потому что в событиях функции, ссылающихся на mousedown, mousemove и т.д. IE исключает исключение, сообщая пользователю, что event
имеет значение null. Вы можете решить его, заменив event
на e
и добавив e = e || event
в файл raphael.draggable.js script. Это исправление не влияет на другие браузеры.
Итак, метод 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
Надеюсь, это поможет вам.
Ответ 6
Это не так сложно, если вы понимаете обычные функции перетаскивания, которые дал вам Крис Батлер.
Я использую это:
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, чтобы вы могли выполнять эти функции для всех фигур.
Ответ 7
Если кто-то все еще ищет решение, вот плагин, который масштабирует, вращает и перетаскивает все фигуры, включая пути.
https://github.com/ElbertF/Raphael.FreeTransform