fix(ads): banner truly continuous across navigation + re-measure on resize
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 48s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m6s
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 48s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m6s
The previous engine kept the scheduler running but the view re-`show()`-ed the
current message on every (re)mount, replaying the fade on each navigation — which
looked like the cycle restarting (especially for a single message). Now:
- A mounted AdBanner reads the engine's live message (bannerCurrent) and renders
it immediately, with no fade; attach no longer re-shows. Only a real advance
fades. Verified: opacity stays 1.0 across a navigation, message preserved.
- The fade is manual opacity on a .fadewrap layer (not transition:fade), kept
independent of the scroll (inner track transform), so a long message still
fades at both ends and a {#key} remount cannot force an intro fade.
- A viewport size change (portrait↔landscape) re-measures the current message
(remeasureBanner on resize/orientationchange, debounced) so the scroll
re-evaluates for the new width — the owner accepts the restart on resize.
Rotator gains restart(); engine gains bannerCurrent()/remeasureBanner().
Engine continuity + remeasure unit-tested.
This commit is contained in:
@@ -54,12 +54,31 @@ export function configureBanner(campaigns: BannerCampaign[], timings: BannerTimi
|
||||
}
|
||||
|
||||
/**
|
||||
* attachBannerHost connects a freshly-mounted view as the DOM host and resyncs it to the live
|
||||
* message, so the banner resumes mid-cycle instead of restarting.
|
||||
* bannerCurrent returns the message the engine is currently displaying (empty before the first
|
||||
* one). A freshly-mounted view reads it to render the live message immediately, without a fade —
|
||||
* so navigating between screens does not visibly restart the cycle.
|
||||
*/
|
||||
export function bannerCurrent(): string {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* attachBannerHost connects a freshly-mounted view as the DOM host. It does NOT re-show the
|
||||
* current message (the view renders it itself from bannerCurrent on mount): re-showing here would
|
||||
* replay the fade-in on every navigation, which looks like the cycle restarting. The engine's own
|
||||
* timer keeps driving show/hide for real message changes through this host.
|
||||
*/
|
||||
export function attachBannerHost(host: BannerHost): void {
|
||||
mounted = host;
|
||||
if (current) host.show(current);
|
||||
}
|
||||
|
||||
/**
|
||||
* remeasureBanner re-presents the current message (re-measuring overflow and restarting its
|
||||
* scroll), for when the viewport size changed (e.g. a portrait↔landscape rotation) and a message
|
||||
* that fit may now overflow, or vice versa.
|
||||
*/
|
||||
export function remeasureBanner(): void {
|
||||
rotator?.restart();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user