Создание путей и изображений, перетаскиваемых в Рафаэле - PullRequest
17 голосов
/ 19 ноября 2010

Возможно ли иметь возможность перетаскивать объекты, отличные от кругов и прямоугольников, вокруг страницы, используя 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>

Ответы [ 7 ]

13 голосов
/ 27 января 2011

Ключ (который я нашел) состоит в том, чтобы преобразовать дельты 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);
3 голосов
/ 03 апреля 2013

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

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

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

1 голос
/ 01 сентября 2011

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

У меня была проблема с этой библиотекой в ​​IE8, потому что в событиях функции упоминались mousedown, mousemove и т. Д.IE исключает исключение, сообщая пользователю, что event равно нулю.Вы можете решить эту проблему, заменив 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

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

1 голос
/ 06 декабря 2010

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

    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, ">");
    };
1 голос
/ 19 ноября 2010

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

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

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

0 голосов
/ 27 ноября 2011

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

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

0 голосов
/ 03 января 2011

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

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, чтобы вы могли заставить эти функции работать для всех видов рисунков.

...