Как реализовать перетаскивание для приложения рисования HTML5 Canvas? - PullRequest
2 голосов
/ 06 декабря 2011

На основе Создание приложения для рисования холста HTML 5 Я создал приложение для рисования холста HTML5. Это работает нормально, но после создания каждого объекта мне просто нужно перетащить объекты. Рабочая демоверсия

Как реализовать перетаскивание фигур?

Ответы [ 5 ]

3 голосов
/ 07 декабря 2011

Тот же эффект может быть достигнут с помощью Raphael.js (http://raphaeljs.com/) с Joint.jS (http://www.jointjs.com/).

К формам, созданным с помощью Raphael, можно обращаться, как к любому элементу DOM, и ими можно управлять с помощью атрибутов. Это потрясающая структура.

Joint.js помогает в соединении фигур. Они также имеют библиотеку диаграмм и могут помочь в создании ERD, Statemachine и нескольких общих диаграмм. Самое приятное, что вы можете расширить их элемент диаграммы и создать свои собственные элементы. Его потрясающе прохладно.

Оформить заказ с исходным кодом на http://www.jointjs.com/demos

3 голосов
/ 06 декабря 2011

Когда пользователь нажимает на холст, вы должны проверить координаты (сравнить его с координатами для объектов) и посмотреть, находится ли он на объекте. Например. Вы можете проверить, находится ли точка (например, координаты четного mousedown) внутри круга с помощью этого метода:

function (pt) {
    return Math.pow(pt.x - point.x,2) + Math.pow(pt.y - point.y,2) < 
                                                             Math.pow(radius,2); 
};

Если mousedown находится на объекте, вы должны изменить координаты объекта в соответствии с тем, как движется мышь.

Вот пример, где вы можете перетащить круг:

<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function() {
    drawCircle(circle);
    element = document.getElementById('canvas');
    element.addEventListener('mousedown', startDragging, false);
    element.addEventListener('mousemove', drag, false);
    element.addEventListener('mouseup', stopDragging, false);
    element.addEventListener('mouseout', stopDragging, false);
}

function mouseX(e) {
return e.clientX - element.offsetLeft;
}

function mouseY(e) {
return e.clientY - element.offsetTop;
}

var Point = function (x, y) {
    this.x = x;
    this.y = y;
    return this;
}

var Circle = function (point, radius) {
    this.point = point;
    this.radius = radius;
    this.isInside = function (pt) {
        return Math.pow(pt.x - point.x, 2) + Math.pow(pt.y - point.y, 2) <
                                                          Math.pow(radius, 2); 
    };
    return this;
}

function startDragging(e) {
    var p = new Point(e.offsetX, e.offsetY);
    if(circle.isInside(p)) {
        deltaCenter = new Point(p.x - circle.point.x, p.y - circle.point.y);
    }
}

function drag(e) {
    if(deltaCenter != null) {
        circle.point.x = (mouseX(e) - deltaCenter.x);
        circle.point.y = (mouseY(e) - deltaCenter.y);   
        drawCircle(circle);
    }
}

function stopDragging(e) {
    deltaCenter = null;
}

function drawCircle(circle) {
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.arc(circle.point.x, circle.point.y, circle.radius, 0, Math.PI*2, true);
    ctx.fill();
}

var circle = new Circle(new Point(30, 40), 25);
var deltaCenter = null;
var element;

</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>

Попробуйте на jsFiddle

2 голосов
/ 16 мая 2012

Если вы используете Рафаэль в качестве «сырой» библиотеки, вы должны самостоятельно отменить / повторить.В графической библиотеке есть стек Undo / Redo и поддерживается экспорт для SVG, PNG, JSON, ...

Дополнительно, у вас есть какие-то Viso-соединители и порты.

http://www.draw2d.org/graphiti/jsdoc/#!/example

Привет

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

Объекты, нарисованные в HTML5 Canvas, превращаются в пиксели, а затем забываются. Вы не можете настроить свойства для них и обновить холст, чтобы увидеть эффекты. Вы можете помнить их самостоятельно, но на холсте все равно будут установлены эти пиксели, поэтому вам придется перерисовывать весь холст (или хотя бы его часть) при настройке свойства.

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

Если вам нужно использовать canvas, вам понадобится написать немало кода для обработки нажатий мыши, свойств объектов и перерисовок.

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

Я не думаю, что есть простой способ сделать это.

Если вы имеете дело только со строками, мой подход заключается в отслеживании всех созданных линий, с начальными координатами, конечными координатами и каким-то z-индексом. Когда пользователь начинает действие перетаскивания (onmousedown), необходимо проверить, находится ли точка рядом с линией, а затем обновить объект и перерисовать холст при перемещении мыши.

Как узнать, принадлежит ли точка определенной линии?

Это становится намного сложнее, если вы имеете дело со сложными объектами. Возможно, вам придется найти решение, чтобы проверить, находится ли точка внутри пути.

...