将转换应用于 SVG 路径上先前转换的结果

Apply transformation to result of previous transformation on SVG path

如果我将 (100, 0) 的翻译应用于 SVG 路径,它会向左移动 100 像素。但是如果我先旋转路径,那么平移就会沿着对角线发生。

我明白为什么会这样——旋转使轴旋转,从而使沿 x 轴的平移不再水平。然而,有时这是不可取的,当我想对前一个结果应用转换而不是让它受到或影响那些以前的结果时。

我知道一个解决方案是将转换后的路径放在组元素中,然后将第二个转换应用于该组。但我想尽可能避免创建组元素。在研究这个问题时,我遇到了 Flatten.js,其中 "flattens" 转换。换句话说,它修改了元素的原始路径,以使其等效于转换。但是,这似乎只适用于整个 svg 元素,而不适用于其中的各个路径。

我目前正在与 Snap.svg 合作以备不时之需。不过,我无法在文档中找到与此相关的任何内容。

为了阐明我要完成的任务,请看这三个示例:

Square simply rotated

Rotate square, translate square 正方形旋转,然后沿 x 轴平移 50。但由于 x 轴现在已经旋转,正方形实际上也沿对角线向下移动。就是这个问题。

Rotate Square, put in group, translate group 通过将正方形放入一个组中,然后对组元素应用平移,正方形纯粹在水平方向上移动。这就是我想要实现的,但不必将正方形放在一个组中。

只需颠倒转换操作的顺序

matrix.translate(50,0).rotate(45, bounds.cx, bounds.cy);

Snap.svg 的答案确实在文档中:Snap.path.map

我是这样使用的:

    var new_shape = original_shape.paper.path(
        Snap.path.map(
            original_shape.realPath.toString(),
            original_shape.transform().localMatrix
        )
        .toString()
    );

这将创建原始形状的克隆,但使用 path 元素并将所有命令变成 C

把上面的代码放到一个只有一个参数的函数中——原形:

function bakeMatrix(){
    var new_shape = original_shape.paper.path(
        Snap.path.map(
            original_shape.realPath.toString(),
            original_shape.transform().localMatrix
        )
        .toString()
    );
}

或者,更好的是,创建一个 Snap.svg 插件:

Element.prototype.bakeMatrix = function(replace){

    var shape = this.paper.path(
        Snap.path.map(
            this.realPath.toString(),
            this.transform().localMatrix
        )
        .toString()
    );

    if (replace) this.remove();
    return shape;
};

有了那个插件,我可以简单地调用 shape.bakeMatrix() 并获得形状的克隆,所有的转换都被烘焙到路径中。附加参数 replace 可让您决定是否应在此过程中丢弃原始形状,只留下转换烘焙的克隆。