impress-2020/public/animate-test.html
Matchu fb39a4f935 simplify animate-test code
we got rid of the custom timing now that I learned about additional API hooks to do exactly what I want!
2020-09-21 15:57:01 -07:00

150 lines
4.8 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<script src="https://code.createjs.com/1.0.0/easeljs.min.js"></script>
<script src="https://code.createjs.com/1.0.0/tweenjs.min.js"></script>
<script src="/api/assetProxy?url=http://images.neopets.com/cp/items/data/000/000/564/564507_fc3216b9b8/all-item_foreground_lower.js"></script>
</head>
<body>
<div style="display: flex; justify-content: center;">
<div
style="
width: 100%;
max-width: 600px;
border: 1px solid #aaa;
position: relative;
"
>
<div style="padding-bottom: 100%;"></div>
<canvas
id="stage-canvas"
style="
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
"
></canvas>
</div>
</div>
<div style="margin-top: 1em; text-align: center;">
<button id="show-hide">Show/hide</button>
<button id="pause-play">Pause/play</button>
</div>
<div style="margin-top: 1em; text-align: center;">
FPS: <span id="fps-count"></span>
</div>
<script>
function loadImage(src) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = () => resolve(image);
image.onerror = (e) => reject(e);
image.src = src;
});
}
function proxyUrl(url) {
return "/api/assetProxy?url=" + encodeURIComponent(url);
}
async function main() {
const composition = Object.values(AdobeAn.compositions)[0];
const library = composition.getLibrary();
const manifestImages = new Map(
library.properties.manifest.map(({ id, src }) => [
id,
loadImage(
proxyUrl(
"http://images.neopets.com/cp/items/data/000/000/564/564507_fc3216b9b8/" +
src
)
),
])
);
try {
await Promise.all(manifestImages.values());
} catch (e) {
console.error("Error loading images", e);
return;
}
const spriteSheets = composition.getSpriteSheet();
for (const { name, frames } of library.ssMetadata) {
const image = await manifestImages.get(name);
spriteSheets[name] = new createjs.SpriteSheet({
images: [image],
frames,
});
}
const movieClip = new library.allitem_foreground_lower();
const canvas = document.getElementById("stage-canvas");
const stage = new library.Stage(canvas);
canvas.width = canvas.offsetWidth * window.devicePixelRatio;
canvas.height = canvas.offsetHeight * window.devicePixelRatio;
stage.scaleX =
(canvas.offsetWidth * window.devicePixelRatio) /
library.properties.width;
stage.scaleY =
(canvas.offsetHeight * window.devicePixelRatio) /
library.properties.height;
movieClip.alpha = 0;
const tween = createjs.Tween.get(movieClip, { paused: true }).to(
{ alpha: 1 },
200
);
stage.on(
"drawend",
() => {
tween.paused = false;
},
null,
true
);
// TODO: I'm not 100% clear on why, but manually caching the movie and
// manually updating the cache at a 60FPS rate (that's how often
// the tick fires, regardless of movie framerate) seems to
// substantially improve performance of things like fade-in. I
// think it might just be perceived performance, because the
// alpha applies to a cached raster instead of the individual
// layers, so it looks better? Although hell, maybe applying
// alpha to a cached raster just _is_ faster than applying it to
// like 200 overlapping layers, that would just make sense...
movieClip.cache(
0,
0,
library.properties.width,
library.properties.height
);
movieClip.on("tick", () => movieClip.updateCache());
stage.addChild(movieClip);
movieClip.framerate = library.properties.fps;
createjs.Ticker.timingMode = createjs.Ticker.RAF;
createjs.Ticker.on("tick", (e) => stage.update(e));
document.getElementById("show-hide").addEventListener("click", () => {
tween.reversed = !tween.reversed;
tween.setPosition(0);
tween.paused = false;
});
document.getElementById("pause-play").addEventListener("click", () => {
movieClip.tickEnabled = !movieClip.tickEnabled;
});
}
main();
</script>
</body>
</html>