Load movies in iframe for new item page preview

Hey hey, it's working! Still stuff to add like pause/play, but yeah!
This commit is contained in:
Emi Matchu 2024-07-03 20:15:35 -07:00
parent 5b2062754d
commit 97e6c39402
4 changed files with 64 additions and 22 deletions

View file

@ -7,19 +7,47 @@ class OutfitLayer extends HTMLElement {
}
connectedCallback() {
setTimeout(() => this.#initializeImage(), 0);
setTimeout(() => this.#connectToChildren(), 0);
}
#initializeImage() {
this.image = this.querySelector("img");
if (!this.image) {
throw new Error(`<outfit-layer> must contain an <img> tag`);
disconnectedCallback() {
window.removeEventListener("message", this.#onMessage);
}
#connectToChildren() {
const image = this.querySelector("img");
const iframe = this.querySelector("iframe");
if (image) {
image.addEventListener("load", () => this.#setStatus("loaded"));
image.addEventListener("error", () => this.#setStatus("error"));
this.#setStatus(image.complete ? "loaded" : "loading");
} else if (iframe) {
this.iframe = iframe;
window.addEventListener("message", (m) => this.#onMessage(m));
this.#setStatus("loading");
} else {
throw new Error(
`<outfit-layer> must contain an <img> or <iframe> tag`,
);
}
}
#onMessage({ source, data }) {
if (source !== this.iframe.contentWindow) {
return;
}
this.image.addEventListener("load", () => this.#setStatus("loaded"));
this.image.addEventListener("error", () => this.#setStatus("error"));
this.#setStatus(this.image.complete ? "loaded" : "loading");
if (
data.type === "status" &&
["loaded", "error"].includes(data.status)
) {
this.#setStatus(data.status);
} else {
throw new Error(
`<outfit-layer> got unexpected message: ${JSON.stringify(data)}`,
);
}
}
#setStatus(newStatus) {

View file

@ -301,15 +301,24 @@ window.addEventListener("message", ({ data }) => {
}
});
startMovie().catch((error) => {
console.error(logPrefix, error);
startMovie()
.then(() => {
parent.postMessage(
{ type: "status", status: "loaded" },
document.location.origin,
);
})
.catch((error) => {
console.error(logPrefix, error);
loadingStatus = "error";
canvas.setAttribute("data-status", "error");
canvas.setAttribute("data-error-message", error.message);
loadingStatus = "error";
parent.postMessage(
{ type: "status", status: "error" },
document.location.origin,
);
// If loading the movie fails, show the fallback image instead, by moving
// it out of the canvas content and into the body.
document.body.appendChild(document.getElementById("fallback"));
console.warn("Showing fallback image instead.");
});
// If loading the movie fails, show the fallback image instead, by moving
// it out of the canvas content and into the body.
document.body.appendChild(document.getElementById("fallback"));
console.warn("Showing fallback image instead.");
});

View file

@ -54,13 +54,16 @@ body.items-show
position: absolute
inset: 0
img
img, iframe
width: 100%
height: 100%
&:has(outfit-layer:state(loading))
background: gray
&:has(outfit-layer:state(error))
border-color: $error-border-color
.species-color-picker
.error-icon
cursor: help
@ -70,4 +73,3 @@ body.items-show
select
border-color: $error-border-color
color: $error-color

View file

@ -6,4 +6,7 @@
"zone": swf_asset.zone.label,
},
}
= image_tag swf_asset.image_url, alt: ""
- if swf_asset.canvas_movie?
%iframe{src: swf_asset_path(swf_asset) + "?playing"}
- else
= image_tag swf_asset.image_url, alt: ""