Maak animaties met GSAP, Three.js, Lenis, CSS. Gebruik bij "animatie", "animate", "beweging", "scroll effect", "3D".
Maak een animatie voor gameshopenter.com. Specificatie: $ARGUMENTS
@media (prefers-reduced-motion: reduce)next/dynamic met ssr: falsectx.revert(), Three.js dispose(), Lenis destroy()gsap/ScrollTrigger niet hele gsap'use client';
import { useRef, useEffect } from 'react';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
export function AnimatedSection() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const ctx = gsap.context(() => {
gsap.from('.item', {
y: 50, opacity: 0, duration: 0.6, stagger: 0.1, ease: 'power2.out',
scrollTrigger: { trigger: ref.current, start: 'top 80%' }
});
}, ref);
return () => ctx.revert(); // CLEANUP — altijd
}, []);
return <div ref={ref}>...</div>;
}
'use client';
import dynamic from 'next/dynamic';
const Scene3D = dynamic(() => import('@/components/Scene3D'), {
ssr: false,
loading: () => <div className="h-64 bg-surface-base animate-pulse rounded-xl" />
});
// In Scene3D.tsx:
// - useFrame voor animatie loop
// - Canvas met dpr={[1, 2]} voor retina
// - ALTIJD dispose geometry + materials in cleanup
// - OrbitControls alleen als interactie nodig
'use client';
import { useEffect } from 'react';
import Lenis from 'lenis';
export function SmoothScroll({ children }: { children: React.ReactNode }) {
useEffect(() => {
const lenis = new Lenis({ duration: 1.2, smoothWheel: true, touchMultiplier: 1.5 });
function raf(time: number) { lenis.raf(time); requestAnimationFrame(raf); }
const id = requestAnimationFrame(raf);
return () => { cancelAnimationFrame(id); lenis.destroy(); };
}, []);
return <>{children}</>;
}
@keyframes fadeUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-enter { animation: fadeUp 0.5s ease-out forwards; }
@media (prefers-reduced-motion: reduce) {
.animate-enter { animation: none; opacity: 1; transform: none; }
}
// Canvas → video via MediaRecorder
const canvas = document.createElement('canvas');
const stream = canvas.captureStream(30); // 30fps
const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
const chunks: Blob[] = [];
recorder.ondataavailable = (e) => chunks.push(e.data);
recorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
// Download of toon
};
recorder.start();
// Animeer op canvas...
setTimeout(() => recorder.stop(), 5000); // 5s video
NODE_OPTIONS="--max-old-space-size=8192" npm run build