chain-react.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. (function(){
  2. window.HPX = window.HPX || {};
  3. window.HPX['chain-react'] = function(el){
  4. const U = window.HPX._u;
  5. const k = U.canvas(el), ctx = k.ctx;
  6. const ac = U.accent(el,'#7c5cff'), ac2 = U.accent2(el,'#22d3ee');
  7. const N = 8;
  8. const stop = U.loop((t) => {
  9. ctx.clearRect(0,0,k.w,k.h);
  10. const cy = k.h/2;
  11. const pad = 60;
  12. const dx = (k.w - pad*2)/(N-1);
  13. const period = 2.4;
  14. const phase = (t % period) / period; // 0..1
  15. for (let i=0;i<N;i++){
  16. const x = pad + i*dx;
  17. const my = i/(N-1);
  18. const d = Math.abs(phase - my);
  19. const pulse = Math.max(0, 1 - d*6);
  20. const r = 18 + pulse*18;
  21. // glow
  22. const g = ctx.createRadialGradient(x,cy,0,x,cy,r*2);
  23. g.addColorStop(0, `rgba(124,92,255,${0.4*pulse})`);
  24. g.addColorStop(1, 'rgba(0,0,0,0)');
  25. ctx.fillStyle = g;
  26. ctx.fillRect(x-r*2, cy-r*2, r*4, r*4);
  27. // circle
  28. ctx.fillStyle = pulse>0.1 ? ac2 : ac;
  29. ctx.beginPath(); ctx.arc(x,cy,r,0,Math.PI*2); ctx.fill();
  30. ctx.strokeStyle='rgba(255,255,255,0.4)'; ctx.lineWidth=2;
  31. ctx.stroke();
  32. // connectors
  33. if (i<N-1){
  34. ctx.strokeStyle='rgba(200,200,230,0.3)'; ctx.lineWidth=2;
  35. ctx.beginPath(); ctx.moveTo(x+r,cy); ctx.lineTo(x+dx-r,cy); ctx.stroke();
  36. }
  37. }
  38. });
  39. return { stop(){ stop(); k.destroy(); } };
  40. };
  41. })();