1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8" />
5<meta name="viewport" content="width=device-width,initial-scale=1" />
6<title>Love Words Heart</title>
7<style>
8 :root{
9 --bg:#000;
10 --warm:#fff7cf;
11 --glow:#ffe36a;
12 --red:#ff1200;
13 }
14 html,body{
15 margin:0;
16 height:100%;
17 background:var(--bg);
18 overflow:hidden;
19 font-family: Arial, Helvetica, sans-serif;
20 }
21 .stage{
22 position:relative;
23 width:100vw;
24 height:100vh;
25 background:#000;
26 }
27 .heart{
28 position:absolute;
29 left:50%;
30 top:50%;
31 width:min(62vmin,640px);
32 height:min(62vmin,640px);
33 transform:translate(-50%,-50%) rotate(-8deg);
34 filter: saturate(1.05);
35 }
36 .word{
37 position:absolute;
38 left:50%;
39 top:50%;
40 transform-origin:center center;
41 color:var(--warm);
42 font-weight:700;
43 letter-spacing:.02em;
44 white-space:nowrap;
45 user-select:none;
46 pointer-events:none;
47 text-shadow:
48 0 0 1px rgba(255,255,255,.95),
49 0 0 6px rgba(255,232,120,.85),
50 0 0 12px rgba(255,220,90,.55),
51 0 0 22px rgba(255,220,90,.22);
52 opacity:.98;
53 animation: drift 8s linear infinite;
54 }
55 .word.dim{
56 opacity:.82;
57 font-weight:500;
58 }
59 .word.red{
60 color:var(--red);
61 font-size:clamp(28px,4.8vmin,58px)!important;
62 font-weight:800;
63 letter-spacing:.01em;
64 text-shadow:
65 0 0 2px rgba(255,80,80,.95),
66 0 0 10px rgba(255,0,0,.9),
67 0 0 22px rgba(255,0,0,.55),
68 0 0 34px rgba(255,0,0,.25);
69 z-index:3;
70 }
71
72 @keyframes drift{
73 0% { filter:brightness(1); }
74 50% { filter:brightness(1.08); }
75 100% { filter:brightness(1); }
76 }
77</style>
78</head>
79<body>
80<div class="stage">
81 <div class="heart" id="heart"></div>
82</div>
83
84<script>
85const words = [
86 "Love","Amour","Liebe","Amore","Amor","Любовь","الحب","愛","Cinta","Αγάπη",
87 "Liefde","Dashuri","Каханне","Ljubav","Laska","Mahabbah","אהבה","Szerelem",
88 "Mīlestība","Сүйүү","Aşk","Tình yêu","uhando","sopp","محبت","ярату","Mahal",
89 "soymek","karlek","jecel","munay","kærlighet","KHAIR","aroha","tia","сүйүү",
90 "Сүю","خۆشەویستن","ljubav","sooyayäa","Upendo","mborayhu","kærleiki","amor",
91 "ama","karout","Любав","Sevgi","munana","Renmen","Láska","Dragoste","عشق"
92];
93
94const heart = document.getElementById('heart');
95const N = 72; // dense but concise
96const scale = 12.8; // heart size
97const centerX = 0, centerY = 8;
98const cycle = 8; // seconds, matches smooth loop in frames
99
100function heartPoint(t){
101 // classic heart curve
102 const x = 16 * Math.pow(Math.sin(t), 3);
103 const y = -(13*Math.cos(t) - 5*Math.cos(2*t) - 2*Math.cos(3*t) - Math.cos(4*t));
104 return {x, y};
105}
106
107function tangentAngle(t){
108 const dt = 0.0001;
109 const p1 = heartPoint(t - dt);
110 const p2 = heartPoint(t + dt);
111 return Math.atan2((p2.y - p1.y), (p2.x - p1.x)) * 180 / Math.PI;
112}
113
114const nodes = [];
115for(let i=0;i<N;i++){
116 const el = document.createElement('div');
117 const isRed = i === 0;
118 el.className = 'word' + (isRed ? ' red' : (Math.random() < .28 ? ' dim' : ''));
119 el.textContent = isRed ? 'Love' : words[(i % (words.length - 1)) + 1];
120 const size = isRed ? 42 : 14 + Math.random()*8;
121 el.style.fontSize = size + 'px';
122 el.style.animationDelay = (-Math.random()*cycle).toFixed(2) + 's';
123 heart.appendChild(el);
124 nodes.push({el, offset:i/N});
125}
126
127function render(time){
128 const t0 = (time/1000 % cycle) / cycle; // 0..1
129 const w = heart.clientWidth;
130 const h = heart.clientHeight;
131
132 for(const item of nodes){
133 const u = (t0 + item.offset) % 1;
134 const t = u * Math.PI * 2;
135
136 const p = heartPoint(t);
137 const ang = tangentAngle(t);
138
139 const x = w/2 + (p.x * scale) + centerX;
140 const y = h/2 + (p.y * scale) + centerY;
141
142 // slight jitter/overlap like the source frames
143 const jitterX = Math.sin((u*18 + t0*8) * Math.PI*2) * 2.2;
144 const jitterY = Math.cos((u*13 - t0*7) * Math.PI*2) * 1.8;
145
146 // words mostly upright, but gently biased by path direction
147 let rot = ang * 0.18;
148 if (rot > 18) rot = 18;
149 if (rot < -18) rot = -18;
150
151 // red "Love" rides the path and tilts more noticeably
152 if(item.el.classList.contains('red')){
153 rot = ang * 0.42;
154 item.el.style.zIndex = 5;
155 }
156
157 item.el.style.left = x + jitterX + 'px';
158 item.el.style.top = y + jitterY + 'px';
159 item.el.style.transform = `translate(-50%,-50%) rotate(${rot}deg)`;
160 }
161 requestAnimationFrame(render);
162}
163requestAnimationFrame(render);
164</script>
165</body>
166</html>