返回 html-ppt-skill
word-cascade.js
根目录 / assets / animations / fx / word-cascade.js
1 (function(){
2 window.HPX = window.HPX || {};
3 window.HPX['word-cascade'] = function(el){
4 const U = window.HPX._u;
5 const k = U.canvas(el), ctx = k.ctx;
6 const pal = U.palette(el);
7 const WORDS = ['AI','知识','Graph','Claude','LLM','Agent','Vector','RAG','Token','神经',
8 'Prompt','Chain','Skill','Code','Cloud','GPU','Flow','推理','Data','Model'];
9 let items = [];
10 let last = -1;
11 let piles = {}; // column -> stack height
12 const stop = U.loop((t) => {
13 ctx.clearRect(0,0,k.w,k.h);
14 if (t - last > 0.18){
15 last = t;
16 const w = WORDS[(Math.random()*WORDS.length)|0];
17 items.push({
18 text: w, x: U.rand(40, k.w-40), y: -20,
19 vy: 0, c: pal[(Math.random()*pal.length)|0],
20 size: U.rand(16,26), landed: false
21 });
22 }
23 ctx.textAlign='center'; ctx.textBaseline='middle';
24 for (const it of items){
25 if (!it.landed){
26 it.vy += 0.4;
27 it.y += it.vy;
28 const col = Math.round(it.x/60);
29 const floor = k.h - (piles[col]||0) - it.size*0.6;
30 if (it.y >= floor){
31 it.y = floor; it.landed = true;
32 piles[col] = (piles[col]||0) + it.size*1.1;
33 if ((piles[col]||0) > k.h*0.8) piles[col] = 0; // reset if too high
34 }
35 }
36 ctx.fillStyle = it.c;
37 ctx.font = `700 ${it.size}px system-ui,sans-serif`;
38 ctx.fillText(it.text, it.x, it.y);
39 }
40 // prune old landed
41 if (items.length > 120){
42 items = items.filter(i => !i.landed).concat(items.filter(i=>i.landed).slice(-60));
43 }
44 });
45 return { stop(){ stop(); k.destroy(); } };
46 };
47 })();
48
48 lines JAVASCRIPT