svg.path icon indicating copy to clipboard operation
svg.path copied to clipboard

Allow to apply transform to path

Open Harvie opened this issue 6 years ago • 2 comments

As described in https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform

it's common for svg <path> element to have transform="" attribute

typicaly it looks something like this:

<path id="something" d="..."  transform="rotate(-10 50 100)
                translate(-36 45.5)
                skewX(40)
                scale(1 0.5)" />

Can you please add possibility to apply this transformation if supplied to svg.path during parsing stage? In fact only support for rotate(), translate() and scale() is needed in most cases. It should be pretty easy to do.

In ideal case svg.path would take two individual strings: d attribute and transform attribute. It would be also perfect, if i can just supply whole <path ... /> string and svg.path would extract the data from it, so i don't need to parse it by myself. Or even whole SVG file, which would in turn get exploded into multiple paths.

Thanks

Harvie avatar Aug 21 '18 00:08 Harvie

This is the same as issue #31, although the title doesn't make that obvious, so I'll keep both open.

regebro avatar Aug 21 '18 14:08 regebro

Any complex number can z can be represented with the matrix.

complex-matrix

Which means just doing typical operations with in complex numbers.

For scale, multiply by scale (no imaginary part). For rotation by theta, you multiply by cos(theta)+i sin(theta) For translation you add dx + i dy

For you skew matrix we need to multiply by a value that has two different imaginary components so I think that's a convert back to reals do the math and put it back. (1 0) (k 1)

Given his code doesn't do anything other than parse SVG paths into Path objects he should generally just allow for scale, rotate, and translation objects on all the elements there as well as the path object itself. Which means just doing those operations on particular elements.

I think a couple functions like:

class CubicBezier(object):
    ...
    def rotate(self, theta):
        """Rotate the Bezier curve by theta radians"""
        rotate = cos(theta) + sin(theta) * 1j
        self.start *= rotate
        self.control1 *= rotate
        self.control2 *= rotate
        self.end *= rotate

would do it.

tatarize avatar Jun 28 '19 19:06 tatarize