feat: blok-a video, zigzag hotspots, logo intro, updated positions

This commit is contained in:
2026-07-30 22:09:41 +03:00
parent 4e758a4d90
commit caab28573d
3 changed files with 118 additions and 53 deletions
+56 -21
View File
@@ -11,7 +11,7 @@ import {
} from 'framer-motion'
import UnitRevealOverlay from './UnitRevealOverlay'
const TOTAL_FRAMES = 299
const TOTAL_FRAMES = 298
const FRAME_PATH = (n: number) =>
`/frames/ezgif-frame-${String(n).padStart(3, '0')}.jpg`
@@ -51,6 +51,10 @@ export default function CloudRevealSection() {
const progressScaleX = useTransform(scrollYProgress, [0, 1], [0, 1])
// --- Text phase opacities ---
// Logo: 08% görünür, sonra kaybolur
const logoOpacity = useTransform(scrollYProgress, [0, 0.02, 0.08, 0.14], [0, 1, 1, 0])
const logoScale = useTransform(scrollYProgress, [0, 0.02], [0.92, 1])
// Phase 1: 015% → tagline (sol alt)
const phase1Opacity = useTransform(scrollYProgress, [0, 0.05, 0.12, 0.18], [0, 1, 1, 0])
const phase1Y = useTransform(scrollYProgress, [0, 0.05], [20, 0])
@@ -174,6 +178,18 @@ export default function CloudRevealSection() {
</div>
)}
{/* LOGO — merkez, ilk frame'de görünür, scroll ile kaybolur */}
<motion.div
style={{ opacity: logoOpacity, scale: logoScale }}
className="absolute inset-0 flex flex-col items-center justify-center z-10 pointer-events-none"
>
<p className="text-white text-5xl md:text-7xl font-serif font-light tracking-[0.25em] drop-shadow-2xl">
VESTA
</p>
<div className="mt-3 w-16 h-px bg-white/40" />
<p className="text-white/60 text-xs tracking-[0.5em] uppercase mt-3">Muğla</p>
</motion.div>
{/* PHASE 1 — Sol alt: Ana tagline */}
<motion.div
style={{ opacity: phase1Opacity, y: phase1Y }}
@@ -261,16 +277,41 @@ const HOTSPOTS: {
id: string
label: string
sub: string
x: number // dot pozisyonu — ekranın % yatay
y: number // dot pozisyonu — ekranın % dikey
dir: 'left' | 'right' // kartın hangi tarafa uzayacağı
x: number
y: number
dir: 'left' | 'right'
}[] = [
{ id: 'blok-a', label: '2+1 Daire', sub: 'Blok A · 89 m²', x: 34, y: 22, dir: 'left' },
{ id: 'blok-b', label: '2+1 Daire', sub: 'Blok B · 84 m²', x: 70, y: 19, dir: 'right' },
{ id: 'blok-c', label: '1+1 Daire', sub: 'Blok C · 60 m²', x: 50, y: 55, dir: 'right' },
{ id: 'blok-d', label: '1+1 Daire', sub: 'Blok D · 47 m²', x: 20, y: 65, dir: 'left' },
{ id: 'blok-a', label: '2+1 Tip A', sub: 'Blok A · 83.35 m²', x: 52, y: 28, dir: 'left' },
{ id: 'blok-b', label: '2+1 Tip B', sub: 'Blok B · 84 m²', x: 93, y: 30, dir: 'left' },
{ id: 'blok-c', label: '1+1', sub: 'Blok C · 60 m²', x: 11, y: 42, dir: 'right' },
]
// Zigzag SVG çizgisi — dot'tan karta uzanır
function ZigzagLine({ dir, delay }: { dir: 'left' | 'right'; delay: number }) {
// sağa giden: sol→sağ, sola giden: sağ→sol
const w = 72
const h = 24
// zigzag path: 3 segment, orta kısmı yukarı/aşağı kayar
const path = dir === 'right'
? `M0,${h/2} L${w*0.3},${h/2} L${w*0.45},4 L${w*0.6},${h-4} L${w*0.75},${h/2} L${w},${h/2}`
: `M${w},${h/2} L${w*0.7},${h/2} L${w*0.55},4 L${w*0.4},${h-4} L${w*0.25},${h/2} L0,${h/2}`
return (
<svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} fill="none" className="shrink-0">
<motion.path
d={path}
stroke="rgba(255,255,255,0.65)"
strokeWidth="1.2"
strokeLinecap="round"
strokeLinejoin="round"
initial={{ pathLength: 0, opacity: 0 }}
animate={{ pathLength: 1, opacity: 1 }}
transition={{ delay, duration: 0.7, ease: 'easeInOut' }}
/>
</svg>
)
}
function UnitHotspots({
scrollYProgress,
onSelect,
@@ -291,7 +332,6 @@ function UnitHotspots({
className="absolute"
style={{ left: `${spot.x}%`, top: `${spot.y}%` }}
>
{/* Dot + çizgi + kart — yatay flex */}
<div className={`flex items-center gap-0 ${spot.dir === 'left' ? 'flex-row-reverse' : 'flex-row'}`}>
{/* Pulsing dot */}
@@ -300,24 +340,19 @@ function UnitHotspots({
<span className="relative inline-flex rounded-full h-3 w-3 bg-white" />
</span>
{/* Animated çizgi */}
<motion.div
className="h-px bg-white/60 shrink-0"
initial={{ width: 0 }}
animate={{ width: 48 }}
transition={{ delay: i * 0.2 + 0.1, duration: 0.4, ease: 'easeOut' }}
/>
{/* Zigzag çizgi */}
<ZigzagLine dir={spot.dir} delay={i * 0.25 + 0.1} />
{/* Ok ucu */}
<motion.div
initial={{ opacity: 0, x: spot.dir === 'right' ? -4 : 4 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: i * 0.2 + 0.4, duration: 0.2 }}
className="shrink-0 text-white/60"
transition={{ delay: i * 0.25 + 0.7, duration: 0.2 }}
className="shrink-0"
>
{spot.dir === 'right'
? <svg width="6" height="8" viewBox="0 0 6 8" fill="none"><path d="M1 1l4 3-4 3" stroke="white" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/></svg>
: <svg width="6" height="8" viewBox="0 0 6 8" fill="none"><path d="M5 1L1 4l4 3" stroke="white" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round"/></svg>
? <svg width="6" height="10" viewBox="0 0 6 10" fill="none"><path d="M1 1l4 4-4 4" stroke="white" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>
: <svg width="6" height="10" viewBox="0 0 6 10" fill="none"><path d="M5 1L1 5l4 4" stroke="white" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>
}
</motion.div>
@@ -325,7 +360,7 @@ function UnitHotspots({
<motion.button
initial={{ opacity: 0, x: spot.dir === 'right' ? -8 : 8 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: i * 0.2 + 0.45, duration: 0.3, ease: 'easeOut' }}
transition={{ delay: i * 0.25 + 0.75, duration: 0.3, ease: 'easeOut' }}
className="pointer-events-auto bg-black/60 backdrop-blur-md border border-white/20 rounded-lg px-3 py-2 text-left hover:bg-black/80 hover:border-white/40 transition-all duration-200 active:scale-95 cursor-pointer"
onClick={() => onSelect({ id: spot.id, label: spot.label, sub: spot.sub })}
>