返回 html-ppt-skill
animation-showcase.html
根目录 / templates / animation-showcase.html
1 <!DOCTYPE html>
2 <html lang="en" data-theme="aurora">
3 <head>
4 <meta charset="utf-8"><title>Animation + FX Showcase — html-ppt</title>
5 <link rel="stylesheet" href="../assets/fonts.css">
6 <link rel="stylesheet" href="../assets/base.css">
7 <link rel="stylesheet" id="theme-link" href="../assets/themes/aurora.css">
8 <link rel="stylesheet" href="../assets/animations/animations.css">
9 <style>
10 .fx-stage{
11 position:relative;
12 margin:20px auto 0;
13 width:min(900px, 92%);
14 height:380px;
15 border-radius:var(--radius-lg, 16px);
16 background:rgba(10,12,22,0.55);
17 border:1px solid var(--border,#2a2a3a);
18 box-shadow:var(--shadow-lg, 0 20px 60px rgba(0,0,0,.4));
19 overflow:hidden;
20 }
21 .fx-label{
22 position:absolute;top:14px;left:16px;z-index:5;
23 font-family:var(--font-mono, ui-monospace,Menlo,monospace);
24 font-size:11px;letter-spacing:.14em;color:var(--text-3,#a0a0b8);
25 text-transform:uppercase;
26 background:rgba(0,0,0,0.35);padding:4px 10px;border-radius:999px;
27 border:1px solid rgba(255,255,255,0.08);
28 }
29 .fx-replay{
30 position:absolute;top:12px;right:14px;z-index:5;
31 appearance:none;cursor:pointer;
32 padding:7px 14px;border-radius:999px;
33 background:linear-gradient(135deg, var(--accent,#7c5cff), var(--accent-2,#22d3ee));
34 color:#fff;font:600 12px system-ui,sans-serif;
35 border:0;letter-spacing:.05em;
36 box-shadow:0 4px 16px rgba(124,92,255,0.35);
37 }
38 .fx-replay:hover{ filter:brightness(1.1); transform:translateY(-1px); }
39 .fx-indicator{position:absolute;top:24px;right:40px;font-family:var(--font-mono);font-size:11px;color:var(--text-3);letter-spacing:.1em}
40 .anim-box{margin:24px auto 0;width:640px;height:240px;border-radius:var(--radius-lg);background:var(--grad-soft);display:flex;align-items:center;justify-content:center;font-size:44px;font-weight:800;color:var(--text-1);box-shadow:var(--shadow-lg);border:1px solid var(--border)}
41 </style>
42 </head>
43 <body>
44 <div class="deck"></div>
45
46 <script>
47 const FX = [
48 ['particle-burst', 'Particles explode from center, gravity + fade, re-bursts every ~2.5s.'],
49 ['confetti-cannon', 'Colored rotating rects arcing from both bottom corners.'],
50 ['firework', 'Rockets launch from the bottom and burst into colored sparks.'],
51 ['starfield', '3D perspective starfield — infinite flythrough.'],
52 ['matrix-rain', 'Classic green katakana + hex columns raining down.'],
53 ['knowledge-graph', 'Force-directed graph, 28 labeled nodes, live physics + springs.'],
54 ['neural-net', '4-6-6-3 feedforward net with pulses traveling along edges.'],
55 ['constellation', 'Drifting points connect when close — ambient background.'],
56 ['orbit-ring', '5 concentric rings with dots rotating at different speeds.'],
57 ['galaxy-swirl', 'Logarithmic spiral with ~800 particles.'],
58 ['word-cascade', 'Words fall from top and pile up at the bottom.'],
59 ['letter-explode', 'Letters fly in from random directions, loops.'],
60 ['chain-react', 'Row of 8 circles — a wave pulse dominoes across them.'],
61 ['magnetic-field', 'Particles follow sine curves leaving gradient trails.'],
62 ['data-stream', 'Rows of scrolling hex/binary text, cyberpunk feel.'],
63 ['gradient-blob', '4 drifting blurred radial gradients (additive blending).'],
64 ['sparkle-trail', 'Sparkles emit at your cursor (auto-wiggles if idle).'],
65 ['shockwave', 'Expanding rings emanating from center, looping.'],
66 ['typewriter-multi', 'Three lines typing concurrently with blinking block cursors.'],
67 ['counter-explosion', 'Number counts 0 → 2400, bursts particles, resets.']
68 ];
69
70 const CSS_ANIMS = [
71 ['fade-up','Translate from +32 px, fade.'],
72 ['fade-down','Translate from -32 px, fade.'],
73 ['fade-left','From left.'],
74 ['fade-right','From right.'],
75 ['rise-in','Rise + blur-off.'],
76 ['drop-in','Drop from above.'],
77 ['zoom-pop','Elastic scale pop.'],
78 ['blur-in','Blur clears.'],
79 ['glitch-in','Glitch jitter.'],
80 ['typewriter','Typewriter reveal.'],
81 ['neon-glow','Neon pulse.'],
82 ['shimmer-sweep','Sheen sweep.'],
83 ['gradient-flow','Gradient flow.'],
84 ['stagger-list','Staggered children.'],
85 ['counter-up','Number tick.'],
86 ['path-draw','SVG strokes draw.'],
87 ['parallax-tilt','3D hover tilt.'],
88 ['card-flip-3d','Y-axis flip.'],
89 ['cube-rotate-3d','Cube rotate.'],
90 ['page-turn-3d','Page turn.'],
91 ['perspective-zoom','Pull from -400 Z.'],
92 ['marquee-scroll','Infinite marquee.'],
93 ['kenburns','Ken Burns zoom.'],
94 ['confetti-burst','Pseudo confetti.'],
95 ['spotlight','Circular clip reveal.'],
96 ['morph-shape','SVG d morph.'],
97 ['ripple-reveal','Corner ripple.']
98 ];
99
100 const deck = document.querySelector('.deck');
101 const total = FX.length + CSS_ANIMS.length;
102
103 // Build FX slides (1..20)
104 FX.forEach((f, i) => {
105 const idx = i + 1;
106 const [name, desc] = f;
107 const sec = document.createElement('section');
108 sec.className = 'slide';
109 sec.setAttribute('data-title', 'fx / ' + name);
110
111 const extraAttrs = name === 'letter-explode'
112 ? 'data-fx-text-value="' + name.toUpperCase() + '"'
113 : name === 'counter-explosion'
114 ? 'data-fx-to="2400"'
115 : name === 'typewriter-multi'
116 ? 'data-fx-line1="> initializing knowledge graph..." data-fx-line2="> loading 28 concept nodes" data-fx-line3="> agent ready. awaiting prompt_"'
117 : '';
118
119 sec.innerHTML = `
120 <span class="fx-indicator">${idx}/${total}</span>
121 <p class="kicker">FX · canvas · ${String(idx).padStart(2,'0')}</p>
122 <h1 class="h1"><span class="gradient-text">${name}</span></h1>
123 <p class="lede">${desc}</p>
124 <div class="fx-stage">
125 <span class="fx-label">data-fx="${name}"</span>
126 <button class="fx-replay" type="button">Replay</button>
127 <div class="fx-host" style="position:absolute;inset:0;" data-fx="${name}" ${extraAttrs}></div>
128 </div>
129 <div class="deck-footer"><span class="dim2">Press → for next slide</span><span class="slide-number" data-current="${idx}" data-total="${total}"></span></div>
130 `;
131 deck.appendChild(sec);
132
133 // Wire Replay button
134 sec.querySelector('.fx-replay').addEventListener('click', () => {
135 const host = sec.querySelector('.fx-host');
136 const name2 = host.getAttribute('data-fx');
137 const attrs = {};
138 for (const a of host.attributes) attrs[a.name] = a.value;
139 const parent = host.parentNode;
140 // stop existing
141 if (window.__hpxActive && window.__hpxActive.has(host)){
142 try{ window.__hpxActive.get(host).stop(); }catch(e){}
143 window.__hpxActive.delete(host);
144 }
145 const fresh = document.createElement('div');
146 for (const k in attrs) fresh.setAttribute(k, attrs[k]);
147 fresh.style.cssText = host.style.cssText;
148 parent.replaceChild(fresh, host);
149 if (window.__hpxReinit) window.__hpxReinit(sec);
150 });
151 });
152
153 // Build CSS animation slides (legacy, kept for completeness)
154 CSS_ANIMS.forEach((a, i) => {
155 const idx = FX.length + i + 1;
156 const sec = document.createElement('section');
157 sec.className = 'slide';
158 sec.setAttribute('data-title', a[0]);
159 sec.innerHTML = `
160 <span class="fx-indicator">${idx}/${total}</span>
161 <p class="kicker">CSS anim · ${String(idx).padStart(2,'0')}</p>
162 <h1 class="h1"><span class="gradient-text">${a[0]}</span></h1>
163 <p class="lede">${a[1]}</p>
164 <div class="anim-box anim-${a[0]}" data-anim="${a[0]}" data-anim-target>${a[0]}</div>
165 <div class="deck-footer"><span class="dim2">Press A to cycle</span><span class="slide-number" data-current="${idx}" data-total="${total}"></span></div>
166 `;
167 deck.appendChild(sec);
168 });
169 </script>
170 <script src="../assets/runtime.js"></script>
171 <script src="../assets/animations/fx-runtime.js"></script>
172 </body></html>
173
173 lines HTML