Add/update methods to Skin class to handle an empty skin.

This commit is contained in:
Karishma Chadha 2019-10-07 13:11:58 -04:00
parent b7a3d32cde
commit c25d1f37b8
3 changed files with 56 additions and 2 deletions

View file

@ -56,7 +56,7 @@ class BitmapSkin extends Skin {
*/
// eslint-disable-next-line no-unused-vars
getTexture (scale) {
return this._texture;
return this._texture || super.getTexture();
}
/**
@ -78,6 +78,10 @@ class BitmapSkin extends Skin {
* @fires Skin.event:WasAltered
*/
setBitmap (bitmapData, costumeResolution, rotationCenter) {
if (!bitmapData.width || !bitmapData.height) {
super.setEmptyImageData();
return;
}
const gl = this._renderer.gl;
// Preferably bitmapData is ImageData. ImageData speeds up updating

View file

@ -66,6 +66,10 @@ class SVGSkin extends Skin {
*/
// eslint-disable-next-line no-unused-vars
getTexture (scale) {
if (!this._svgRenderer.canvas.width || !this._svgRenderer.canvas.height) {
return super.getTexture();
}
// The texture only ever gets uniform scale. Take the larger of the two axes.
const scaleMax = scale ? Math.max(Math.abs(scale[0]), Math.abs(scale[1])) : 100;
const requestedScale = Math.min(scaleMax / 100, this._maxTextureScale);
@ -108,6 +112,12 @@ class SVGSkin extends Skin {
// updating Silhouette and is better handled by more browsers in
// regards to memory.
const canvas = this._svgRenderer.canvas;
if (!canvas.width || !canvas.height) {
super.setEmptyImageData();
return;
}
const context = canvas.getContext('2d');
const textureData = context.getImageData(0, 0, canvas.width, canvas.height);

View file

@ -140,7 +140,7 @@ class Skin extends EventEmitter {
*/
// eslint-disable-next-line no-unused-vars
getTexture (scale) {
return null;
return this._emptyImageTexture;
}
/**
@ -171,6 +171,46 @@ class Skin extends EventEmitter {
*/
updateSilhouette () {}
/**
* Set the contents of this skin to an empty skin.
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} bitmapData - new contents for this skin.
* @param {int} [costumeResolution=1] - The resolution to use for this bitmap.
* @param {Array<number>} [rotationCenter] - Optional rotation center for the bitmap. If not supplied, it will be
* calculated from the bounding box
* @fires Skin.event:WasAltered
*/
setEmptyImageData () {
// Free up the current reference to the _texture
this._texture = null;
if (this._emptyImageData) {
this._silhouette.update(this._emptyImageData);
} else {
// Create a transparent pixel
this._emptyImageData = new ImageData(1, 1);
// Create a new texture and update the silhouette
const gl = this._renderer.gl;
const textureOptions = {
auto: true,
wrap: gl.CLAMP_TO_EDGE,
src: this._emptyImageData
};
// Note: we're using _emptyImageTexture here instead of _texture
// so that we can cache this empty texture for later use as needed.
// this._texture can get modified by other skins (e.g. BitmapSkin
// and SVGSkin, so we can't use that same field for caching)
this._emptyImageTexture = twgl.createTexture(gl, textureOptions);
this._silhouette.update(this._emptyImageData);
}
// TODO should we just make it not visible here?
this.emit(Skin.Events.WasAltered);
}
/**
* Does this point touch an opaque or translucent point on this skin?
* Nearest Neighbor version