缩放和镜像SVG对象

时间:2014-05-27 22:03:17

标签: svg matrix scale flip

我如何最容易地首先缩放一个对象,比如说它当前大小的2倍,然后垂直和水平翻转它们,或两者兼而有之?

截至目前,我可以设置" scale(2,2)"因为它的宽度和高度是它的2倍,但是我不能用它来翻转它,而是用于垂直翻转的刻度(-1,1)。

我以编程方式创建SVG对象,作为要导出的格式。

4 个答案:

答案 0 :(得分:90)

要应用缩放和翻转,只需在变换中列出两者。

transform="scale(2,2) scale(-1,1)"

或简单地组合值

transform="scale(-2,2)"

当然,您使用负标度的问题是,对象会在SVG的原点(左上角)翻转,因此它们可能会脱离文档的边缘。您还需要通过添加翻译来纠正此问题。

因此,例如,假设我们有一个100x100的文档。

<svg width="100" height="100">
    <polygon points="100,0,100,100,0,100"/>
</svg>

要垂直翻转,我们会这样做:

<polygon points="100,0,100,100,0,100" transform="scale(2,-2)"/>

并且为了纠正屏幕上的移动,我们要么在翻转之前将其移动为负(因此它会在屏幕上翻转):

<polygon points="100,0,100,100,0,100" transform="scale(2,-2) translate(0,-100)"/>

(此处列出的翻译是第二个,因为变换列表有效地从右到左应用)

或者我们可以在之后将其转换为正数(按比例缩放):

<polygon points="100,0,100,100,0,100" transform="translate(0,200) scale(-2,2)"/>

Here is a demo showing vertical flip, horizontal flip and both flips

<强>更新

翻转(就位)屏幕上某处的现有对象。首先确定其边界框(minX,minY,maxX,maxY),或 centreX,centreY ,如果您已经知道了。

然后将以下内容添加到其变换中:

translate(<minX+maxX>,0) scale(-1, 1)   // for flip X
translate(0,<minY+maxY>) scale(1, -1)   // for flip Y

或者如果你有中心,你可以使用

translate(<2 * centreX>,0) scale(-1, 1)   // for flip X

所以在你的例子中:

<rect x="75" y="75" width="50" height="50"  transform="translate(-100, -100) scale(2, 2) scale(1, 1) rotate(45, 100, 100)" />

minX + maxX 达到200.所以为了横向翻转,我们提前:

translate(200,0) scale(-1, 1)

所以最终的对象变成:

<rect x="75" y="75" width="50" height="50"  transform="translate(200,0) scale(-1, 1) translate(-100, -100) scale(2, 2) scale(1, 1) rotate(45, 100, 100)" />

Demo here

答案 1 :(得分:9)

只需将以下属性添加到svg中的路径标记中

transform="scale (-1, 1)" transform-origin="center"

例如:<path transform="scale (-1, 1)" transform-origin="center" ......./>

答案 2 :(得分:0)

Here是Livescript式的代码段,您可以通过任意因素水平翻转和缩放:

    # scale is 1 by default

    if mirror or scale isnt 1
        [minx, miny, width, height] = svg.attributes.viewBox |> split-by ',' |> cast-each-as (Number)

        s = scale
        # container is the root `g` node 
        container.attributes.transform = if mirror
            "translate(#{s * (width + minx) + minx}, #{-miny * (s-1)}) scale(#{-s},#{s})"
        else
            "translate(#{-minx * (s-1)}, #{-miny * (s-1)}) scale(#{s},#{s})"

        if scale isnt 1
            svg.attributes
                ..viewBox = "#{minx},#{miny},#{width * scale},#{height * scale}"
                ..width = "#{width * scale}"
                ..height = "#{height * scale}"

答案 3 :(得分:0)

认识企鹅“Tux”。为了这个练习,我在他的脚上画了字母“L”和“R”。

Tux the pinguin

首先,让我们在图像的中心绘制 Tux。如果画布的尺寸为 500x500,而 Tux 的尺寸为 100x100,我们必须将他定位在 (200,200)

  <svg width="500" height="500">
    <!-- marking our border and a cross through the center -->
    <rect x="0" y="0" width="500" height="500" stroke-width="2" stroke="red" fill="none"></rect>
    <line x1="0" y1="0" x2="500" y2="500" stroke="red" stroke-width="2"></line>
    <line x1="500" y1="0" x2="0" y2="500" stroke="red" stroke-width="2"></line>

    <!-- our pinguin in the center -->
    <image x="200" y="200" width="100" height="100" href="assets/pinguin.png"></image>
  </svg>

The result

现在,如果我们想水平镜像我们的 pinguin(左右切换),很容易只使用带有 scale(-1 1) 的变换。但是,当我们尝试这样做时,我们的企鹅就会消失。

  <svg width="500" height="500">
    ...
    <image ... transform="scale(-1 1)"></image>
  </svg>

pinguin is gone

原因是我们变换的默认反射点(所谓的“变换原点”)不在图像的中心,但实际上仍在(0,0)点。< /p>

最明显的解决方案是将反射点移动到我们图像的中心点 (250,250)。 (在本例中,是画布的中心)。

  <svg width="500" height="500">
    ...
    <image ... transform="scale(-1 1)" transform-origin="250 250"></image>
  </svg>

Change the transform origin

调整大小的工作原理完全相同。您可以用 2 个音阶进行,也可以将它们合并为 1 个音阶。

  <svg width="500" height="500">
    <!-- use 2 scales -->
    <image x="200" y="200" width="100" height="100" href="assets/pinguin.png"
           transform="scale(-1 1) scale(2 2)" transform-origin="250 250">
    </image>    
    <!-- or just multiply the values of both scales -->
    <image x="200" y="200" width="100" height="100" href="assets/pinguin.png"
           transform="scale(-2 2)" transform-origin="250 250">
    </image>
  </svg>

still 2 options