Skip to content

Instantly share code, notes, and snippets.

@elliotthall
Created September 11, 2024 16:16
Show Gist options
  • Select an option

  • Save elliotthall/7aa197b94bdff1d7a9d30ba7d8d9d192 to your computer and use it in GitHub Desktop.

Select an option

Save elliotthall/7aa197b94bdff1d7a9d30ba7d8d9d192 to your computer and use it in GitHub Desktop.
A texture flipbook in A frame
/**
Load a series of images as the texture of the entity
files are loaded on start using these properties
urlPrefix+index+.+fileType
to make a url like /assets/monitor_1.jpg
*/
AFRAME.registerComponent('texture-flipbook', {
multiple: true,
// Selector for image src for detail
schema: {
urlPrefix: {type: 'string', default: '/stemcellclinic/public/assets/stemcellcity/bedroom/monitor_0'},
fileType: {type: 'string', default: 'png'}, // used as filename suffix, so make sure it matches your file
startFrame: {type: 'int', default: 1},
endFrame: {type: 'int', default: 1}, // Included with loop
speed: {type: 'int', default: 500},
repeat: {type: 'boolean', default: true},
startOnLoad: {type: 'boolean'}
},
init: function () {
this.imageArray = [];
this.index = 0;
this.playing = false;
this.loadImages();
},
/** Loads in sequence using start and end frame, if one is missing we stop with a warning */
loadImages: function () {
const loader = new THREE.TextureLoader();
this.imageArray = [];
for (let x = this.data.startFrame; x <= this.data.endFrame; x++) {
const imageURL = this.data.urlPrefix + x + "." + this.data.fileType;
const imageFile = loader.load(imageURL);
if (imageFile) {
this.imageArray.push(imageFile);
} else {
console.log(imageURL + " not found for texture flipbook! Stopping load");
break;
}
}
},
play: function () {
const mesh = this.el.getObject3D("mesh");
this.material = mesh.material;
// We store this so we can revert to starting state
this.defaultMap = mesh.material.map;
if (this.data.startOnLoad) {
this.playFlipbook();
}
},
revert: function () {
this.material.map = this.defaultMap;
this.material.needsUpdate = true;
},
playFlipbook: function () {
this.playing = true;
this.flipbookInterval = setInterval(e => {
if (this.playing) {
this.nextFrame();
}
}, this.data.speed);
},
nextFrame: function () {
if (this.index >= this.imageArray.length) {
this.index = 0;
this.finishFlipbook();
return;
}
this.material.map = this.imageArray[this.index++];
this.material.needsUpdate = true;
},
finishFlipbook: function () {
if (!this.data.repeat) {
this.stopFlipbook();
}
this.el.emit('onFlipbookFinished', {
id: this.id,
repeat: this.data.repeat,
endFrame: this.data.endFrame
}, false);
},
/** Stop animation but leave the frame index where it is */
pauseFlipbook: function () {
clearInterval(this.detail.id);
this.playing = false;
},
/** Stop animation and reset the index */
stopFlipbook: function () {
clearInterval(this.flipbookInterval);
this.index = 0;
this.playing = false;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment