Как повернуть ранее перетаскиваемый объект SVG, используя JavaScript и Raphael? - PullRequest
3 голосов
/ 13 октября 2011

Я использую библиотеку Raphael для поворота и перетаскивания изображения. Я правильно перетаскиваю и у меня есть кнопка, которая правильно поворачивает ее на 90 градусов при каждом нажатии. Однако у меня возникла проблема, когда я поворачиваю изображение, перетаскиваю его, а затем снова пытаюсь повернуть.

Единственными элементами в HTML являются div для хранения холста Рафаэля и кнопка, которая поворачивает изображение. JavaScript здесь:

var gboard;
var piece;

window.onload = function () 
{
    gboard = Raphael("gameboard", 800, 500);    
    // piece = gboard.rect(100, 100, 50, 50).attr({fill: "#0CF", "fill-opacity": 1, stroke: "none", cursor: "move"});
    piece = gboard.image("piece.gif", 100, 100, 50, 50).attr({cursor: "move"});
    piece.drag(dragMove, dragStart, dragStop);  
    var angle = 0;

    document.getElementById('btn').onclick = function () {
        angle += 90;
        var cx = piece.attr('x') + 25;
        var cy = piece.attr('y') + 25;
        piece.animate({transform: "R" + angle + ", " + cx + ", " + cy + ""}, 500, "<>");
        // piece.transform("R90," + cx + "," + cy);
    };

}

// Set up the object for dragging
function dragStart() 
{
    this.ox = this.attr("x");
    this.oy = this.attr("y");
}

// Clean up after dragging ends
function dragStop() {}

/**
 * Handle the moving of objects when dragging 
 * Check the current angle to compensate for rotated coordinate system.
 */
function dragMove(dx, dy) 
{
    var angle = getAngle(this._['deg']);
    if (angle == 90)
        this.attr({x: this.ox + dy, y: this.oy - dx});
    else if (angle == 180)
        this.attr({x: this.ox - dx, y: this.oy - dy});
    else if (angle == 270)
        this.attr({x: this.ox - dy, y: this.oy + dx});
    else // angle == 0
        this.attr({x: this.ox + dx, y: this.oy + dy});
}

/** 
 * Get the simplified equivalent angle (0 <= angle <= 360) for the given angle. 
 *
 * @param deg   The angle in degrees
 * @return  The equivalent angle between 0 and 360
 */
function getAngle(deg)
{
    if (deg % 360 == 0)
        return 0;   
    else if (deg < 0)
    {
        while (deg < 0)
            deg += 360;
    }
    else if (deg > 360)
    {
        while (deg > 360)
            deg -= 360;
    }

    return deg;
}

Ответы [ 3 ]

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

Я решил эту проблему, повторно применив все преобразования при изменении значения.

http://alias.io/raphael/free_transform/

Источник: https://github.com/ElbertF/Raphael.FreeTransform

1 голос
/ 08 января 2013

Вместо того, чтобы манипулировать положением с помощью атрибутов x / y и вращением с помощью преобразования, вы можете использовать инструмент преобразования, чтобы справиться с обоими, значительно упрощая ваш проект.

Поскольку мы используем заглавную букву «Т» в переводе, которая игнорирует предыдущие команды перевода в той же строке, нам больше не нужно беспокоиться о текущем угле при перетаскивании.

var gboard, 
    piece;

gboard = Raphael("gameboard", 800, 500);    

var angle = 0,
    x = 100,
    y = 100;

//note that this now starts at 0,0 and is immediately translated to 100,100
piece = gboard.image("piece.gif", 0, 0, 50, 50).attr({cursor: "move", transform: "R" + angle + "T" + x + "," + y });

piece.drag(dragMove, dragStart, dragStop);

document.getElementById('btn').onclick = function () {  
  angle += 90;
  piece.animate({transform: "R" + angle + "T" + x + "," + y}, 500, "<>");
};

// Set up the object for dragging
function dragStart() 
{
    this.ox = x;
    this.oy = y;
}

// Clean up after dragging ends
function dragStop() {}

//Since we're using a capital 'T' in the translation, which ignores previous translation commands in the same string, we no longer have to worry about the current angle here    
function dragMove(dx, dy) {
  x = this.ox + dx;
  y = this.oy + dy;
  piece.attr({ transform: "R" + angle + "T" + x + "," + y });
}

jsFiddle

0 голосов
/ 13 октября 2011

Любопытный;похоже, что вращение фактически изменяет значения x и y.Поэтому, если вы поворачиваете на 90 градусов, перемещение поля на 100 пикселей вправо фактически сдвигает его на 100 пикселей вверх , что затем переводится как значение вправо.Это отбрасывает значения cx и cy, которые определяют точку, вокруг которой вращается блок.

Чтобы увидеть, что я имею в виду, поверните один раз, затем перетащите блок, наблюдая значения X и Y в инспекторе..

Я вижу два способа это исправить: вы можете либо сделать математику, чтобы пересчитать «реальные» x и y при каждом повороте, либо вы можете отслеживать x и y самостоятельно, прикрепиватрибуты данных (что я бы порекомендовал).Удачи!

...