Skip to content

Instantly share code, notes, and snippets.

@sorskoot
Created Apr 19, 2022
Embed
What would you like to do?
Wonderland Component doing Flipbook Animation
class DynamicTextureCache {
constructor() {
this.textures = {};
}
loadTextures(url, columns, rows) {
if (!this.textures.hasOwnProperty(url)) {
this.textures[url] = new Promise((resolve, reject) => { let image = new Image();
let textures = [];
image.src = url;
image.onload = () => {
let canvas = document.createElement('canvas');
let context = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0);
let spriteWidth = image.width / columns;
let spriteHeight = image.height / rows;
for (let y = 0; y < rows; y++) {
for (let x = 0; x < columns; x++) {
let pc = this.copyPartOfCanvas(canvas, x * spriteWidth, y * spriteHeight, spriteWidth, spriteHeight);
let texturePc = new WL.Texture(pc);
textures.push(texturePc);
}
};
resolve(textures);
};
})
}
return this.textures[url];
}
copyPartOfCanvas(canvas, x, y, width, height) {
let copy = document.createElement('canvas');
copy.width = width;
copy.height = height;
let ctx2 = copy.getContext("2d");
ctx2.drawImage(canvas, x, y, width, height, 0, 0, width, height);
return copy;
}
}
let textureCache = new DynamicTextureCache();
WL.registerComponent('flipbook', {
base: { type: WL.Type.Material },
url: { type: WL.Type.String, default: '' },
columns: { type: WL.Type.Int, default: 4 },
rows: { type: WL.Type.Int, default: 4 },
duration: { type: WL.Type.Float, default: 2.0 },
loop: { type: WL.Type.Bool, default: true },
}, {
init: function () {
this.textures = [];
/* Keep inactive until texture loaded */
this.active = false;
textureCache.loadTextures(this.url, this.columns, this.rows).then((tex) => {
for (let i = 0; i < tex.length; i++) {
this.textures.push(this.createMaterial(this.base, tex[i]));
};
this.active = true;
this.index = Math.floor(Math.random() * this.textures.length);
});
},
createMaterial: function (base, texture, emissiveTexture) {
let mat = base.clone();
if (mat.shader == "Flat Opaque Textured") {
mat.flatTexture = texture;
} else if (mat.shader == "Phong Opaque Textured") {
mat.diffuseTexture = texture;
} else {
console.error("Shader", mat.shader, "not supported by flipbook");
}
return mat;
},
start: function () {
this.mesh = this.object.getComponent("mesh");
},
onActivate: function() {
this.t = 0;
this.mesh.active = true;
},
onDeactivate: function() {
if(this.mesh) this.mesh.active = false;
},
update: function(dt) {
this.t += dt;
const frame = ~~(this.t*this.textures.length/this.duration);
if(!this.loop && frame >= this.textures.length) {
this.active = false;
}
this.index = frame % this.textures.length;
if (this.textures && this.textures.length && this.previousIndex != this.index) {
this.previousIndex = this.index;
this.mesh.material = this.textures[this.index];
}
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment