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

Support LaTex Tweening #482

Open
levirs565 opened this issue Mar 6, 2023 · 5 comments · May be fixed by #800
Open

Support LaTex Tweening #482

levirs565 opened this issue Mar 6, 2023 · 5 comments · May be fixed by #800
Assignees
Labels
a-2d Relates to the 2d package b-enhancement New feature or request c-accepted The issue is ready to be worked on

Comments

@levirs565
Copy link
Contributor

levirs565 commented Mar 6, 2023

Description
Math video need LaTex Tweening like in Manim.

Proposed solution
Parse MathJax rendered SVG and render each shape from SVG manually. Then we can animate each shape.

To tween LaTex we can use this function:

yield * tex().tweenTex(target tex, duration)

Considered alternatives
Use external library for doing it.

Additional context

I have been working on this issue but PR are closed.

@levirs565
Copy link
Contributor Author

levirs565 commented Mar 7, 2023

This my experiment result:

out.mp4

To render Tex I use this methods:

  • Convert Tex to SVG
  • Parse SVG and extract all path
  • Render path to canvas

To tween Tex I use this methods:

  • Diff path between new and old tex
  • Animate diff like in CodeBlock component

You can see Latex component code in this url.

Scene code is this:

import {Latex} from '@motion-canvas/2d/lib/components';
import {makeScene2D} from '@motion-canvas/2d/lib/scenes';
import {waitFor} from '@motion-canvas/core/lib/flow';
import {createRef} from '@motion-canvas/core/lib/utils';

export default makeScene2D(function* (view) {
  const tex = createRef<Latex>();
  view.add(
    <Latex
      ref={tex}
      tex="{\color{white} x = \sin \left( \frac{\pi}{2} \right)}"
      y={0} // height and width can calculate based on each other
    />,
  );

  yield* waitFor(2);
  yield* tex().tweenTex(
    '{\\color{white} x = \\sin \\left( \\frac{\\pi}{2} \\right) + 3}',
    1,
  );
  yield* tex().tweenTex(
    '{\\color{white} x = 1 + \\sin \\left( \\frac{\\pi}{2} \\right) + 3}',
    1,
  );
  yield* tex().tweenTex(
    '{\\color{white} x = 3 + \\sin \\left( \\frac{\\pi}{2} \\right) + 1}',
    1,
  );
  yield* tex().opacity(0, 1);
  yield* waitFor(2);
  yield* tex().opacity(1, 1);
  yield* tex().tweenTex(
    '{\\color{white} x = \\sin \\left( \\frac{\\pi}{2} \\right)}',
    8,
  );
});

@aarthificial Are you accept this?

@aarthificial
Copy link
Contributor

Thanks for making the issue

@aarthificial aarthificial added b-enhancement New feature or request c-accepted The issue is ready to be worked on a-2d Relates to the 2d package labels Mar 12, 2023
@levirs565
Copy link
Contributor Author

I have new way to tweening Latex. First, we need create component SVG Component.

SVG Component will convert SVG node into Motion Canvas Shape and add shape into component as children. We can animate SVG child using normal tweening. This component also can tween between two SVG. Here is my SVG component code.

Latex component will inherit SVG component. We just need convert Latex into SVG. To tween Latex we just tween the SVG component. Here is my Latex component

This will not only resolve this issue. But also resolve this issue.

The result of this way is equal to old one.

I will merge my component into this repository when my SVG component can render most of SVG node.

@levirs565
Copy link
Contributor Author

I have problem when placing my SVG component into Layout.

My SVG component is rendered correctly. However, other component inside layout is gone.

After some investigation. I found that, Layout component does not respect scale.

@aarthificial
Copy link
Contributor

Layout component does not respect scale.

This is by design, no layout engines support rudimental scaling/rotation - it would be a nightmare to handle.
The SVG node should respect the width and size properties in the same way images do.

This component also can tween between two SVG

Note that your solution to tweening is vastly different than the one Manim uses.
It's good enough for me but that's not what you mentioned in the description of the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a-2d Relates to the 2d package b-enhancement New feature or request c-accepted The issue is ready to be worked on
Projects
None yet
2 participants