remotion-dev / anime-example

Example of using Anime.JS in Remotion

Home Page:https://anime-example.vercel.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

direction: 'alternate' with seek?

siderakis opened this issue · comments

direction: 'alternate', doesn't seem to work using animation.seek(((frame / fps) * 1000) % animation.duration); as in the example.

Also, something like this could be helpful to reduce boilerplate

const useAnime = (animeProps: anime.AnimeParams) => {
	const frame = useCurrentFrame();
	const {fps} = useVideoConfig();
	const ref = useRef<HTMLDivElement>(null);
	const [animation, setAnimation] = useState<anime.AnimeInstance | null>(null);

	// Using a useEffect, because anime needs to get the ref once it's mounted
	useEffect(() => {
		setAnimation(() => {
			return anime({
				targets: ref.current,
				autoplay: false,
				...animeProps,
			});
		});
		// Only run once
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, []);
	useEffect(() => {
		if (!animation) {
			return;
		}
		animation.seek(((frame / fps) * 1000) % animation.duration);
	}, [animation, fps, frame]);

	return {ref, animation};
};

replacing the seek' and '% animation.duration line with tick fixed the issue

	`animation.seek(((frame / fps) * 1000) % animation.duration);`

becomes

	`animation.tick((frame / fps) * 1000);`

.tick() does unfortunately not make the time idempotent 🥲

When dragging the timeline cursor in reverse, it will not reverse the animation, so I think .seek() is better.
direction: "alternate" indeed does not seem to work (I don't know why), but you can alternate the Remotion frame

import {interpolate} from "remotion";


const animationDurationInFrames = Math.floow(animation.duration / 1000 / fps)
const alternatedFrame = interpolate(
	frame % animationDurationInFrames,
	[0, animationDurationInFrames, animationDurationInFrames * 2],
	[0, animationdurationInFrames, 0]
)

and then pass alternatedFrame instead of frame to seek.