Changeset 39dab6b in Klonkt for src/assets/js
- Timestamp:
- 08/12/2026 09:43:20 PM (3 months ago)
- Children:
- 5e0fea7
- Parents:
- 2086ea2
- Location:
- src/assets/js
- Files:
-
- 1 added
- 2 edited
-
ward-sky.js (modified) (3 diffs)
-
ward-theme.js (added)
-
ward.js (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/js/ward-sky.js
r2086ea2 r39dab6b 99 99 100 100 /** Eén canvas met alle avatars naast elkaar, zodat tekenen één drawImage is. */ 101 async function buildAtlas(faces ) {101 async function buildAtlas(faces, accent) { 102 102 const size = FACE * 2; // retina-scherp 103 103 const cols = Math.max(1, Math.ceil(Math.sqrt(faces.length || 1))); … … 120 120 g.save(); 121 121 g.beginPath(); g.arc(x + size / 2, y + size / 2, size / 2, 0, Math.PI * 2); g.clip(); 122 g.fillStyle = '#5a32e6'; g.fillRect(x, y, size, size);122 g.fillStyle = accent || '#5a32e6'; g.fillRect(x, y, size, size); 123 123 g.fillStyle = '#fff'; 124 124 g.font = `600 ${size * 0.45}px system-ui, sans-serif`; … … 176 176 this.faces = faces; 177 177 this.spots = orbitPlacement(faces.map((f) => f.ageMs)); 178 this.atlas = await buildAtlas(faces );178 this.atlas = await buildAtlas(faces, this._accent()); 179 179 this._resize(); 180 } 181 182 /** De themakleur uit de CSS-variabele, voor de placeholder-schijfjes. */ 183 _accent() { 184 return getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#5a32e6'; 185 } 186 187 /** Het thema veranderde: de letters-op-schijf opnieuw in het nieuwe accent. */ 188 async reskin() { 189 if (this.faces.length) this.atlas = await buildAtlas(this.faces, this._accent()); 180 190 } 181 191 -
src/assets/js/ward.js
r2086ea2 r39dab6b 8 8 */ 9 9 import { SkyRenderer } from '/ward/sky.js'; 10 import { PRESETS, loadColor, saveColor, applyColor } from '/ward/theme.js'; 10 11 11 12 const state = JSON.parse(document.getElementById('ward-state').textContent); 13 14 // De opgeslagen themakleur meteen toepassen, voor het eerste frame. 15 applyColor(loadColor()); 12 16 const $ = (id) => document.getElementById(id); 13 17 … … 421 425 } catch { /* zonder hemel blijft het scherm gewoon werken */ } 422 426 })(); 427 428 // De hemel skint zijn placeholder-schijfjes bij als de themakleur wisselt. 429 window.addEventListener('ward-accent', () => sky.reskin()); 423 430 } 424 431 … … 515 522 } 516 523 517 /** De controle kost per guardian een remote fetch, dus hij komt ná het tekenen. */ 524 /** 525 * De themakiezer (SkyPalette): acht presets, gekozen kleur kleurt alles. 526 * Een rij swatches in een dialoog; de keuze staat meteen en blijft bewaard. 527 */ 528 function wireTheme() { 529 const dlg = document.getElementById('theme-dialog'); 530 const row = document.getElementById('theme-swatches'); 531 const current = loadColor(); 532 row.replaceChildren(); 533 PRESETS.forEach((rgb) => { 534 const b = el('button', 'swatch'); 535 b.type = 'button'; 536 b.style.background = '#' + rgb.toString(16).padStart(6, '0'); 537 b.setAttribute('aria-label', 'kleur ' + rgb.toString(16)); 538 if (rgb === current) b.classList.add('chosen'); 539 b.addEventListener('click', () => { 540 saveColor(rgb); 541 row.querySelectorAll('.swatch').forEach((s) => s.classList.remove('chosen')); 542 b.classList.add('chosen'); 543 // De hemel tekent de placeholder-schijfjes in het accent; even opnieuw. 544 window.dispatchEvent(new CustomEvent('ward-accent')); 545 }); 546 row.append(b); 547 }); 548 document.getElementById('theme-open').addEventListener('click', () => dlg.showModal()); 549 document.getElementById('theme-close').addEventListener('click', () => dlg.close()); 550 } 551 552 /** 553 * De mini-speler: audio blijft doorspelen terwijl je scrolt of van stand 554 * wisselt. 555 * 556 * Een feed-kaart rendert een gewone <audio>, maar de feed wordt bij elke 557 * verversing opnieuw getekend en dan sterft dat element -- de muziek stopt 558 * midden in een nummer. Daarom is er ÉÉN blijvende speler buiten de feed; een 559 * audiotegel geeft alleen zijn bron door en pauzeert zichzelf. Zo overleeft 560 * het geluid een herteken en een wissel naar de hemel, precies als in de app. 561 */ 562 function wireMiniPlayer() { 563 const bar = document.getElementById('mini-player'); 564 const audio = document.getElementById('mini-audio'); 565 const title = document.getElementById('mini-title'); 566 const toggle = document.getElementById('mini-toggle'); 567 568 // Vangen in de CAPTURE-fase: zodra een feed-audio wil spelen, neemt de 569 // gedeelde speler het over. Delegatie op document, want de kaarten komen en 570 // gaan. 571 document.addEventListener('play', (e) => { 572 const t = e.target; 573 if (!(t instanceof HTMLAudioElement) || t === audio) return; 574 e.preventDefault(); 575 t.pause(); 576 const card = t.closest('.post'); 577 title.textContent = card?.querySelector('.name')?.textContent || 'Audio'; 578 if (audio.src !== new URL(t.currentSrc || t.src, location.href).href) { 579 audio.src = t.currentSrc || t.src; 580 } 581 audio.play().catch(() => {}); 582 bar.hidden = false; 583 }, true); 584 585 toggle.addEventListener('click', () => { audio.paused ? audio.play() : audio.pause(); }); 586 audio.addEventListener('play', () => { toggle.textContent = '⏸'; }); 587 audio.addEventListener('pause', () => { toggle.textContent = '▶'; }); 588 audio.addEventListener('ended', () => { bar.hidden = true; }); 589 document.getElementById('mini-close').addEventListener('click', () => { audio.pause(); bar.hidden = true; }); 590 } 591 592 /** De controle kost per guardian een remote fetch, dus hij komt ná het tekenen. *//** De controle kost per guardian een remote fetch, dus hij komt ná het tekenen. */ 518 593 async function loadChecks() { 519 594 if (!state.guardians.length) return; … … 542 617 wireSky(); 543 618 wireComposer(); 619 wireTheme(); 620 wireMiniPlayer(); 544 621 loadFeed(); 545 622 renderOffers();
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)