Делегирование функции перетаскивания в Рафаэле - PullRequest
0 голосов
/ 12 января 2012

Используя Рафаэля, я хочу иметь возможность перетаскивать фигуру (эллипс в примере ниже), содержащую текстовый объект, перетаскивая либо фигуру, либо текст.Я надеялся сделать это, установив функции, передаваемые методу drag() текстового элемента, для делегирования связанной фигуре (пробуя более полиморфный подход к этому другому ).Однако это приводит к ошибке « obj.addEventListener не является функцией » при вызове text.drag(...).

Я новичок в javascript, поэтому я, вероятно, сделал действительноочевидная ошибка, но я не могу определить это.Неправильно ли я использовал call() в своих делегирующих функциях moveText, dragText и upText?Или это вещь Рафаэля?Любая помощь будет принята с благодарностью.

<html>
<head>
<title>Raphael delegated drag test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="js/raphael.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<script type="text/javascript">
window.onload = function initPage() {
    'use strict';
    var paper = Raphael("holder", 640, 480);
    var shape = paper.ellipse(190,100,30, 20).attr({
            fill: "green", 
            stroke: "green", 
            "fill-opacity": 0, 
            "stroke-width": 2, 
            cursor: "move"
        });
    var text = paper.text(190,100,"Ellipse").attr({
            fill: "green", 
            stroke: "none", 
            cursor: "move"
        });

    // Associate the shape and text elements with each other
    shape.text = text;
    text.shape = shape;

    // Drag start
    var dragShape = function () {
        this.ox = this.attr("cx");
        this.oy = this.attr("cy");
    } 
    var dragText = function () {
        dragShape.call(this.shape);
    }

    // Drag move
    var moveShape = function (dx, dy) {
        this.attr({cx: this.ox + dx, cy: this.oy + dy});
        this.text.attr({x: this.ox + dx, y: this.oy + dy});
    }
    var moveText = function (dx,dy) {
        moveShape.call(this.shape,dx,dy);
    }

    // Drag release
    var upShape = function () {
    }       
    var upText = function () {
        upShape.call(this.shape);
    }

    shape.drag(moveShape, dragShape, upShape);
    text.drag(moveText, dragText, upText);
};
</script> 
    <div id="holder"></div>
</body>
</html>

Решение

Как указано в в этом ответе , проблема возникает из-за выбораимена атрибутов:

// Associate the shape and text elements with each other
shape.text = text;
text.shape = shape;

Изменение их на более подробные имена (с меньшей вероятностью конфликтовать с Рафаэлем) устраняет проблему, но безопаснее установить их как data атрибутов:

// Associate the shape and text elements with each other
shape.data("enclosedText",text);
text.data("parentShape",shape);

// Drag start
var dragShape = function () {
    this.ox = this.attr("cx");
    this.oy = this.attr("cy");
} 
var dragText = function () {
    dragShape.call(this.data("parentShape"));
}

// Drag move
var moveShape = function (dx, dy) {
    this.attr({cx: this.ox + dx, cy: this.oy + dy});
    this.data("enclosedText").attr({x: this.ox + dx, y: this.oy + dy});
}
var moveText = function (dx,dy) {
    moveShape.call(this.data("parentShape"),dx,dy);
}

1 Ответ

3 голосов
/ 12 января 2012
// Associate the shape and text elements with each other
shape.text = text;
text.shape = shape;

Вы добавляете атрибуты к объектам Рафаэля.Не зная, как Рафаэль работает (или будет работать в будущем), это опасно и, очевидно, также является причиной проблемы.Если вы действительно хотите связать их, я рекомендую использовать Raphaels Element.data: http://raphaeljs.com/reference.html#Element.data

...