Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of SVG transform and Some refactors #1712

Merged
merged 15 commits into from
Jan 25, 2022
Merged

Improve handling of SVG transform and Some refactors #1712

merged 15 commits into from
Jan 25, 2022

Conversation

TonyCrane
Copy link
Collaborator

Motivation

ManimGL only supports matrix(...), scale(...), translate(...) transform, and doesn't support multiple transformation in a single transform property, which causes many issues.

For example

Code:

class Code(Scene):
    def construct(self):
        svg = SVGMobject("formula.svg", stroke_width=0).set_width(13)
        self.add(svg)

formula

Result:
image

This pull request adds full support for all transforms in the svg standard, which are matrix translate scale rotate skewX skewY.
And refactors the parsing of the name and parameters of each transform by referring to https://github.com/cjlano/svg/blob/3ea3384457c9780fa7d67837c9c5fd4ebc42cb3b/svg/svg.py#L75.

Proposed changes

  • Mmanimlib/mobject/mobject.py: allow Mobject.scale receive iterable scale_factor clip it with min_scale_factor
  • Mmanimlib/mobject/svg/svg_mobject.py: replace warnings.warn with log.warning
  • Mmanimlib/mobject/svg/svg_mobject.py: refactor SVGMobject.handle_transforms and add support for rotate and skewX skewY

Test

The current performance of the above example

Code:

class Code(Scene):
    def construct(self):
        svg = SVGMobject("formula.svg", stroke_width=0).set_width(13)
        self.add(svg)

formula
Result:
image

rotate

Code:

class Code(Scene):
    def construct(self):
        svg = SVGMobject("test.svg")
        self.add(svg)
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <rect width="300" height="100" transform="rotate(60)"/>
</svg>

Result:
image

skewX and skewY

Code:

class Code(Scene):
    def construct(self):
        svg = VGroup(
            SVGMobject("skewX.svg"),
            SVGMobject("skewY.svg")
        ).arrange(RIGHT)
        self.add(svg)

skewX.svg:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <rect width="300" height="100" transform="skewX(30)"/>
</svg>

skewY.svg:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <rect width="300" height="100" transform="skewY(30)"/>
</svg>

Result:
image

@TonyCrane
Copy link
Collaborator Author

I added a new class _PathStringParser to parse the path string.
Because the A command receives three numbers and two flag (which can only be 0 or 1) and then two numbers, the path string may be like A1.0 1.0 0 11.1 which represents 1.0 1.0 0 1 1 0.1.

@TonyCrane
Copy link
Collaborator Author

@3b1b, this pull request is ready to be merged :)

@3b1b
Copy link
Owner

3b1b commented Jan 25, 2022

Thanks for doing this!

@3b1b 3b1b merged commit 07f84e2 into master Jan 25, 2022
@3b1b 3b1b deleted the fix-svg branch January 25, 2022 21:26
TonyCrane added a commit that referenced this pull request Jan 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants