拉斐尔变换 - 缩放然后旋转,倾斜效果

时间:2013-12-20 22:52:12

标签: javascript html5 svg raphael

这是我遇到的问题的一个问题:

http://jsfiddle.net/Tw4Qh/1/

鉴于此html:

<div id="box"></div>

和这个js(都在jsfiddle演示):

var paper = Raphael('box', 300, 300);
var center = { x:150, y:150 }, size = { x:10, y:10 };
var look = { stroke:'#000000', 'stroke-width':1,
    fill:'#888888', opacity:1, 'stroke-opacity':0.9,
    'fill-opacity': 0.7, 'stroke-dasharray': '- '
};
var path = paper.path('').attr(look);

function reset() {
    // reset to small square
    path.attr({ path:[
        [ 'M', center.x - size.x, center.y - size.y ],
        [ 'L', center.x + size.x, center.y - size.y ],
        [ 'L', center.x + size.x, center.y + size.y ],
        [ 'L', center.x - size.x, center.y + size.y ],
        [ 'z' ]
    ] }).transform([]);
    console.log(path._.transform);
}

function add_state_one() {
    // move down and left slightly and scale up
    path.transform(path._.transform.concat([
        [ 'T', -50, 10 ],
        [ 'S', 2.5, 7.5 ]
    ]));
    console.log(path._.transform);
}

function add_state_two() {
    // use bounding box center
    var bb = path.getBBox(),
        center = { x:(bb.x + bb.x2)/2, y:(bb.y + bb.y2)/2 };
    path.transform(path._.transform.concat([
        [ 'R', 30, center.x, center.y ],
        [ 'S', 0.8, 0.7, center.x, center.y ]
    ]));
    console.log(path._.transform);
}

function add_state_three() {
    // use original center
    path.transform(path._.transform.concat([
        [ 'R', 45, center.x, center.y ],
        [ 'S', 0.7, 0.5, center.x, center.y ]
    ]));
    console.log(path._.transform);
}

// buttons
var blook = { 'stroke-dasharray':'', stroke:'transparent' };
var btn = {
    rst:paper.path([ [ 'M', 0, 0 ], [ 'L', 10, 0 ],
               [ 'L', 10, 10 ], [ 'L', 0, 10 ], [ 'z' ] ])
        .attr(look).attr(blook).click(reset),
    st1:paper.path([ [ 'M', 20, 0 ], [ 'L', 30, 0 ],
            [ 'L', 30, 10 ], [ 'L', 20, 10 ], [ 'z' ] ])
        .attr(look).attr(blook).attr({ fill:'#0000ff' })
        .click(add_state_one),
    st2:paper.path([ [ 'M', 40, 0 ], [ 'L', 50, 0 ],
            [ 'L', 50, 10 ], [ 'L', 40, 10 ], [ 'z' ] ])
        .attr(look).attr(blook).attr({ fill:'#ff0000' })
        .click(add_state_two),
    st3:paper.path([ [ 'M', 60, 0 ], [ 'L', 70, 0 ],
            [ 'L', 70, 10 ], [ 'L', 60, 10 ], [ 'z' ] ])
        .attr(look).attr(blook).attr({ fill:'#00ff00' })
        .click(add_state_three)
};

// click grey
reset();

基本上我需要应用比例,然后应用旋转,而旋转不受比例的影响。

想象一下你有一个正方形。现在你对它应用一个比例,这样它就是一个高大的矩形。现在,您希望旋转此生成的矩形,使其保持矩形,具有直角,但角度为45度。我们正在努力实现一个在一个角落平衡的矩形,倾斜45度角。相反,正如在jsfiddle中所展示的那样,当我应用一个比例(产生一个矩形),然后一个旋转(将它倾斜在一个角落上)时,我转而使用一个倾斜的矩形(或奇怪的钻石)。

我确信有些人知道如何实现这一目标。最终我计划从多个原点添加多个不同的变换(平移,旋转和缩放),但我不希望这种偏斜效应发生。试图解决这个问题。任何帮助表示赞赏。

由于

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,经过一段时间试图找到它究竟来自哪里,我想出了导致它是不规则尺度的原因。每当您的x轴和y轴按比例缩放时,就会发生这种情况。

我所做的就是在旋转之前撤消不规则缩放,然后重做它。要撤消它,您应该通过原始比例的反转来重新缩放它。在您的示例中,要使状态2正常工作,您可以执行以下操作:

function add_state_two() {
    // use bounding box center
    var bb = path.getBBox(),
        center = { x:(bb.x + bb.x2)/2, y:(bb.y + bb.y2)/2 };
    path.transform(path._.transform.concat([
        [ 'S', 1/2.5, 1/7.5, center.x, center.y ],
        [ 'R', 30, center.x, center.y ],
        [ 'S', 2.5*0.8, 7.5*0.7, center.x, center.y ]
    ]));
    console.log(path._.transform);
}

首先,我让它恢复到原来的1:1比例。然后旋转它,然后重新缩放它。注意我将第二个刻度上的原始值乘以新值,因此您没有两个单独的刻度。这应该有用。

http://jsfiddle.net/Tw4Qh/2/