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

Создание путей и изображений, перетаскиваемых в 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>
4b9b3361

Ответ 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