mirror of
https://github.com/scratchfoundation/scratch-render.git
synced 2025-08-28 22:30:04 -04:00
Add/update methods to Skin class to handle an empty skin.
This commit is contained in:
parent
b7a3d32cde
commit
c25d1f37b8
3 changed files with 56 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
42
src/Skin.js
42
src/Skin.js
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue