Skip to content

Instantly share code, notes, and snippets.

@ksassnowski
Last active February 25, 2023 06:15
Show Gist options
  • Save ksassnowski/dc3e1e8dee5c1d40c40b1d4a5baa175b to your computer and use it in GitHub Desktop.
Save ksassnowski/dc3e1e8dee5c1d40c40b1d4a5baa175b to your computer and use it in GitHub Desktop.
`group` function
import { Node } from '@motion-canvas/2d/lib/components';
import { all } from '@motion-canvas/core/lib/flow';
import {
InterpolationFunction,
TimingFunction,
deepLerp,
easeInOutCubic,
} from '@motion-canvas/core/lib/tweening';
import { Vector2 } from '@motion-canvas/core/lib/types';
type NodeType<A extends any[]> = A extends (infer U)[] ? U : never;
export class NodeGroup<T extends Node[]> {
public constructor(private nodes: T) {
for (const node of nodes) {
for (const { key } of node) {
if (!this.hasOwnProperty(key)) {
// *points at butterfly* Is this reflection?
(this as any)[key] = this.createHandler(key);
}
}
}
}
public save() {
for (const node of this.nodes) {
node.save();
}
}
public restore(
duration: number,
timingFunction: TimingFunction = easeInOutCubic,
) {
return all(
...this.nodes.map((node) => node.restore(duration, timingFunction)),
);
}
public *shift(
value: Vector2,
duration: number,
timingFunction: TimingFunction = easeInOutCubic,
) {
yield* all(
...this.nodes.map((node) =>
node.position(node.position().add(value), duration, timingFunction),
),
);
}
private createHandler(key: string) {
return (
value: any,
duration: number,
timingFunction: TimingFunction = easeInOutCubic,
interpolationFunction: InterpolationFunction<any> = deepLerp,
) => {
return all(
...this.nodes.map((node) =>
(node as any)[key](
value,
duration,
timingFunction,
interpolationFunction,
),
),
);
};
}
}
export function group<T extends Node[]>(...nodes: T) {
return new ChainableGroup(nodes) as NodeGroup<T> & NodeType<T>;
}
@ksassnowski
Copy link
Author

Note that this is a really rough proof of concept with a bunch of hardcoded exceptions (like save and restore). This would obviously need more work, should this ever make it's way into the core (not saying that it will). But it works well enough for my own projects, so I thought it would be useful to share.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment