Skip to main content

ยท One min read
Jacob

New features ๐ŸŽ‰โ€‹

  • levirs565's avatarThe Latex node now supports tweening:#800
    Press play to preview the animation
    import ...

    export default makeScene2D(function* (view) {
    const tex = createRef<Latex>();
    view.add(<Latex ref={tex} tex="{{y=}}{{a}}{{x^2}}" fill="white" />);

    yield* waitFor(0.2);
    yield* tex().tex('{{y=}}{{a}}{{x^2}} + {{bx}}', 1);
    yield* waitFor(0.2);
    yield* tex().tex(
    '{{y=}}{{\\left(}}{{a}}{{x^2}} + {{bx}}{{\\over 1}}{{\\right)}}',
    1,
    );
    yield* waitFor(0.2);
    yield* tex().tex('{{y=}}{{a}}{{x^2}}', 1);
    });

  • squigglesdev's avatar?render and ?present url parameters can be used to immediately start rendering or presenting when opening the editor.#631

Fixed bugs ๐Ÿ›โ€‹

  • aarthificial's avatarTxt nodes properly support tweening emojis.#1085
  • aarthificial's avatarFix stack overflow caused by restoring a Code node#1084
  • aarthificial's avatarPrevent invalid cache sizes.#1083
  • aarthificial's avatarFix line tweening.#1075
  • aarthificial's avatarFix text alignment.#1061
Check out the Update Guide for information on how to update your existing projects.

ยท 2 min read
Jacob

New features ๐ŸŽ‰โ€‹

  • ksassnowski's avatarA brand-new Camera node with helper methods for zooming and focusing on elements:#1019
    Press play to preview the animation
    import ...

    export default makeScene2D(function* (view) {
    const camera = createRef<Camera>();
    const rect = createRef<Rect>();
    const circle = createRef<Circle>();

    const scene = (
    <Node>
    <Grid stroke={'#fff1'} lineWidth={1} size="100%" spacing={25}>
    <Rect ref={rect} fill={'#e6a700'} size={50} position={[50, -25]} />
    <Circle ref={circle} fill={'#e13238'} size={50} position={[-50, 25]} />
    </Grid>
    </Node>
    );

    view.add(
    <>
    <Camera.Stage
    scene={scene}
    x={-200}
    width={300}
    height={200}
    stroke={'#242424'}
    lineWidth={4}
    />
    <Camera.Stage
    cameraRef={camera}
    scene={scene}
    x={200}
    width={300}
    height={200}
    stroke={'#242424'}
    lineWidth={4}
    />
    </>,
    );

    yield* all(
    camera().centerOn(rect(), 3),
    camera().rotation(180, 3),
    camera().zoom(1.8, 3),
    );
    yield* camera().centerOn(circle(), 2);
    yield* camera().reset(1);
    });

  • aarthificial's avatarNew effects can be used to react to changes in signals:#1043
    import {makeScene2D} from '@motion-canvas/2d';
    import {createEffect, createSignal} from '@motion-canvas/core';

    export default makeScene2D(function* () {
    const signal = createSignal(0);

    createEffect(() => {
    console.log('Signal changed: ', signal());
    });

    yield* signal(1, 2);
    });
  • mancopp's avatarAll vector operations can now be used with vector signals for a more concise code:#1030
    // Before
    yield* node().position(node().position().add([200, 100]), 2);

    // Now
    yield* node().position.add([200, 100], 2);
  • aarthificial's avatarPolygon.vertex() and Polygon.vertexCompletion() can be used to retrieve information about the vertices of a polygon.#1045
  • mancopp's avatarNew example for the Code node.#1023

Fixed bugs ๐Ÿ›โ€‹

  • aarthificial's avatarHandle invalid values for time events.#1044
  • aarthificial's avatarFix the destination uv in shaders.#1026
  • Josephine19001's avatarFix the type of the layout gap property.#1039
  • aarthificial's avatarFix Code size calculation.#1025
Check out the Update Guide for information on how to update your existing projects.

ยท 3 min read
Jacob

New features ๐ŸŽ‰โ€‹

  • aarthificial's avatarA brand-new Code node with dedicated code signals, customizable syntax highlighting, and more expressive animation system (Including automatic diff-based transitions).#946
    Press play to preview the animation
    import ...

    export default makeScene2D(function* (view) {
    const code = createRef<Code>();

    view.add(
    <Code
    ref={code}
    fontSize={28}
    fontFamily={'JetBrains Mono, monospace'}
    offsetX={-1}
    x={-400}
    code={'const number = 7;'}
    />,
    );

    yield* waitFor(0.6);
    yield* all(
    code().code.replace(code().findFirstRange('number'), 'variable', 0.6),
    code().code.prepend(0.6)`function example() {\n `,
    code().code.append(0.6)`\n}`,
    );

    yield* waitFor(0.6);
    yield* code().selection(code().findFirstRange('variable'), 0.6);

    yield* waitFor(0.6);
    yield* all(
    code().code('const number = 7;', 0.6),
    code().selection(DEFAULT, 0.6),
    );
    });

  • aarthificial's avatarNew withDefaults helper function lets you quickly extend nodes with your own defaults.#982
    import {Txt, withDefaults} from '@motion-canvas/2d';

    export const MyTxt = withDefaults(Txt, {
    fill: 'rgba(255, 255, 255, 0.6)',
    fontFamily: 'JetBrains Mono',
    fontSize: 28,
    });
  • aarthificial's avatarWhen using loop, the iteration count can be omitted to create an infinite loop:#952
    // These two are equivalent:
    yield* loop(() => { /* animation */ });
    yield* loop(Infinity, () => { /* animation */ });
  • aarthificial's avatarNew spawn function lets you run animations in the background, from any place, without needing to yield them.#951
  • aarthificial's avatarPolygon now extendsCurve giving it access to all curve-related properties like startArrow and radius.#961
  • jmaen's avatarColor fields in the editor now come with a visual color picker.#962
  • aarthificial's avatarNew Vector2 methods: #985
  • aarthificial's avatarNew cardinalPoint method lets you mapOrigins and Directions to their corresponding cardinal points of the node.#988
  • aarthificial's avatarNew waitTransition lets you animate transitions using nodes.#983
  • aarthificial's avatarWhen passed to OpenGL, Matrix2D is now converted to a 3x3 square matrix (as opposed to a 3x2 matrix)#984
  • aarthificial's avatarThe view's cachePadding is now respected when calculating the cache size of individual nodes.#986
  • Niikelion's avatarPresentation Mode now supports PowerPoint shortcuts (Page Up, Page Down, etc.)#993
  • nvborisenko's avatarParts of the motion-canvas-player shadow root are now exposed using part and can be customized with CSS.#956
  • aarthificial's avatarFiddles on this website now play automatically when scrolled into view.#1001

Fixed bugs ๐Ÿ›โ€‹

  • CactusPuppy's avatarAccount for italic fonts in cache.#968
  • rogerpinho's avatarFix typo in the Quickstart Guide.#974
  • aarthificial's avatarProperly handle offset when retrieving the absolute position of a node.#987
  • aarthificial's avatarFix the spline warning for reactive points.#981
Check out the Update Guide for information on how to update your existing projects.

ยท One min read
Jacob

New features ๐ŸŽ‰โ€‹

  • aarthificial's avatarShaders let you create custom visual effects using WebGL.#929#920
    Press play to preview the animation
    import ...

    // Original shader created by ufffd
    // https://www.shadertoy.com/view/lcfXD8
    const Shader = `\
    #version 300 es
    precision highp float;

    in vec2 screenUV;
    out vec4 outColor;

    uniform float time;
    uniform vec2 resolution;

    #define g(p) dot(sin(p),cos(p.zxy)) //

    float m(vec3 p){
    return (1.0 + 0.2 * sin(p.y * 6e2))
    * g(0.8 * g(8.0 * p) + 10.0 * p)
    * (1.0 + sin(time + length(p.xy) / 0.1))
    + 0.3 * sin(time * 0.15 + p.z * 5.0 + p.y)
    * (2.0 + g((sin(time * 0.2 + p.z * 3.0) * 350.0 + 250.0) * p));
    }

    void main() {
    vec3 r = normalize(vec3((screenUV - 0.5) * resolution, resolution.y));
    vec3 p;
    vec3 f;
    float e = 50.0;
    float d;
    float i;

    for (p.z = time / 4.0; i++ < 90.0 && e > 0.05; e = m(p += r * d)) {
    d += 0.02 * e;
    }

    f.x = 0.06 + 0.06 * sin(p.z);
    outColor = vec4(2.0 * m(p) - m(p - f) - m(p - f.yxy))
    * smoothstep(0.75, 1.05, 1.0 / d);
    }
    `;

    export default makeScene2D(function* (view) {
    view.add(<Rect shaders={Shader} size={view.size} />);

    yield* waitFor(10);
    });

  • aarthificial's avatarThe node inspector can be toggled on and off.#921
  • jmaen's avatarNumber inputs can be edited by dragging left and right.#917
Check out the Update Guide for information on how to update your existing projects.

ยท One min read
Jacob

New features ๐ŸŽ‰โ€‹

  • aarthificial's avatarA new scene graph tab lets you peek into the contents of the scene.#909#914Scene Graph Tab
  • jmaen's avatarHolding Shift + Ctrl lets you drag over the timeline to select the range. B and N can be used to snap the beginning and end of the range to the playhead.#907
  • aarthificial's avatarEditor plugins can now register custom inspectors that display information on the right side of the editor.#913

Fixed bugs ๐Ÿ›โ€‹

  • aarthificial's avatarThe mouse is tracked correctly when dragging time events.#912
Check out the Update Guide for information on how to update your existing projects.

ยท 4 min read
Jacob

New features ๐ŸŽ‰โ€‹

  • aarthificial's avatarThe points of a Line can now be tweened.#853
    Press play to preview the animation
    import ...

    export default makeScene2D(function* (view) {
    const line = createRef<Line>();
    view.add(
    <Line
    ref={line}
    points={[
    [-150, 70],
    [150, 70],
    [0, -70],
    ]}
    stroke={'lightseagreen'}
    lineWidth={8}
    radius={20}
    closed
    />,
    );

    yield* line()
    .points(
    [
    [-150, 0],
    [0, 100],
    [150, 0],
    [150, -70],
    [-150, -70],
    ],
    2,
    )
    .back(2);
    });

  • aarthificial's avatarTxt nodes can now be nested inside each other.#861
    Press play to preview the animation
    import {Txt, makeScene2D} from '@motion-canvas/2d';

    export default makeScene2D(function* (view) {
    view.fill('#141414');
    view.add(
    <Txt fill={'white'} fontSize={32} width={720} textWrap>
    Whereas recognition of the inherent dignity and of the{' '}
    <Txt.i>equal</Txt.i> and inalienable rights of all members of
    the human family is the foundation of <Txt.b>freedom</Txt.b>,
    justice and <Txt fill="#25C281">peace</Txt> in the world.
    </Txt>,
    );
    });
  • aarthificial's avatarNew querying helpers let you find nodes in the scene.#852
  • rmhartog's avatarTransitions can now control which scene is drawn on top.#832
  • rmhartog's avatarA new Video.playbackRate property lets you control the speed of a video.#831
  • aarthificial's avatarThis version introduces the concept of experimental features. Marked with , these features are meant mostly for testing and gathering feedback. Find out more about them in this dedicated section.#876
  • aarthificial's avatarNew Editor Plugins allow you to extend the editor's interface. With them, you can define custom tabs in the sidebar and draw overlays on top of the animation preview or the presenter.#884
  • aarthificial's avatarThe timeline can now be scrubbed by holding down LMB and dragging left or right.#862
    For complex animation, dragging to the left may lag a bit since the entire generator must be re-run each time.
  • jmaen's avatarHovering over the audio icon now reveals a volume slider that lets you adjust the volume.#872
  • Vija02's avatarThe ArrowUp and ArrowDown keys allow you to control the volume.#856
  • aarthificial's avatarThe animation range is no longer editable by default. Just like with the audio track, hold SHIFT before dragging to edit it.#862
  • Vaibhavi-Sita's avatarWhen looping is disabled, the editor will seek back to the start of the animation and stop there instead of pausing at the end.#823
  • CactusPuppy's avatarVector2 now includes static properties representing each type of origin.#855
  • aarthificial's avatarapplyState can now be used to tween to the new state and not just immediately apply it.#859
  • aarthificial's avatarThe spawner has been deprecated in favor of the children property.#858
    view.add(
    // before
    <Node spawner={() => range(count()).map(() => <Node />)} />,
    );

    view.add(
    // after
    <Node>{() => range(count()).map(() => <Node />)}</Node>,
    );
  • rmhartog's avatarProject configuration now supports glob patterns#834
    import motionCanvas from '@motion-canvas/vite-plugin';
    import {defineConfig} from 'vite';

    export default defineConfig({
    plugins: [
    motionCanvas({
    project: './src/projects/*.ts',
    }),
    ],
    });
  • rmhartog's avatarOpacity is clamped between 0 and 1.#835
  • aarthificial's avatarErrors that occur when loading an image are now properly reported in the editor.#847

Fixed bugs ๐Ÿ›โ€‹

  • aarthificial's avatarAdded a missing middle property to the LayoutProps interface.#891
  • aarthificial's avatarCardinal points now correctly account for the Node's offset.#883
  • aarthificial's avatar"Go to source" actions should work again.#895
  • shaikan's avatarUnusual characters in file names are now properly handled.#821
  • SleeklyCoding's avatarWhen opening the output directory, it will be automatically created if it doesn't exist.#787
  • aarthificial's avatarFixed line jitter under certain conditions.#863
  • rmhartog's avatarCorrectly calculate bounding boxes of Txt nodes.#836
  • aarthificial's avatarFixed tweening cardinal points.#829
Check out the Update Guide for information on how to update your existing projects.

ยท 2 min read
Jacob

New features ๐ŸŽ‰โ€‹

  • aarthificial's avatarNodes can now be skewed:#803
    Press play to preview the animation
    import ...

    export default makeScene2D(function* (view) {
    const ref = createRef<Img>();
    yield view.add(
    <Img
    ref={ref}
    skew={[-24, -12]}
    src="https://images.unsplash.com/photo-1696931073577-5638a6891e1e"
    width={240}
    radius={20}
    />,
    );

    yield* ref().skew([24, 12], 1, easeOutElastic).back(1);
    });

  • levirs565's avatarNew SVG node lets you display and tween SVG graphics.#763
    (The amount of supported SVG features is still limited, the node was designed mainly to support LaTeX tweening in the future update)
  • SleeklyCoding's avatarA new lineCount property lets you retrieve the number of lines in a code block.#802
  • aarthificial's avatarslideTransition now allows for diagonal movement defined using Origin.#801
  • aarthificial's avatarAny external changes made to the audio file are now picked up and automatically reflected in the editor.#793
  • aarthificial's avatarWhen rendering, an estimated remaining time is displayed in the bottom right.#795
  • me-nkr's avatarNew playback controls for seeking to the very beginning and end of the animation.#814
  • alsongarbuja's avatarWhen dragging time events, a line indicator is displayed to help precisely align the event with the audio.#808
  • aarthificial's avatarHolding MMB allows you to drag the timeline left and right.#794
  • aarthificial's avatarA new error warns about a missing image source.#817

Fixed bugs ๐Ÿ›โ€‹

  • aarthificial's avatarSpecific event names, such as constructor no longer cause the editor to crash.#819
  • aarthificial's avatarAdded missing Curve properties to Circle.#805
  • aarthificial's avatarArrow heads now always point in the correct direction.#792
Check out the Update Guide for information on how to update your existing projects.

ยท 2 min read
Jacob

New features ๐ŸŽ‰โ€‹

  • aarthificial's avatarThe Rect and Circle nodes now extend Curvegiving them access to all its properties and methods:#771#759
    Press play to preview the animation
    import ...

    export default makeScene2D(function* (view) {
    const ref = createRef<Circle>();
    view.add(
    <Circle
    ref={ref}
    size={160}
    stroke={'lightseagreen'}
    lineWidth={8}
    endAngle={270}
    endArrow
    />,
    );

    yield* all(ref().start(1, 1), ref().rotation(180, 1, easeInCubic));
    ref().start(0).end(0);
    yield* all(ref().end(1, 1), ref().rotation(360, 1, easeOutCubic));
    });

  • levirs565's avatarNew SVG Path component:#700
    Press play to preview the animation
    import ...

    export default makeScene2D(function* (view) {
    view.add(
    <Path
    scale={8}
    position={-96}
    fill={'lightseagreen'}
    data={
    'M4 6.47L5.76 10H20v8H4V6.47M22 4h-4l2 4h-3l-2-4h-2l2 4h-3l-2-4H8l2 4H7L5 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V4z'
    }
    />,
    );
    });

  • ksassnowski's avatarNew start and end signals for animating the Grid node.#761
  • aarthificial's avatarNew helper methods for managing references: #775
  • aarthificial's avatarImg and Video nodes with radius are automatically clipped.#773
  • ksassnowski's avatarBBox transformation methods accept PossibleMatrix2D.#770
  • aarthificial's avatarNew middle cardinal point.#758
  • ksassnowski's avatarNew rotate and polarLerp methods for Vector2.#756
  • Logon27's avatarThe editor now lets you copy the mouse coordinates by pressing P#737
  • aarthificial's avatarrestore() can be called without duration to restore the state immediately.#736

Fixed bugs ๐Ÿ›โ€‹

  • aarthificial's avatarFixed the "Last updated by" information on documentation pages.#776
  • Caesarovich's avatarTimeline correctly displays small time ranges.#739
  • aarthificial's avatarIt's no longer possible to spawn multiple color pickers.#747
Check out the Update Guide for information on how to update your existing projects.

ยท 2 min read
Jacob

New features ๐ŸŽ‰โ€‹

  • aarthificial's avatarAll entities are now imported from the main entry point of each package. The only exception is the CodeBlock node which still requires the full import path:
    import {all, createRef} from '@motion-canvas/core';
    import {makeScene2D, Circle} from '@motion-canvas/2d';
    // the only exception:
    import {CodeBlock, insert} from '@motion-canvas/2d/lib/components/CodeBlock';
    Importing from subdirectories will continue to work until version 4.#721#710
  • aarthificial's avatarNew presenter and renderer plugin hooks.
    You can learn how to create your own plugins in the new Authoring Plugins guide.#723
  • ajs1998's avatarNew Random.gauss() method lets you generate random numbers using a gaussian (normal) distribution.#709
  • aarthificial's avatarUpdated sidebar design lets you hide the timeline and collapse panels by dragging.#692
  • aarthificial's avatarApplication-wide settings let you configure the project defaults and change the editor appearance. You can edit them in the settings tab on the left.#697
  • aarthificial's avatarYou can use a new eye dropper tool to pick colors from the canvas
    (see browser compatibility)#691
  • aarthificial's avatarError stack traces now include function names.#693
  • aarthificial's avatarOverall improvements to the Fiddle editor.#706#712#713

Fixed bugs ๐Ÿ›โ€‹

  • aarthificial's avatarFix package.json entry.#720
  • aarthificial's avatarFix collapsable sections.#698
  • rtkid-nt's avatarUse project variables when rendering/presenting.#690
Check out the Update Guide for information on how to update your existing projects.

ยท 2 min read
Jacob

New features ๐ŸŽ‰โ€‹

  • aarthificial's avatarThe brand new Video (FFmpeg) exporter lets you render your animations directly to a video file. It's included by default (with the option to opt out) in all new projects created with npm init @motion-canvas. Check out the docs to learn how to install it in your existing projects.#673#660
  • aarthificial's avatarAn improved rendering button provides visual feedback about the rendering process.#662#681
  • aarthificial's avatarA new OUTPUT DIRECTORY button lets you reveal the current output directory in your file explorer. You can find it directly below the RENDER button.#663
  • aarthificial's avatarCollapsible panels are now animated.#671
  • aarthificial's avatarArray values, such as points of a Line, are now displayed in the inspector.#670
  • aarthificial's avatarThe create package now supports command-line arguments for providing answers without having to go through the interactive prompt:#668
    npm init @motion-canvas@latest -- --name Hello --path ./hello --language ts
  • aarthificial's avatarMeta fields can declare descriptions. When hovering over the field in the editor, the description will be displayed in a form of a tooltip.#664
  • aarthificial's avatarNew hooks let plugins extend the behavior of the player (The plugin documentation will be available soon).#679

Fixed bugs ๐Ÿ›โ€‹

  • aarthificial's avatarCorrectly support URLs to external images.#678
  • aarthificial's avatarRemove the yellow dependency pre-bundling warning.#676
  • aarthificial's avatarFix editing the audio offset by dragging the waveform.#674
  • aarthificial's avatarIgnore children with disabled layout.#669
  • aarthificial's avatarPrevent Color tree shaking.#666
Check out the Update Guide for information on how to update your existing projects.