michaelpeskov/components/VideoShowcase.tsx

142 lines
4.1 KiB
TypeScript

'use client'
import { useEffect, useRef } from 'react'
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
import Image from 'next/image'
if (typeof window !== 'undefined') {
gsap.registerPlugin(ScrollTrigger)
}
export default function VideoShowcase() {
const containerRef = useRef<HTMLDivElement>(null)
const videoRef = useRef<HTMLDivElement>(null)
const overlayRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const container = containerRef.current
const video = videoRef.current
const overlay = overlayRef.current
if (!container || !video || !overlay) return
// Check for reduced motion
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches
const ctx = gsap.context(() => {
if (prefersReducedMotion) {
// Simple fade for reduced motion
gsap.from(video, {
opacity: 0,
scale: 0.9,
duration: 1,
scrollTrigger: {
trigger: container,
start: 'top 60%',
toggleActions: 'play none none reverse'
}
})
} else {
// Video scale animation on scroll
gsap.fromTo(video,
{
scale: 0.8,
borderRadius: '2rem'
},
{
scale: 1,
borderRadius: '1rem',
duration: 1,
ease: 'power2.out',
scrollTrigger: {
trigger: container,
start: 'top 70%',
end: 'center center',
scrub: 1
}
}
)
// Parallax effect on video
gsap.to(video, {
yPercent: -20,
ease: 'none',
scrollTrigger: {
trigger: container,
start: 'top bottom',
end: 'bottom top',
scrub: true
}
})
// Overlay fade out on scroll
gsap.to(overlay, {
opacity: 0,
duration: 0.5,
scrollTrigger: {
trigger: container,
start: 'top 50%',
toggleActions: 'play none none reverse'
}
})
}
}, container)
return () => ctx.revert()
}, [])
const handlePlayClick = () => {
// Replace with actual video player logic
console.log('Play video')
}
return (
<section ref={containerRef} className="py-32 px-6 bg-slate-800">
<div className="max-w-6xl mx-auto">
<div className="text-center mb-16">
<h2 className="text-5xl md:text-6xl font-bold text-white mb-6">
See the Magic
</h2>
<p className="text-xl text-gray-300 max-w-2xl mx-auto">
Watch Michael Peskov in action as he creates moments of wonder and amazement.
</p>
</div>
<div
ref={videoRef}
className="relative aspect-video rounded-2xl overflow-hidden shadow-2xl"
style={{ willChange: 'transform' }}
>
<Image
src="/michael-peskov-magier-taschendieb-453624.jpeg"
alt="Michael Peskov showreel preview"
fill
className="object-cover"
priority
/>
{/* Video overlay */}
<div
ref={overlayRef}
className="absolute inset-0 bg-black/40 flex items-center justify-center cursor-pointer group"
onClick={handlePlayClick}
>
<div className="w-20 h-20 bg-white/90 rounded-full flex items-center justify-center group-hover:bg-white group-hover:scale-110 transition-all duration-300">
<div className="w-0 h-0 border-l-[16px] border-l-slate-800 border-y-[12px] border-y-transparent ml-1" />
</div>
</div>
{/* Gradient overlay */}
<div className="absolute inset-0 bg-gradient-to-t from-slate-900/50 to-transparent pointer-events-none" />
</div>
{/* Video info */}
<div className="text-center mt-8">
<p className="text-gray-400">
As seen on <span className="text-white font-semibold">SAT.1, WDR, ZDF & Amazon Prime Video</span>
</p>
</div>
</div>
</section>
)
}