fix(ui): kiosk map animates again + paints on resize; gloss scoped; icons get intrinsic size
Demo images / Build & push demo images (push) Successful in 3m42s
Demo images / Build & push demo images (push) Successful in 3m42s
- NetworkMap3D: kiosks keep static PLACEMENT (the rAF-fragile intro was the blank-screen cause) but re-attach the half-rate ticker — the calm orbit is back; and measure() now renders explicitly when no ticker runs, so resizes repaint instead of leaving a stale/blank/mis-scaled projection (also fixes reduced-motion users on any screen). - Gloss v3 scoped to .logo-gloss opt-in (screensaver, intro, login, splash tap-logo) — it had leaked onto every logo-gradient-border user, including the dashboard header, via AnimatedLogo's default border. - normalize-app-icon.py output now carries intrinsic 512x512 dimensions: a viewBox-only SVG collapses to nothing in auto-sized tiles (the 'transparent icon in My Apps' report); both app icons regenerated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
2b7e92e770
commit
b5e33784e6
@@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 100 100">
|
||||||
<!-- normalized by scripts/normalize-app-icon.py: margin=0.12 per side -->
|
<!-- normalized by scripts/normalize-app-icon.py: margin=0.12 per side -->
|
||||||
<svg x="12.000" y="12.000" width="76.000" height="76.000" viewBox="0 0 8000 8000" preserveAspectRatio="xMidYMid meet">
|
<svg x="12.000" y="12.000" width="76.000" height="76.000" viewBox="0 0 8000 8000" preserveAspectRatio="xMidYMid meet">
|
||||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8000 8000">
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8000 8000">
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.7 KiB |
@@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 100 100">
|
||||||
<!-- normalized by scripts/normalize-app-icon.py: margin=0.12 per side -->
|
<!-- normalized by scripts/normalize-app-icon.py: margin=0.12 per side -->
|
||||||
<svg x="12.000" y="12.000" width="76.000" height="76.000" viewBox="0 0 94 94" preserveAspectRatio="xMidYMid meet">
|
<svg x="12.000" y="12.000" width="76.000" height="76.000" viewBox="0 0 94 94" preserveAspectRatio="xMidYMid meet">
|
||||||
<svg viewBox="0 0 94 94" id="vector" xmlns="http://www.w3.org/2000/svg">
|
<svg viewBox="0 0 94 94" id="vector" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="logo-gradient-border screensaver-logo-cycle relative w-48 h-48 sm:w-64 sm:h-64 md:w-80 md:h-80 flex items-center justify-center overflow-hidden">
|
<div class="logo-gradient-border logo-gloss screensaver-logo-cycle relative w-48 h-48 sm:w-64 sm:h-64 md:w-80 md:h-80 flex items-center justify-center overflow-hidden">
|
||||||
<!-- Squares logo -->
|
<!-- Squares logo -->
|
||||||
<div class="screensaver-logo-squares absolute inset-[3px] flex items-center justify-center">
|
<div class="screensaver-logo-squares absolute inset-[3px] flex items-center justify-center">
|
||||||
<AnimatedLogo size="xl" no-border fit />
|
<AnimatedLogo size="xl" no-border fit />
|
||||||
|
|||||||
@@ -878,7 +878,9 @@ function tick(_time: number, deltaMS: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function attachTicker() {
|
function attachTicker() {
|
||||||
if (tickerAttached || staticMode) return
|
// Kiosks run staticMode for PLACEMENT (instant, intro-free) but still get
|
||||||
|
// the calm orbit — half-rate via the kioskLowPower frame-skip in tick().
|
||||||
|
if (tickerAttached || (staticMode && !kioskLowPower)) return
|
||||||
gsap.ticker.add(tick)
|
gsap.ticker.add(tick)
|
||||||
tickerAttached = true
|
tickerAttached = true
|
||||||
}
|
}
|
||||||
@@ -1179,17 +1181,19 @@ function measure() {
|
|||||||
}
|
}
|
||||||
// Resize: snap to the current mode's fit (no tween — tracks the drag)
|
// Resize: snap to the current mode's fit (no tween — tracks the drag)
|
||||||
applyMode(viewMode.value, false)
|
applyMode(viewMode.value, false)
|
||||||
|
// No ticker (reduced-motion) means nobody repaints after this resize —
|
||||||
|
// without an explicit render the map keeps its stale (possibly zero-size)
|
||||||
|
// projection: the "loads blank / wrong scale until refresh" bug.
|
||||||
|
if (built && !tickerAttached) render()
|
||||||
}
|
}
|
||||||
|
|
||||||
function initialBuild() {
|
function initialBuild() {
|
||||||
// Kiosk TVs get the fully static map: no entrance animation, no ticker.
|
// Kiosk TVs take the static PLACEMENT path (the GSAP entrance intro needs
|
||||||
// The GSAP intro needs healthy rAF delivery to ever reach opacity 1 — on
|
// healthy rAF delivery to reach opacity 1 — on a paint-starved kiosk it
|
||||||
// a paint-starved kiosk it stalls and the screen reads as BLANK until a
|
// stalls and the screen reads as BLANK until a lucky refresh,
|
||||||
// lucky refresh (framework-pt, 2026-08-14). Half-rate ticking (below)
|
// framework-pt 2026-08-14) but keep the calm orbital motion: the ticker
|
||||||
// helped but any continuous SVG animation is still the single biggest
|
// re-attaches below at half rate. Fully-static-everything was tried and
|
||||||
// load on the kiosk's compositor, and at TV distance the still map loses
|
// rejected — it also killed the animation on screens that could carry it.
|
||||||
// nothing. Everything lands in place immediately, graph updates apply
|
|
||||||
// instantly, and the 2D/3D toggle still works.
|
|
||||||
staticMode = prefersReducedMotion() || kioskLowPower
|
staticMode = prefersReducedMotion() || kioskLowPower
|
||||||
built = true
|
built = true
|
||||||
applyGraph()
|
applyGraph()
|
||||||
@@ -1208,6 +1212,8 @@ function initialBuild() {
|
|||||||
if (staticMode) {
|
if (staticMode) {
|
||||||
introPlayed = true
|
introPlayed = true
|
||||||
playIntro() // static branch: everything lands in place
|
playIntro() // static branch: everything lands in place
|
||||||
|
attachTicker() // no-op for reduced-motion; kiosks resume the calm orbit
|
||||||
|
render() // paint the landed state now — nothing else repaints until a tick
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
attachTicker()
|
attachTicker()
|
||||||
|
|||||||
@@ -1135,13 +1135,15 @@ html.controller-nav [data-controller-container]:focus {
|
|||||||
lower reflection arc, bottom depth vignette, paint-black base; inset
|
lower reflection arc, bottom depth vignette, paint-black base; inset
|
||||||
rim lights; and a curved liquid "window streak" on ::before (under
|
rim lights; and a curved liquid "window streak" on ::before (under
|
||||||
the badge's z-1 content, above the paint). Revert: delete this block. */
|
the badge's z-1 content, above the paint). Revert: delete this block. */
|
||||||
.logo-gradient-border {
|
.logo-gradient-border.logo-gloss,
|
||||||
|
.tap-to-start-logo .logo-gradient-border {
|
||||||
background: none;
|
background: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.logo-gradient-border::after {
|
.logo-gradient-border.logo-gloss::after,
|
||||||
|
.tap-to-start-logo .logo-gradient-border::after {
|
||||||
inset: 0;
|
inset: 0;
|
||||||
/* Dense intermediate stops + a fine turbulence grain (top layer,
|
/* Dense intermediate stops + a fine turbulence grain (top layer,
|
||||||
overlay-blended) dither the near-black falloffs — without them the
|
overlay-blended) dither the near-black falloffs — without them the
|
||||||
@@ -1160,7 +1162,8 @@ html.controller-nav [data-controller-container]:focus {
|
|||||||
inset 0 0 0 1px rgba(255,242,212,0.08),
|
inset 0 0 0 1px rgba(255,242,212,0.08),
|
||||||
0 12px 34px rgba(0,0,0,0.65);
|
0 12px 34px rgba(0,0,0,0.65);
|
||||||
}
|
}
|
||||||
.logo-gradient-border::before {
|
.logo-gradient-border.logo-gloss::before,
|
||||||
|
.tap-to-start-logo .logo-gradient-border::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 8%;
|
left: 8%;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
>
|
>
|
||||||
<!-- Logo - half in, half out of container -->
|
<!-- Logo - half in, half out of container -->
|
||||||
<div class="absolute -top-10 left-1/2 -translate-x-1/2 z-10">
|
<div class="absolute -top-10 left-1/2 -translate-x-1/2 z-10">
|
||||||
<div class="logo-gradient-border w-20 h-20">
|
<div class="logo-gradient-border logo-gloss w-20 h-20">
|
||||||
<AnimatedLogo no-border fit />
|
<AnimatedLogo no-border fit />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="glass-card p-8 pt-16 sm:p-12 sm:pt-20 text-center relative overflow-visible onb-card">
|
<div class="glass-card p-8 pt-16 sm:p-12 sm:pt-20 text-center relative overflow-visible onb-card">
|
||||||
<!-- Logo - half in, half out of container -->
|
<!-- Logo - half in, half out of container -->
|
||||||
<div class="absolute -top-8 sm:-top-10 left-0 right-0 flex justify-center z-10 onb-logo">
|
<div class="absolute -top-8 sm:-top-10 left-0 right-0 flex justify-center z-10 onb-logo">
|
||||||
<div class="logo-gradient-border w-16 h-16 sm:w-20 sm:h-20">
|
<div class="logo-gradient-border logo-gloss w-16 h-16 sm:w-20 sm:h-20">
|
||||||
<AnimatedLogo no-border fit />
|
<AnimatedLogo no-border fit />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ def main() -> int:
|
|||||||
inner = re.sub(r"^\s*<\?xml[^>]*\?>\s*", "", svg)
|
inner = re.sub(r"^\s*<\?xml[^>]*\?>\s*", "", svg)
|
||||||
|
|
||||||
out = (
|
out = (
|
||||||
f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {canvas:g} {canvas:g}">\n'
|
f'<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 {canvas:g} {canvas:g}">\n'
|
||||||
f' <!-- normalized by scripts/normalize-app-icon.py: margin={args.margin:g} per side -->\n'
|
f' <!-- normalized by scripts/normalize-app-icon.py: margin={args.margin:g} per side -->\n'
|
||||||
f' <svg x="{x:.3f}" y="{y:.3f}" width="{scale_w:.3f}" height="{scale_h:.3f}" '
|
f' <svg x="{x:.3f}" y="{y:.3f}" width="{scale_w:.3f}" height="{scale_h:.3f}" '
|
||||||
f'viewBox="{inner_viewbox}" preserveAspectRatio="xMidYMid meet">\n'
|
f'viewBox="{inner_viewbox}" preserveAspectRatio="xMidYMid meet">\n'
|
||||||
|
|||||||
Reference in New Issue
Block a user