Wall of People Groups: the level-of-detail hook reports the zoom it actually draws at

rega's L12 photo probe read host.__wallLod().cardPx as 0 after 46 wheel ticks: the field was set once when the cards were first laid out and never again, since the canvas renderer replaced the LOD component that used to update it. The canvas now records one card's on-screen width at every frame it draws (stats.cardPx, both the grid and the poster), and the hook returns that. The container's header comment no longer claims Font Awesome is loaded: the canvas draws its own icons, and d3 is pinned and kept off window.d3 (src/wallD3.js).
This commit is contained in:
Doxa Maps 2026-09-29 12:25:40 +00:00
parent ef83e0ab9b
commit 488d34836a
3 changed files with 7 additions and 3 deletions

View file

@ -110,7 +110,7 @@ export default {
},
mounted() {
// A test hook on the HOST element (not window): the level-of-detail state, as before.
try { const host = this.$el?.getRootNode?.()?.host; if (host) host.__wallLod = () => ({ ...this.lodState, stats: this._wc ? { ...this._wc.stats } : null }); } catch (_) { /* no host */ }
try { const host = this.$el?.getRootNode?.()?.host; if (host) host.__wallLod = () => ({ ...this.lodState, cardPx: this._wc ? this._wc.stats.cardPx : this.lodState.cardPx, stats: this._wc ? { ...this._wc.stats } : null }); } catch (_) { /* no host */ }
this.initializeCanvas();
this.fetchData();
// The canvas is not reactive: redraw when a prayer is added (heart + count) or the language changes.

View file

@ -59,7 +59,8 @@ export class WallCanvas {
this.images = new Map() // url → { img, ok, used } (img: the photo or its thumbnail)
// Counters for the performance probes (read through the Vue host hook): photos kept as thumbnails,
// how many took the canvas fallback, and cards whose text was measured.
this.stats = { loaded: 0, thumbs: 0, thumbsFallback: 0, measured: 0 }
// cardPx: one card's on-screen width at the last frame drawn, so a probe can read the zoom level.
this.stats = { loaded: 0, thumbs: 0, thumbsFallback: 0, measured: 0, cardPx: 0 }
this.loading = 0
this.queue = []
this.canvas = document.createElement('canvas')
@ -180,6 +181,7 @@ export class WallCanvas {
ctx.setTransform(this.dpr * s, 0, 0, this.dpr * s, this.dpr * tx, this.dpr * ty)
if (this.posterOn) return this.drawPoster(ctx, s, tx, ty)
const cardPx = this.grid.cw * s
this.stats.cardPx = Math.round(cardPx)
const { c0, c1, r0, r1 } = this.visibleRange()
const want = []
for (let r = r0; r <= r1; r++) {
@ -207,6 +209,7 @@ export class WallCanvas {
for (const R of sp.sheets) ctx.fillRect(R.x, R.y, R.w, R.h)
const [x0, y0] = this.toWorld(0, 0), [x1, y1] = this.toWorld(this.cssW, this.cssH)
const cardPx = (sp.cards[0]?.w || 0) * s, want = []
this.stats.cardPx = Math.round(cardPx)
this.measureBudget = MEASURE_PER_FRAME; this.measureMore = false
for (const R of sp.cards) {
if (R.x + R.w < x0 || R.x > x1 || R.y + R.h < y0 || R.y > y1) continue

View file

@ -14,7 +14,8 @@
*
* Data: the live pray.doxa.life people-group list (2,107 groups, with photos and prayer counts).
* Prayers and comments stay in this browser's localStorage, under a 'wall-pg:' prefix.
* d3 and Font Awesome are CDN globals, loaded on first mount.
* d3 is loaded on first mount, pinned and integrity-checked, and kept off the host's window.d3
* (src/wallD3.js). Font Awesome is no longer used: the canvas draws its own icons.
*/
import PeopleGroupsWall from './src/components/PeopleGroupsWall.vue'
import CommentsDialog from './src/components/CommentsDialog.vue'