Skip to content

feat(2d): use SVG component in Latex and support tweening#800

Merged
aarthificial merged 10 commits intomotion-canvas:mainfrom
levirs565:latex3
Aug 13, 2024
Merged

feat(2d): use SVG component in Latex and support tweening#800
aarthificial merged 10 commits intomotion-canvas:mainfrom
levirs565:latex3

Conversation

@levirs565
Copy link
Contributor

This PR add tweening support for Latex component. This PR will fix #482

How it Work?

Latex component now inherit SVG component. Latex tweening algorithm will follow SVG tweening algorithm.

Changed Behavior

Old behavior: Latex component's size is depend on custom width or custom height
New behavior: Latex component's size is depend on font size. With this, With this, we can synchronize Txt size and Latex size more easily.

Latex Tweening

Latex can be splitted into subtex. To make subtex we just enclose part of tex with {{}}. Why?. The reason is to make tweening more flexible. User can choose where transformed, inserted or deleted subtex.

Latex svg propery can be string or array of string. When it string, it will be parsed to list of substring.

How to Use?

To use Latex tweening we can use tween tex property as normal.

Examples and Result

This is example usage of Latex tweening:

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={['y{{=}}{{a}}{{x^2}}']} fill="white" />);

  yield* waitFor(0.5);
  yield* tex().tex(['y', '=', '{{a}}{{x^2}} + {{bx}}'], 1);
  yield* waitFor(0.5);
  yield* tex().tex(['y', '=', '{{c}} + {{a}}{{x^2}} + {{bx}}'], 1);
  yield* waitFor(0.5);
  yield* tex().tex(['y', '=', '{{a}}{{x^2}} + {{bx}} + {{c}}'], 1);
  yield* waitFor(0.5);
  yield* tex().tex(['y', '=', '{{x^2}}'], 1);
  yield* waitFor(0.5);
  yield* tex().tex(['y', '=', '{{a}}{{x^2}}'], 1);
  yield* waitFor(0.5);
  yield* tex().tex(['y', '=', '\\left({{a}}{{x^2}}\\right)'], 1);
  yield* waitFor(0.5);
  yield* tex().tex(
    ['y', '=', '{{\\left(}}{{a}}{{x^2}}{{\\over 1}}{{\\right)}}'],
    1,
  );
  yield* tex().fontSize(96, 2);
});

Here is the result:

out.mp4

@levirs565 levirs565 changed the title feat(2d): use SVG component in Latex and support t feat(2d): use SVG component in Latex and support tweening Aug 27, 2023
@fangjunzhou
Copy link
Contributor

Does this branch support changing the color of some parts of the latex? Let's say highlight some parts of the equation for example.

@benniel
Copy link

benniel commented Dec 3, 2023

I get the following errors when running your example:

this.string.codePointAt is not a function
The problem occurred here:

27 |   yield* tex().fontSize(96, 2);
   |                ^
28 | });
29 | 

at node_modules/mathjax-full/js/input/tex/TexParser.js/TexParser2.prototype.getCodePoint (/node_modules/.vite/deps/chunk-Y63HJXGX.js:6189:32)
at node_modules/mathjax-full/js/input/tex/TexParser.js/TexParser2.prototype.Parse (/node_modules/.vite/deps/chunk-Y63HJXGX.js:6145:20)
at TexParser2 (/node_modules/.vite/deps/chunk-Y63HJXGX.js:6078:14)
at node_modules/mathjax-full/js/input/tex.js/TeX3.prototype.compile (/node_modules/.vite/deps/chunk-Y63HJXGX.js:11771:25)
at node_modules/mathjax-full/js/core/MathItem.js/AbstractMathItem2.prototype.compile (/node_modules/.vite/deps/chunk-Y63HJXGX.js:903:37)
at node_modules/mathjax-full/js/core/MathDocument.js/RenderList2.methodActions/RenderList< (/node_modules/.vite/deps/chunk-Y63HJXGX.js:43955:37)
at node_modules/mathjax-full/js/core/MathDocument.js/RenderList2.prototype.renderConvert (/node_modules/.vite/deps/chunk-Y63HJXGX.js:44021:29)
at node_modules/mathjax-full/js/core/MathItem.js/AbstractMathItem2.prototype.convert (/node_modules/.vite/deps/chunk-Y63HJXGX.js:899:33)
at node_modules/mathjax-full/js/core/MathDocument.js/AbstractMathDocument2.prototype.convert (/node_modules/.vite/deps/chunk-Y63HJXGX.js:44206:15)
at image (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49756:47)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at desiredSize (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49383:26)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47384:23)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49455:11)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at updateLayout (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47268:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at requestLayoutUpdate (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47251:12)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at (/node_modules/.vite/deps/chunk-Y63HJXGX.js:45847:12)
at getter (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5304:37)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at createQueue (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5328:26)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5324:24)
at (
)
at next (/node_modules/.vite/deps/chunk-BRNMUPSA.js:3563:32)
at threads (/node_modules/.vite/deps/chunk-BRNMUPSA.js:3627:29)
at next/result< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4286:49)
at execute (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4377:16)
at next (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4286:23)
at next (/node_modules/.vite/deps/chunk-CYBRUBDT.js:33:18)
at recalculate (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4269:18)
image is undefined
The problem occurred here:

27 |   yield* tex().fontSize(96, 2);
   |                ^
28 | });
29 | 

at desiredSize (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49385:9)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47384:23)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49455:11)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at updateLayout (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47268:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at requestLayoutUpdate (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47251:12)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at (/node_modules/.vite/deps/chunk-Y63HJXGX.js:45847:12)
at getter (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5304:37)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at createQueue (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5328:26)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5324:24)
at (
)
at next (/node_modules/.vite/deps/chunk-BRNMUPSA.js:3563:32)
at threads (/node_modules/.vite/deps/chunk-BRNMUPSA.js:3627:29)
at next/result< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4286:49)
at execute (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4377:16)
at next (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4286:23)
at next (/node_modules/.vite/deps/chunk-CYBRUBDT.js:33:18)
at recalculate (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4269:18)
size is undefined
The problem occurred here:

27 |   yield* tex().fontSize(96, 2);
   |                ^
28 | });
29 | 

at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47385:49)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49455:11)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at updateLayout (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47268:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at requestLayoutUpdate (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47251:12)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at (/node_modules/.vite/deps/chunk-Y63HJXGX.js:45847:12)
at getter (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5304:37)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at createQueue (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5328:26)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5324:24)
at (
)
at next (/node_modules/.vite/deps/chunk-BRNMUPSA.js:3563:32)
at threads (/node_modules/.vite/deps/chunk-BRNMUPSA.js:3627:29)
at next/result< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4286:49)
at execute (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4377:16)
at next (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4286:23)
at next (/node_modules/.vite/deps/chunk-CYBRUBDT.js:33:18)
at recalculate (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4269:18)
this.string.codePointAt is not a function
The problem occurred here:
at node_modules/mathjax-full/js/input/tex/TexParser.js/TexParser2.prototype.getCodePoint (/node_modules/.vite/deps/chunk-Y63HJXGX.js:6189:32)
at node_modules/mathjax-full/js/input/tex/TexParser.js/TexParser2.prototype.Parse (/node_modules/.vite/deps/chunk-Y63HJXGX.js:6145:20)
at TexParser2 (/node_modules/.vite/deps/chunk-Y63HJXGX.js:6078:14)
at node_modules/mathjax-full/js/input/tex.js/TeX3.prototype.compile (/node_modules/.vite/deps/chunk-Y63HJXGX.js:11771:25)
at node_modules/mathjax-full/js/core/MathItem.js/AbstractMathItem2.prototype.compile (/node_modules/.vite/deps/chunk-Y63HJXGX.js:903:37)
at node_modules/mathjax-full/js/core/MathDocument.js/RenderList2.methodActions/RenderList< (/node_modules/.vite/deps/chunk-Y63HJXGX.js:43955:37)
at node_modules/mathjax-full/js/core/MathDocument.js/RenderList2.prototype.renderConvert (/node_modules/.vite/deps/chunk-Y63HJXGX.js:44021:29)
at node_modules/mathjax-full/js/core/MathItem.js/AbstractMathItem2.prototype.convert (/node_modules/.vite/deps/chunk-Y63HJXGX.js:899:33)
at node_modules/mathjax-full/js/core/MathDocument.js/AbstractMathDocument2.prototype.convert (/node_modules/.vite/deps/chunk-Y63HJXGX.js:44206:15)
at image (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49756:47)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at desiredSize (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49383:26)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47384:23)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49455:11)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at updateLayout (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47268:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at requestLayoutUpdate (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47251:12)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at computedSize (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47241:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at getWidth (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47069:17)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5319:19)
at getter/< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5494:86)
at getter (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5494:55)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5319:19)
at getPath (/node_modules/.vite/deps/chunk-Y63HJXGX.js:48937:44)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at drawShape (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47726:23)
at drawShape (/node_modules/.vite/deps/chunk-Y63HJXGX.js:48000:11)
at draw (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49436:10)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46678:12)
at drawChildren (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46697:13)
at draw (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47723:10)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46678:12)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49005:11)
at draw (/node_modules/.vite/deps/chunk-CYBRUBDT.js:41:20)
at render/< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4230:31)
at execute (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4377:16)
at render (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4230:12)
image is undefined
The problem occurred here:
at desiredSize (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49385:9)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47384:23)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49455:11)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at updateLayout (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47268:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at requestLayoutUpdate (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47251:12)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at computedSize (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47241:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at getWidth (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47069:17)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5319:19)
at getter/< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5494:86)
at getter (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5494:55)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5319:19)
at getPath (/node_modules/.vite/deps/chunk-Y63HJXGX.js:48937:44)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at drawShape (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47726:23)
at drawShape (/node_modules/.vite/deps/chunk-Y63HJXGX.js:48000:11)
at draw (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49436:10)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46678:12)
at drawChildren (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46697:13)
at draw (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47723:10)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46678:12)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49005:11)
at draw (/node_modules/.vite/deps/chunk-CYBRUBDT.js:41:20)
at render/< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4230:31)
at execute (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4377:16)
at render (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4230:12)
size is undefined
The problem occurred here:
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47385:49)
at applyFlex (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49455:11)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at updateLayout (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47268:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at requestLayoutUpdate (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47251:12)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at computedSize (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47241:10)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at getWidth (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47069:17)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5319:19)
at getter/< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5494:86)
at getter (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5494:55)
at get (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5296:28)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5319:19)
at getPath (/node_modules/.vite/deps/chunk-Y63HJXGX.js:48937:44)
at invoke (/node_modules/.vite/deps/chunk-BRNMUPSA.js:5543:26)
at drawShape (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47726:23)
at drawShape (/node_modules/.vite/deps/chunk-Y63HJXGX.js:48000:11)
at draw (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49436:10)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46678:12)
at drawChildren (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46697:13)
at draw (/node_modules/.vite/deps/chunk-Y63HJXGX.js:47723:10)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:46678:12)
at render (/node_modules/.vite/deps/chunk-Y63HJXGX.js:49005:11)
at draw (/node_modules/.vite/deps/chunk-CYBRUBDT.js:41:20)
at render/< (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4230:31)
at execute (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4377:16)
at render (/node_modules/.vite/deps/chunk-BRNMUPSA.js:4230:12)

@levirs565
Copy link
Contributor Author

@benniel Can you rerun example on latest commit? Before rerun reinstall all npm packages (npm install) dan rebuild all packages (npx lerna run build).

@levirs565
Copy link
Contributor Author

Does this branch support changing the color of some parts of the latex? Let's say highlight some parts of the equation for example.

You can use \textcolor for coloring LaTex part. However, animating LaTex part color currently is not supported.

I will create new Pull Request for animating LaTex color.

@levirs565
Copy link
Contributor Author

@aarthificial Can you review this PR?

@zyansheep
Copy link

Would it be possible to do a write-in animation with this PR like in manim? (i.e. sequentially drawing the path for each symbol?)

@julien-blanchon
Copy link

Would it be possible to do a write-in animation with this PR like in manim? (i.e. sequentially drawing the path for each symbol?)

I would love to see that too !!

@Yourself1011
Copy link

Any update on this? I'd really like to see it in the library.

@mxcop
Copy link

mxcop commented May 8, 2024

+1 I would also love to see this in Motion Canvas :)

@Omixxx
Copy link

Omixxx commented Jun 18, 2024

this is a big feature! @aarthificial what can we do to speed up the merge?

@Quantodeluz
Copy link

Could you update this to 3.16.0?

@Quantodeluz
Copy link

I'm getting an error when i try to split this into SubTex:
normal: '\\Delta y'
image
error: '{{\\Delta}}{{y}}'
image

@aarthificial aarthificial merged commit 92a5659 into motion-canvas:main Aug 13, 2024
@aarthificial
Copy link
Contributor

I'm really sorry it took me so long.
Thanks so much for all the work!

@aarthificial
Copy link
Contributor

@Quantodeluz Try using the array syntax and wrap the y in a single curly bracket pair:

['\\Delta', '{y}']

We join the parts with no spaces so {{\\Delta}}{{y}} ends up being \Deltay instead of \Delta y causing the invalid behavior.
With an array you still won't get any spaces but it will be parsed as\Delta{y} which should be correct LaTeX.

Astavie pushed a commit to Astavie/motion-canvas that referenced this pull request Aug 14, 2024
blubbers122 pushed a commit to blubbers122/motion-canvas that referenced this pull request May 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support LaTex Tweening

10 participants