fix: decode portrait frames before first interaction

This commit is contained in:
Leon
2026-08-18 19:09:38 +08:00
parent 4060b9fb84
commit dda7963d8d
3 changed files with 40 additions and 4 deletions

View File

@@ -838,6 +838,7 @@ var SkinPresenter = class {
poster;
portrait;
preloads;
portraitReady = false;
enabled = true;
// Default to the max frame so the first paint after load is the dark shell;
// starting at 0 flashed the light palette before the directory resolved.
@@ -852,7 +853,7 @@ var SkinPresenter = class {
this.root = document.createElement("div");
this.root.className = "liang-skin-backdrop";
this.root.dataset.plugin = PACKAGE_ID;
this.root.dataset.media = "sequence";
this.root.dataset.media = "poster";
this.root.setAttribute("aria-hidden", "true");
this.poster = document.createElement("img");
this.poster.className = "liang-skin-poster";
@@ -866,10 +867,22 @@ var SkinPresenter = class {
this.portrait.addEventListener("error", this.handleSequenceError);
this.preloads = PORTRAIT_ANCHORS.map(({ file }) => {
const image = new Image();
image.loading = "eager";
image.decoding = "async";
image.src = `${ASSET_PREFIX}/portrait-source-v2/${file}`;
return image;
});
void Promise.all(this.preloads.map((image) => image.decode())).then(
() => {
if (this.disposed) return;
this.portraitReady = true;
this.root.dataset.media = "sequence";
this.updatePortrait(paletteForFrame(this.frame).level);
},
() => {
if (!this.disposed) this.root.dataset.media = "poster";
}
);
this.root.append(this.portrait, this.poster);
document.body.prepend(this.root);
this.poster.addEventListener("error", this.handlePosterError);
@@ -942,6 +955,7 @@ var SkinPresenter = class {
this.theme.setTheme(theme);
}
updatePortrait(level) {
if (!this.portraitReady) return;
const { lowerIndex, upperIndex, mix: mix2 } = portraitBlendForLevel(
level,
ANCHOR_LEVELS