diff --git a/plugin-designs/gospel-internet/src/components/GiBoundedSetMap.vue b/plugin-designs/gospel-internet/src/components/GiBoundedSetMap.vue index d2527cc5b..54ae341af 100644 --- a/plugin-designs/gospel-internet/src/components/GiBoundedSetMap.vue +++ b/plugin-designs/gospel-internet/src/components/GiBoundedSetMap.vue @@ -102,19 +102,26 @@ onMounted(async () => { console.warn('[gospel-internet] the centre cross could not be drawn:', e && e.message || e) } - // ★ FIT THE WHOLE TARGET ON LOAD. The default zoom clipped the outer rings top and bottom — - // the reader met a drawing already cut off, which reads as a rendering fault rather than as - // something to zoom out of. Fitted from the projected extent, so it follows the chart's own - // size rather than a guessed zoom. - try { - const [w, sLat] = project(-SPREAD, -SPREAD) - const [e, nLat] = project(SPREAD, SPREAD) - // Padding is generous and symmetric because the fit must hold the LABELS too, not just the - // points: at 1280 the outermost band label sat on the canvas edge. And a short, wide canvas - // (the bounded chart in a narrow column is 796x249) fits to WIDTH and clips top and bottom - // unless the bounds are given room in the dimension that is scarce. - map.fitBounds([[w, sLat], [e, nLat]], { padding: 40, duration: 0 }) - } catch (_) {} + // ★ FIT AFTER THE BOX HAS SETTLED, AND RESIZE FIRST. The previous version fitted + // immediately: on one narrow layout the canvas was still 796x249 from a stale measurement, + // so the fit was computed against the wrong aspect, resolved to the WIDTH, and clipped the + // cloud top and bottom. Raising the padding did nothing there, because padding cannot fix a + // fit that was aimed at a box of the wrong shape — which is why that one layout was + // unchanged while the others improved. + // map.resize() makes the engine re-read the container; fitting on the next frame lets the + // flex layout finish first. Both are cheap and neither depends on a timer. + const fitTarget = () => { + try { + map.resize() + const [w, sLat] = project(-SPREAD, -SPREAD) + const [e, nLat] = project(SPREAD, SPREAD) + map.fitBounds([[w, sLat], [e, nLat]], { padding: 40, duration: 0 }) + } catch (_) { /* a fit that cannot be computed leaves the default view, which still draws */ } + } + if (typeof requestAnimationFrame === 'function') requestAnimationFrame(fitTarget) + else fitTarget() + // and again once the engine settles, for a container that was still resolving on that frame + try { map.once('idle', fitTarget) } catch (_) {} } // ★ CALLED UNCONDITIONALLY, AND THE GUARD THAT USED TO BE HERE IS WHY THIS WAS BROKEN TWICE. // createBoardMap only resolves after `await map.once('load')`, so by here the event HAS fired. diff --git a/plugin-designs/gospel-internet/src/components/GiCenteredSetMap.vue b/plugin-designs/gospel-internet/src/components/GiCenteredSetMap.vue index de0f28477..aa2c669e8 100644 --- a/plugin-designs/gospel-internet/src/components/GiCenteredSetMap.vue +++ b/plugin-designs/gospel-internet/src/components/GiCenteredSetMap.vue @@ -117,19 +117,26 @@ onMounted(async () => { console.warn('[gospel-internet] the centre cross could not be drawn:', e && e.message || e) } - // ★ FIT THE WHOLE TARGET ON LOAD. The default zoom clipped the outer rings top and bottom — - // the reader met a drawing already cut off, which reads as a rendering fault rather than as - // something to zoom out of. Fitted from the projected extent, so it follows the chart's own - // size rather than a guessed zoom. - try { - const [w, sLat] = project(-EXTENT, -EXTENT) - const [e, nLat] = project(EXTENT, EXTENT) - // Padding is generous and symmetric because the fit must hold the LABELS too, not just the - // points: at 1280 the outermost band label sat on the canvas edge. And a short, wide canvas - // (the bounded chart in a narrow column is 796x249) fits to WIDTH and clips top and bottom - // unless the bounds are given room in the dimension that is scarce. - map.fitBounds([[w, sLat], [e, nLat]], { padding: 40, duration: 0 }) - } catch (_) {} + // ★ FIT AFTER THE BOX HAS SETTLED, AND RESIZE FIRST. The previous version fitted + // immediately: on one narrow layout the canvas was still 796x249 from a stale measurement, + // so the fit was computed against the wrong aspect, resolved to the WIDTH, and clipped the + // cloud top and bottom. Raising the padding did nothing there, because padding cannot fix a + // fit that was aimed at a box of the wrong shape — which is why that one layout was + // unchanged while the others improved. + // map.resize() makes the engine re-read the container; fitting on the next frame lets the + // flex layout finish first. Both are cheap and neither depends on a timer. + const fitTarget = () => { + try { + map.resize() + const [w, sLat] = project(-EXTENT, -EXTENT) + const [e, nLat] = project(EXTENT, EXTENT) + map.fitBounds([[w, sLat], [e, nLat]], { padding: 40, duration: 0 }) + } catch (_) { /* a fit that cannot be computed leaves the default view, which still draws */ } + } + if (typeof requestAnimationFrame === 'function') requestAnimationFrame(fitTarget) + else fitTarget() + // and again once the engine settles, for a container that was still resolving on that frame + try { map.once('idle', fitTarget) } catch (_) {} ready.value = true } // ★ CALLED UNCONDITIONALLY, AND THE GUARD THAT USED TO BE HERE IS WHY THIS WAS BROKEN TWICE. diff --git a/plugin-designs/gospel-internet/src/setChartFeatures.js b/plugin-designs/gospel-internet/src/setChartFeatures.js index 87e9b0c95..fa78c6f91 100644 --- a/plugin-designs/gospel-internet/src/setChartFeatures.js +++ b/plugin-designs/gospel-internet/src/setChartFeatures.js @@ -157,8 +157,13 @@ export function degreesToPixelRadius(degrees, { minZoom = 0, maxZoom = 22 } = {} * else here. */ export function crossFeature(project, { arm = 13, cx = 0, cy = 0 } = {}) { - const vert = [[cx, cy - arm], [cx, cy + arm]].map(([u, v]) => project(u, v)) - const horiz = [[cx - arm * 0.7, cy - arm * 0.35], [cx + arm * 0.7, cy - arm * 0.35]].map(([u, v]) => project(u, v)) + // Latin proportions, not a plus. Reported as reading "+ with equal arms": the upper arm was + // 0.65 of the lower, which is a real difference and too small to see at this size. The upper + // arm is now a third of the lower and the bar is narrower than the height, so the shape is + // legible as a cross at the size it is actually drawn. + const upper = arm * 0.55, lower = arm * 1.65, bar = arm * 0.62 + const vert = [[cx, cy - upper], [cx, cy + lower]].map(([u, v]) => project(u, v)) + const horiz = [[cx - bar, cy - upper * 0.05], [cx + bar, cy - upper * 0.05]].map(([u, v]) => project(u, v)) return { type: 'FeatureCollection', features: [ diff --git a/public/dx-maps/doxa-maps-spa/manifest.json b/public/dx-maps/doxa-maps-spa/manifest.json index c410f8d9b..0394f00bd 100644 --- a/public/dx-maps/doxa-maps-spa/manifest.json +++ b/public/dx-maps/doxa-maps-spa/manifest.json @@ -615,7 +615,7 @@ "bundle": "gospel-internet", "scriptUrl": "./gospel-internet/gospel-internet.js", "output": "dx-maps/gospel-internet/gospel-internet.js", - "integrity": "sha384-ms4BzXmzlKrMiucFY6RR1kcxpNI1KEllXaqE6K4JtxWe0I6VkpkFcf7GulVybnrr", + "integrity": "sha384-6ypksiuOg1UYnG8SJOD9nFoDxMeisCv7Z8ZxvQtGI8E0Yonjw1IkXPHOI2hoHVTn", "elements": [ "gospel-internet-board" ], @@ -635,7 +635,7 @@ "scriptUrl": "./gospel-internet/gospel-internet.js", "embed": { "iframe": "", - "script": "\n\n\n\n\n" + "script": "\n\n\n\n\n" }, "instances": [ { diff --git a/public/dx-maps/gospel-internet/board/board/index.html b/public/dx-maps/gospel-internet/board/board/index.html index 27b8f8a7f..bfa643029 100644 --- a/public/dx-maps/gospel-internet/board/board/index.html +++ b/public/dx-maps/gospel-internet/board/board/index.html @@ -36,7 +36,7 @@ - + - + - + - + - + - + - + \n\n\n" + "script": "\n\n\n\n\n" }, "instances": [ {