This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / pages / profile-fx / willow.sh.js
1.9 kB 60 lines
1const styles = ` 2 [data-punchcard] { 3 .bg-green-100, .dark\\:bg-green-100 { --w-size: 20%; } 4 .bg-green-200, .dark\\:bg-green-200 { --w-size: 30%; } 5 .bg-green-300, .dark\\:bg-green-300 { --w-size: 40%; } 6 .bg-green-400, .dark\\:bg-green-400 { --w-size: 50%; } 7 .bg-green-500, .dark\\:bg-green-500 { --w-size: 60%; } 8 .bg-green-600, .dark\\:bg-green-600 { --w-size: 70%; } 9 .bg-green-700, .dark\\:bg-green-700 { --w-size: 80%; } 10 .bg-green-800, .dark\\:bg-green-800 { --w-size: 90%; } 11 .bg-green-900, .dark\\:bg-green-900 { --w-size: 100%; } 12 13 > div > div { 14 background-color: color-mix(in srgb, #2160ec var(--w-size), light-dark(white, black)); 15 transition: transform 0.2s ease-out; 16 will-change: transform; 17 } 18 } 19`; 20 21const sheet = new CSSStyleSheet(); 22sheet.replaceSync(styles); 23document.adoptedStyleSheets = [sheet]; 24 25const RADIUS = 60; 26const MAX_SCALE = 2.5; 27 28const grid = document.querySelector('[data-punchcard]'); 29const dots = Array.from(grid.querySelectorAll(':scope > div > div')); 30 31function mousemove(e) { 32 for (const dot of dots) { 33 const rect = dot.getBoundingClientRect(); 34 const cx = rect.left + rect.width / 2; 35 const cy = rect.top + rect.height / 2; 36 const dist = Math.hypot(e.clientX - cx, e.clientY - cy); 37 const scale = 1 + (MAX_SCALE - 1) * Math.max(0, 1 - dist / RADIUS); 38 dot.style.transform = `scale(${scale})`; 39 } 40} 41 42function mouseleave() { 43 for (const dot of dots) { 44 dot.style.transform = 'scale(1)'; 45 } 46} 47 48function toggleAnimation(enabled) { 49 if (enabled) { 50 grid.addEventListener('mousemove', mousemove); 51 grid.addEventListener('mouseleave', mouseleave); 52 } else { 53 grid.removeEventListener('mousemove', mousemove); 54 grid.removeEventListener('mouseleave', mouseleave); 55 } 56} 57 58const motion = window.matchMedia('(prefers-reduced-motion: reduce)'); 59toggleAnimation(!motion.matches); 60motion.addEventListener('change', (event) => toggleAnimation(!event.matches));