Files
ayrisapart/components/CallToAction.tsx
2026-04-19 17:23:31 +03:00

125 lines
4.5 KiB
TypeScript

'use client'
import { motion, useScroll, useTransform } from 'framer-motion'
import { useRef } from 'react'
import Link from 'next/link'
import Image from 'next/image'
const images = [
{
src: "https://images.unsplash.com/photo-1541410950669-e771b058097d?q=80&w=2070&auto=format&fit=crop",
w: 305, h: 225,
tx: -550, ty: -350,
rotate: -2
},
{
src: "https://images.unsplash.com/photo-1590490360182-c33d57733427?q=80&w=2100&auto=format&fit=crop",
w: 325, h: 425,
tx: 550, ty: -350,
rotate: 1
},
{
src: "https://images.unsplash.com/photo-1566665797739-1674de7a421a?q=80&w=2070&auto=format&fit=crop",
w: 385, h: 485,
tx: -550, ty: 350,
rotate: -1
},
{
src: "https://images.unsplash.com/photo-1571896349842-33c89424de2d?q=80&w=2073&auto=format&fit=crop",
w: 425, h: 365,
tx: 550, ty: 350,
rotate: 2
},
]
export default function CallToAction({ lang, dict }: { lang: string, dict: any }) {
const containerRef = useRef<HTMLDivElement>(null)
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start start", "end end"]
})
// Title: Stays hit at 0 until scroll hits 30%, then reveals quickly.
const entranceOpacity = useTransform(scrollYProgress, [0.85, 0.95, 1], [0, 1, 1])
// Description / Button: Reveals even later, ensuring images are already scattering
const textOpacity = useTransform(scrollYProgress, [0.5, 0.7, 1], [0, 1, 1])
const textY = useTransform(scrollYProgress, [0.5, 0.7, 1], [50, 0, 0])
// Scatter range: Images start dispersing at 20% to clear the path for text
const scatterRange = [0.2, 0.95]
const scatterTLX = useTransform(scrollYProgress, scatterRange, [0, -580])
const scatterTLY = useTransform(scrollYProgress, scatterRange, [0, -380])
const scatterTRX = useTransform(scrollYProgress, scatterRange, [0, 580])
const scatterTRY = useTransform(scrollYProgress, scatterRange, [0, -380])
const scatterBLX = useTransform(scrollYProgress, scatterRange, [0, -580])
const scatterBLY = useTransform(scrollYProgress, scatterRange, [0, 380])
const scatterBRX = useTransform(scrollYProgress, scatterRange, [0, 580])
const scatterBRY = useTransform(scrollYProgress, scatterRange, [0, 380])
const scatterX = [scatterTLX, scatterTRX, scatterBLX, scatterBRX]
const scatterY = [scatterTLY, scatterTRY, scatterBLY, scatterBRY]
return (
<section ref={containerRef} className="relative h-[300vh] bg-white z-60">
<div className="sticky top-0 h-screen flex items-center justify-center overflow-hidden">
{/* SCATTERING POLAROIDS */}
{images.map((img, i) => (
<motion.div
key={i}
style={{
x: scatterX[i],
y: scatterY[i],
rotate: img.rotate
}}
className="absolute z-10"
>
<div className={`relative shadow-2xl p-4 bg-white`} style={{ width: img.w, height: img.h }}>
<div className="relative w-full h-full">
<Image src={img.src} alt="Ayris" fill className="object-cover" />
</div>
</div>
</motion.div>
))}
{/* REVEALING CENTER CONTENT */}
<motion.div
style={{ opacity: entranceOpacity }}
className="relative z-20 text-center max-w-4xl px-8"
>
<div className="space-y-12">
<h2 className="text-6xl md:text-[110px] font-serif text-[#1A1A1A] leading-[1] tracking-tight uppercase">
{dict.hero.title}
</h2>
<div className="flex flex-col items-center space-y-12">
<motion.p
style={{ opacity: textOpacity, y: textY }}
className="text-[#1A1A1A]/60 text-xl md:text-2xl font-medium max-w-xl italic leading-relaxed"
>
&quot;{dict.footer.desc}&quot;
</motion.p>
<motion.div style={{ opacity: textOpacity, y: textY }}>
<Link
href={`/${lang}/reservation`}
className="inline-flex items-center space-x-3 group text-[14px] font-bold tracking-[0.4em] text-[#1A1A1A] uppercase border-b-2 border-[#1A1A1A] pb-3"
>
<span className="text-[#C88C4B] text-xl transform group-hover:translate-x-1.5 transition-transform duration-500"></span>
<span>{dict.footer.book}</span>
</Link>
</motion.div>
</div>
</div>
</motion.div>
</div>
</section>
)
}