fb
This commit is contained in:
124
components/CallToAction.tsx
Normal file
124
components/CallToAction.tsx
Normal file
@@ -0,0 +1,124 @@
|
||||
'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"
|
||||
>
|
||||
"{dict.footer.desc}"
|
||||
</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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user