From 97a035b3a360433d49a654ae12be6d0e9f861ebf Mon Sep 17 00:00:00 2001 From: Emi Matchu Date: Thu, 5 Feb 2026 18:59:08 -0800 Subject: [PATCH] [WV2] Fix bug where play/pause button shows even after anims removed --- app/assets/javascripts/outfit-viewer.js | 43 ++++++++++++++----------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/outfit-viewer.js b/app/assets/javascripts/outfit-viewer.js index d173cf78..5187ffb3 100644 --- a/app/assets/javascripts/outfit-viewer.js +++ b/app/assets/javascripts/outfit-viewer.js @@ -8,7 +8,31 @@ class OutfitViewer extends HTMLElement { } connectedCallback() { - // Set up listener for bubbled hasanimationschange events from layers + const observer = new MutationObserver((mutations) => { + // When a layer is added, update its playing state to match ours. + const addedLayers = mutations + .flatMap(m => [...m.addedNodes]) + .filter(n => n.tagName === "OUTFIT-LAYER"); + for (const layer of addedLayers) { + if (this.#internals.states.has("playing")) { + layer.play(); + } else { + layer.pause(); + } + } + + const removedLayers = mutations + .flatMap(m => [...m.removedNodes]) + .filter(n => n.tagName === "OUTFIT-LAYER"); + + // If any layers were added or removed, updated our hasAnimations state. + if (addedLayers.length > 0 || removedLayers.length > 0) { + this.#updateHasAnimations(); + } + }); + observer.observe(this, { childList: true }); + + // When a new layer finishes loading and determines it has animations, update. this.addEventListener("hasanimationschange", (e) => { // Only handle events from outfit-layer children, not from ourselves if (e.target === this) return; @@ -16,23 +40,6 @@ class OutfitViewer extends HTMLElement { this.#updateHasAnimations(); }); - // Watch for new layers being added and apply the current playing state - const observer = new MutationObserver((mutations) => { - for (const mutation of mutations) { - for (const node of mutation.addedNodes) { - if (node.tagName === "OUTFIT-LAYER") { - // Apply current playing state to the new layer - if (this.#internals.states.has("playing")) { - node.play(); - } else { - node.pause(); - } - } - } - } - }); - observer.observe(this, { childList: true }); - // The `` is connected to the DOM right before its // children are. So, to engage with the children, wait a tick! setTimeout(() => this.#connectToChildren(), 0);