manim icon indicating copy to clipboard operation
manim copied to clipboard

Fix `Write()` stroke width to scale with `font_size` or object scale

Open irvanalhaq9 opened this issue 8 months ago • 1 comments

Overview: What does this pull request change?

  1. Fix #4220
  2. Add docstring

Motivation and Explanation: Why and how do your changes improve the library?

Previously, the stroke effect was hardcoded and appeared too thick on small fonts and too thin on large ones.

This PR introduces a helper method _adjust_stroke_width_for_text() that dynamically adjusts the stroke width based on the font size of the text, proportionally scaled to 25% of the default stroke width.

The adjustment only applies when:

  • The the font_size is too small, such as below 20, so zooming-in is needed.
  • The the font_size is too big, but this is actually not a problem, but scaling stroke_width make it look better.
  • The stroke_width is not explicitly provided by the user.

For all other cases, the stroke_width is 2.0 (default from DrawBorderThenFill), and behaves like before this change.

Links to added or changed documentation pages

https://manimce--4222.org.readthedocs.build/en/4222/reference/manim.animation.creation.Write.html

Further Information and Comments

Test:

class WriteScaleStrokeWidth(MovingCameraScene):
    def construct(self):
        self.add(NumberPlane())
        test1 = MathTex(r"\text{MatText Test}").scale(4).set_color(RED)
        self.play(Write(test1,run_time=2))
        
        test2 = Text("Text Test").scale(0.1).set_color(BLUE).next_to(test1, DOWN*2)
        camera_frame = self.camera.frame
        self.play(
            camera_frame.animate(rate_func=linear).set(width=test2.width+0.2).move_to(test2)
        )
        wr = Write(test2,run_time=2)
        self.play(wr)
        self.wait()

Before the fix:

https://github.com/user-attachments/assets/e3dbbd65-6a90-46e5-b85e-77ef7f2c20ba

After the fix:

https://github.com/user-attachments/assets/9f9bd9a7-84e5-4acf-9885-4f2dd77f3ed6

Reviewer Checklist

  • [ ] The PR title is descriptive enough for the changelog, and the PR is labeled correctly
  • [ ] If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
  • [ ] If applicable: newly added functions and classes are tested

irvanalhaq9 avatar Apr 19 '25 14:04 irvanalhaq9

I'm still not sure why the tests are failing — the code works fine on my local machine. Is there something in my code that I need to change?

Edit: I've addressed the failed test by scaling stroke_width only if font_size is too small or too large, and the vmobject has a non-zero height.

My investigation:

  1. Too small in normal Scene appear: the font_size < 20, so zooming-in is needed.
  2. Too big is actually not a problem, but scaling stroke_width make it look better.
  3. If the mobject height is zero, accessing font_size causes ZeroDivisionError.

For other cases, it behaves like before.

irvanalhaq9 avatar Apr 21 '25 17:04 irvanalhaq9