This commit is contained in:
33333-33333 2026-06-21 22:29:00 +09:00
commit 0a6148c73f
67 changed files with 2653 additions and 1519 deletions

View file

@ -7,11 +7,13 @@ const imageAssetIndex = new Map();
const scaledSpriteCache = new Map();
const stainOverlayCache = new Map();
const SPRITE_CACHE_LIMIT = 128;
const STAIN_CACHE_LIMIT = 64;
const INITIAL_IMAGE_IDS = new Set(["smile", "zunchi", "zunchi_02", "genkotsu"]);
const EARLY_IMAGE_IDS = new Set(["smile", "angry", "teary", "jito", "drool", "cry", "sleep", "pokan", "normal_smirk", "normal_tongue", "normal_happy", "weak", "hurt", "hurt2", "zunchi", "zunchi_02", "genkotsu"]);
const INITIAL_IMAGE_IDS = new Set(["smile", "hungry_70", "zunchi_slave", "zunchi_slave_alt", "zunchi", "zunchi_02", "genkotsu", "pushpin", "pushpin_stuck"]);
const EARLY_IMAGE_IDS = new Set(["smile", "angry", "teary", "jito", "drool", "cry", "sleep", "pokan", "normal_smirk", "normal_tongue", "normal_happy", "weak", "hurt", "hurt2", "fear", "flee", "flee_fear2", "fear_blue", "fear_cry", "sleep2", "stress_dizzy", "stress_sweat", "intimidate", "birth_ritual", "zunchi_slave", "zunchi_slave_alt", "hungry_70", "zunchi", "zunchi_02", "genkotsu", "pushpin", "pushpin_stuck"]);
function trimCanvasCache(cache, limit = 420) {
function trimCanvasCache(cache, limit = 128) {
while (cache.size > limit) {
const first = cache.keys().next().value;
if (first === undefined) break;
@ -19,16 +21,16 @@ function trimCanvasCache(cache, limit = 420) {
}
}
function quantizedCanvasSize(v, step = 16) {
function quantizedCanvasSize(v, step = 24) {
return Math.max(1, Math.round(v / step) * step);
}
const SPRITE_CACHE_SCALE = 2.0;
const SPRITE_CACHE_SCALE = 1.55;
function getCachedSpriteCanvas(id, img, w, h) {
if (!img || !w || !h) return img;
const qw = quantizedCanvasSize(w, 16);
const qh = quantizedCanvasSize(h, 16);
const qw = quantizedCanvasSize(w);
const qh = quantizedCanvasSize(h);
const key = `${id}:${qw}x${qh}`;
let canvas = scaledSpriteCache.get(key);
if (canvas) return canvas;
@ -41,14 +43,14 @@ function getCachedSpriteCanvas(id, img, w, h) {
c.clearRect(0, 0, qw, qh);
c.drawImage(img, 0, 0, qw, qh);
scaledSpriteCache.set(key, canvas);
trimCanvasCache(scaledSpriteCache, 520);
trimCanvasCache(scaledSpriteCache, SPRITE_CACHE_LIMIT);
return canvas;
}
function getCachedStainOverlayCanvas(id, img, w, h, stain = 0, seed = 0.5) {
if (!img || stain <= 0.01 || !w || !h) return null;
const qw = quantizedCanvasSize(w, 16);
const qh = quantizedCanvasSize(h, 16);
const qw = quantizedCanvasSize(w);
const qh = quantizedCanvasSize(h);
const bucket = Math.max(1, Math.min(8, Math.ceil(stain * 8)));
const seedBucket = Math.round((seed || 0) * 16);
const key = `${id}:${qw}x${qh}:s${bucket}:r${seedBucket}`;
@ -80,7 +82,7 @@ function getCachedStainOverlayCanvas(id, img, w, h, stain = 0, seed = 0.5) {
c.globalAlpha = 1;
c.globalCompositeOperation = "source-over";
stainOverlayCache.set(key, canvas);
trimCanvasCache(stainOverlayCache, 360);
trimCanvasCache(stainOverlayCache, STAIN_CACHE_LIMIT);
return canvas;
}
@ -175,9 +177,23 @@ function loadImages(ids = null, onProgress = null) {
return Promise.all(tasks).then(() => undefined);
}
function trimImageMemory(aggressive = false) {
trimCanvasCache(scaledSpriteCache, aggressive ? 48 : SPRITE_CACHE_LIMIT);
trimCanvasCache(stainOverlayCache, aggressive ? 16 : STAIN_CACHE_LIMIT);
}
if (typeof document !== "undefined") {
document.addEventListener("visibilitychange", () => {
if (document.hidden) trimImageMemory(true);
});
}
if (typeof window !== "undefined") {
window.setInterval(() => trimImageMemory(false), 45000);
}
function startBackgroundImageLoading() {
setupAssetIndex();
const allAssets = [...SPRITES, ...DECOR_ASSETS];
const loadGroup = (ids, priority = "low") => {
for (const id of ids) {
const asset = imageAssetIndex.get(id);
@ -189,7 +205,8 @@ function startBackgroundImageLoading() {
: (fn) => setTimeout(fn, 60);
schedule(() => loadGroup(EARLY_IMAGE_IDS, "auto"), 450);
schedule(() => {
for (const asset of allAssets) loadImageAsset(asset, "low");
for (const asset of [...SPRITES, ...DECOR_ASSETS]) loadImageAsset(asset, "low");
trimImageMemory(false);
}, 2200);
}
@ -224,4 +241,4 @@ function getImageMetrics(idOrImg) {
setupAssetIndex();
window.TarinaiAssets = { images, imageBoundsCache, imageMetrics, imagePromises, scaledSpriteCache, stainOverlayCache, loadImages, startBackgroundImageLoading, ensureImage, isImageReady, getRenderableImage, imageAlphaBounds, getImageMetrics, getCachedSpriteCanvas, getCachedStainOverlayCanvas };
window.TarinaiAssets = { images, imageBoundsCache, imageMetrics, imagePromises, scaledSpriteCache, stainOverlayCache, loadImages, startBackgroundImageLoading, trimImageMemory, ensureImage, isImageReady, getRenderableImage, imageAlphaBounds, getImageMetrics, getCachedSpriteCanvas, getCachedStainOverlayCanvas };