<!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>