fix(parallax): animate background-position-y directly so SSR parallax works pre-WASM
This commit is contained in:
@@ -2,8 +2,11 @@
|
||||
* parallax - scroll-driven background-position panning for ParallaxImage.
|
||||
*
|
||||
* Single Responsibility: own the parallax math and scroll/observer lifecycle.
|
||||
* Blazor owns the component lifecycle and calls register/unregister; this module
|
||||
* writes only the `--parallax-pos` CSS custom property — never concrete style.
|
||||
* Blazor owns the component lifecycle and calls register/unregister. When the
|
||||
* IntersectionObserver fires and JS attaches the scroll listener, this module
|
||||
* sets data-parallax-active and immediately primes background-position-y —
|
||||
* atomically cancelling the pre-WASM CSS animation and writing the correct
|
||||
* position in the same turn, so there is no flash at the handoff.
|
||||
*/
|
||||
|
||||
interface RegisterOptions {
|
||||
@@ -44,7 +47,12 @@ function applyParallax(handle: Handle): void {
|
||||
progress = clamp(progress, 0, 1);
|
||||
|
||||
const pos = progress * clamp(options.speed, 0, 1) * 100;
|
||||
element.style.setProperty('--parallax-pos', `${pos}%`);
|
||||
// Write background-position-y on each layer directly — the same property the
|
||||
// pre-WASM CSS animation drives (now cancelled via data-parallax-active).
|
||||
const layers = element.querySelectorAll<HTMLElement>(':scope > .layer');
|
||||
for (const layer of layers) {
|
||||
layer.style.backgroundPositionY = `${pos}%`;
|
||||
}
|
||||
}
|
||||
|
||||
function attachScrollListener(handle: Handle): void {
|
||||
@@ -60,7 +68,8 @@ function attachScrollListener(handle: Handle): void {
|
||||
|
||||
handle.scrollListener = listener;
|
||||
window.addEventListener('scroll', listener, { passive: true });
|
||||
// Prime position immediately so entry isn't a frame behind the first scroll.
|
||||
// Cancel CSS animation and prime position atomically — no gap where neither drives.
|
||||
handle.element.setAttribute('data-parallax-active', '');
|
||||
applyParallax(handle);
|
||||
}
|
||||
|
||||
@@ -140,6 +149,7 @@ export function unregister(handleId: string): void {
|
||||
if (!handle) return;
|
||||
|
||||
detachScrollListener(handle);
|
||||
handle.element.removeAttribute('data-parallax-active');
|
||||
handle.observer.disconnect();
|
||||
handle.resizeObserver?.disconnect();
|
||||
handles.delete(handleId);
|
||||
|
||||
Reference in New Issue
Block a user