| import React from 'react'; | |
| import { AbsoluteFill } from 'remotion'; | |
| import { C, DISPLAY, MONO } from '../theme'; | |
| import { backOut, easeOut, glow, lerp, prog } from '../lib/anim'; | |
| const polar = (cx: number, cy: number, r: number, deg: number) => ({ | |
| x: cx + r * Math.cos((deg * Math.PI) / 180), | |
| y: cy + r * Math.sin((deg * Math.PI) / 180), | |
| }); | |
| const arc = (cx: number, cy: number, r: number, a0: number, a1: number) => { | |
| const s = polar(cx, cy, r, a0); | |
| const e = polar(cx, cy, r, a1); | |
| const large = a1 - a0 > 180 ? 1 : 0; | |
| return `M ${s.x} ${s.y} A ${r} ${r} 0 ${large} 1 ${e.x} ${e.y}`; | |
| }; | |
| const Equation: React.FC<{ f: number }> = ({ f }) => { | |
| const parts = ['7641', '−', '1467', '=', '6174']; | |
| return ( | |
| <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'center', gap: 18, fontFamily: MONO, fontWeight: 700 }}> | |
| {parts.map((p, i) => { | |
| const o = easeOut(prog(f, 46 + i * 11, 58 + i * 11)); | |
| return ( | |
| <span | |
| key={i} | |
| style={{ | |
| fontSize: p === '6174' ? 62 : 52, | |
| color: p === '6174' ? C.gold : p === '−' || p === '=' ? C.dim : C.ink, | |
| letterSpacing: '0.05em', | |
| opacity: o, | |
| transform: `translateY(${(1 - o) * 14}px)`, | |
| display: 'inline-block', | |
| textShadow: p === '6174' ? glow(C.gold, 22, 0.6) : undefined, | |
| }} | |
| > | |
| {p} | |
| </span> | |
| ); | |
| })} | |
| </div> | |
| ); | |
| }; | |
| export const Loop: React.FC<{ f: number; dur: number }> = ({ f }) => { | |
| const cta = easeOut(prog(f, 132, 158)); | |
| const topOut = 1 - prog(f, 126, 148); | |
| const draw = easeOut(prog(f, 8, 46)); | |
| const R = 246; | |
| const d = arc(540, 560, R, -150, 150); | |
| const len = (Math.PI * R * 300) / 180; | |
| return ( | |
| <AbsoluteFill> | |
| <div style={{ position: 'absolute', top: 190, left: 90, right: 90, display: 'flex', justifyContent: 'space-between', alignItems: 'center', opacity: topOut }}> | |
| <div style={{ fontFamily: MONO, fontSize: 22, letterSpacing: '0.4em', color: C.cyan }}>THE TRAP</div> | |
| <div style={{ fontFamily: MONO, fontSize: 20, letterSpacing: '0.2em', color: C.dim }}>04 / 04</div> | |
| </div> | |
| <div style={{ position: 'absolute', top: 234, left: 90, width: 900, height: 1, background: 'linear-gradient(90deg, rgba(89,227,255,0.5), rgba(89,227,255,0))', opacity: topOut }} /> | |
| {/* the loop */} | |
| <div style={{ opacity: topOut }}> | |
| <AbsoluteFill style={{ alignItems: 'center' }}> | |
| <div | |
| style={{ | |
| position: 'absolute', | |
| top: 360, | |
| fontFamily: DISPLAY, | |
| fontWeight: 700, | |
| fontSize: 196, | |
| letterSpacing: '0.04em', | |
| color: C.gold, | |
| textShadow: glow(C.gold, 46, 0.7), | |
| transform: `scale(${1 + 0.02 * Math.sin(f * 0.14)})`, | |
| }} | |
| > | |
| 6174 | |
| </div> | |
| </AbsoluteFill> | |
| <svg width={1080} height={1920} viewBox="0 0 1080 1920" style={{ position: 'absolute' }}> | |
| <defs> | |
| <marker id="arrow" markerWidth="10" markerHeight="10" refX="7" refY="3" orient="auto" markerUnits="strokeWidth"> | |
| <path d="M 0 0 L 8 3 L 0 6 z" fill={C.gold} /> | |
| </marker> | |
| </defs> | |
| <path | |
| d={d} | |
| fill="none" | |
| stroke={C.gold} | |
| strokeOpacity={0.22} | |
| strokeWidth={2} | |
| strokeDasharray="2 10" | |
| transform={`rotate(${f * 0.3} 540 560)`} | |
| /> | |
| <path | |
| d={d} | |
| fill="none" | |
| stroke={C.gold} | |
| strokeWidth={3.4} | |
| strokeLinecap="round" | |
| markerEnd="url(#arrow)" | |
| strokeDasharray={`${len} ${len}`} | |
| strokeDashoffset={len * (1 - draw)} | |
| transform={`rotate(${f * 0.3} 540 560)`} | |
| opacity={0.9} | |
| /> | |
| {[0, 1, 2].map((i) => { | |
| const a = f * 1.1 + i * 120 - 150; | |
| const pt = polar(540, 560, R, a); | |
| return <circle key={i} cx={pt.x} cy={pt.y} r={3.4} fill={i === 0 ? '#FFF3C9' : C.gold} opacity={0.8} />; | |
| })} | |
| </svg> | |
| <div style={{ position: 'absolute', top: 862, left: 0, right: 0 }}> | |
| <Equation f={f} /> | |
| </div> | |
| <div | |
| style={{ | |
| position: 'absolute', | |
| top: 992, | |
| left: 0, | |
| right: 0, | |
| textAlign: 'center', | |
| fontFamily: DISPLAY, | |
| fontWeight: 700, | |
| fontSize: 46, | |
| letterSpacing: '0.55em', | |
| color: C.gold, | |
| opacity: easeOut(prog(f, 100, 124)), | |
| textShadow: glow(C.gold, 18, 0.4), | |
| }} | |
| > | |
| FOREVER | |
| </div> | |
| </div> | |
| {/* CTA */} | |
| <AbsoluteFill style={{ opacity: cta, transform: `translateY(${(1 - cta) * 40}px)` }}> | |
| <div | |
| style={{ | |
| position: 'absolute', | |
| top: 430, | |
| left: 0, | |
| right: 0, | |
| textAlign: 'center', | |
| fontFamily: DISPLAY, | |
| fontWeight: 700, | |
| fontSize: 300, | |
| color: C.gold, | |
| opacity: 0.05, | |
| letterSpacing: '-0.02em', | |
| }} | |
| > | |
| 6174 | |
| </div> | |
| <div style={{ position: 'absolute', top: 540, left: 60, right: 60, textAlign: 'center' }}> | |
| <div style={{ fontFamily: MONO, fontSize: 22, letterSpacing: '0.4em', color: C.cyan, marginBottom: 30 }}>YOUR TURN</div> | |
| <div style={{ fontFamily: DISPLAY, fontWeight: 700, fontSize: 92, lineHeight: 1.04, letterSpacing: '-0.035em', color: C.ink }}> | |
| HOW MANY STEPS | |
| </div> | |
| <div style={{ fontFamily: DISPLAY, fontWeight: 700, fontSize: 92, lineHeight: 1.04, letterSpacing: '-0.035em', color: C.ink, marginBottom: 54 }}> | |
| DID <span style={{ color: C.gold }}>YOURS</span> TAKE? | |
| </div> | |
| <div | |
| style={{ | |
| display: 'inline-flex', | |
| alignItems: 'center', | |
| gap: 14, | |
| background: C.gold, | |
| color: '#120C02', | |
| fontFamily: DISPLAY, | |
| fontWeight: 700, | |
| fontSize: 40, | |
| letterSpacing: '0.12em', | |
| padding: '20px 42px', | |
| borderRadius: 999, | |
| transform: `scale(${1 + 0.025 * Math.sin(f * 0.18)})`, | |
| boxShadow: `0 0 54px rgba(255,201,74,0.4)`, | |
| }} | |
| > | |
| COMMENT IT | |
| <span style={{ fontSize: 34 }}>↓</span> | |
| </div> | |
| </div> | |
| <div | |
| style={{ | |
| position: 'absolute', | |
| top: 1120, | |
| left: 0, | |
| right: 0, | |
| textAlign: 'center', | |
| fontFamily: MONO, | |
| fontSize: 20, | |
| letterSpacing: '0.32em', | |
| color: C.dim, | |
| opacity: backOut(prog(f, 200, 222)), | |
| }} | |
| > | |
| KAPREKAR'S CONSTANT · 6174 | |
| </div> | |
| </AbsoluteFill> | |
| {f >= 316 ? <AbsoluteFill style={{ background: '#000', opacity: prog(f, 316, 330) }} /> : null} | |
| </AbsoluteFill> | |
| ); | |
| }; | |
Xet Storage Details
- Size:
- 7.21 kB
- Xet hash:
- 307d8d0ea5d0698f32b6f3b97a05846de2e9f62539a7938e66c9cf6c5f3a2517
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.