Skip to content

Commit cb58c87

Browse files
authored
Merge pull request #4 from TheShovel/develop
2 parents b55d80d + 7615638 commit cb58c87

6 files changed

Lines changed: 3739 additions & 3361 deletions

File tree

src/BitmapSkin.js

Lines changed: 117 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,133 @@
1-
const twgl = require('twgl.js');
1+
const twgl = require("twgl.js");
22

3-
const Skin = require('./Skin');
3+
const Skin = require("./Skin");
44

55
class BitmapSkin extends Skin {
6-
/**
7-
* Create a new Bitmap Skin.
8-
* @extends Skin
9-
* @param {!int} id - The ID for this Skin.
10-
* @param {!RenderWebGL} renderer - The renderer which will use this skin.
11-
*/
12-
constructor (id, renderer) {
13-
super(id, renderer);
14-
15-
/** @type {!int} */
16-
this._costumeResolution = 1;
17-
18-
/** @type {Array<int>} */
19-
this._textureSize = [0, 0];
6+
/**
7+
* Create a new Bitmap Skin.
8+
* @extends Skin
9+
* @param {!int} id - The ID for this Skin.
10+
* @param {!RenderWebGL} renderer - The renderer which will use this skin.
11+
*/
12+
constructor(id, renderer) {
13+
super(id, renderer);
14+
15+
/** @type {!int} */
16+
this._costumeResolution = 1;
17+
18+
/** @type {Array<int>} */
19+
this._textureSize = [0, 0];
20+
}
21+
22+
/**
23+
* Dispose of this object. Do not use it after calling this method.
24+
*/
25+
dispose() {
26+
if (this._texture) {
27+
this._renderer.gl.deleteTexture(this._texture);
28+
this._texture = null;
2029
}
21-
22-
/**
23-
* Dispose of this object. Do not use it after calling this method.
24-
*/
25-
dispose () {
26-
if (this._texture) {
27-
this._renderer.gl.deleteTexture(this._texture);
28-
this._texture = null;
29-
}
30-
super.dispose();
30+
super.dispose();
31+
}
32+
33+
/**
34+
* @return {Array<number>} the "native" size, in texels, of this skin.
35+
*/
36+
get size() {
37+
return [
38+
this._textureSize[0] / this._costumeResolution,
39+
this._textureSize[1] / this._costumeResolution,
40+
];
41+
}
42+
43+
/**
44+
* @param {Array<number>} scale - The scaling factors to be used.
45+
* @return {WebGLTexture} The GL texture representation of this skin when drawing at the given scale.
46+
*/
47+
// eslint-disable-next-line no-unused-vars
48+
getTexture(scale) {
49+
return this._texture || super.getTexture();
50+
}
51+
52+
/**
53+
* Set the contents of this skin to a snapshot of the provided bitmap data.
54+
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} bitmapData - new contents for this skin.
55+
* @param {int} [costumeResolution=1] - The resolution to use for this bitmap.
56+
* @param {Array<number>} [rotationCenter] - Optional rotation center for the bitmap. If not supplied, it will be
57+
* calculated from the bounding box
58+
* @fires Skin.event:WasAltered
59+
*/
60+
setBitmap(bitmapData, costumeResolution, rotationCenter) {
61+
if (!bitmapData.width || !bitmapData.height) {
62+
super.setEmptyImageData();
63+
return;
3164
}
32-
33-
/**
34-
* @return {Array<number>} the "native" size, in texels, of this skin.
35-
*/
36-
get size () {
37-
return [this._textureSize[0] / this._costumeResolution, this._textureSize[1] / this._costumeResolution];
65+
const gl = this._renderer.gl;
66+
67+
// TW: We want to use <canvas> as-is because reading ImageData wastes memory.
68+
// However, vanilla LLK/scratch-vm will reuse any canvas that we get here for other costumes,
69+
// which will cause bugs when Silhouette lazily reads the canvas data.
70+
// Turbo Warp/scratch-vm does not reuse canvases and will set canvas.reusable = false.
71+
let textureData = bitmapData;
72+
if (
73+
bitmapData instanceof HTMLCanvasElement &&
74+
bitmapData.reusable !== false
75+
) {
76+
const context = bitmapData.getContext("2d", { willReadFrequently: true });
77+
textureData = context.getImageData(
78+
0,
79+
0,
80+
bitmapData.width,
81+
bitmapData.height,
82+
);
3883
}
3984

40-
/**
41-
* @param {Array<number>} scale - The scaling factors to be used.
42-
* @return {WebGLTexture} The GL texture representation of this skin when drawing at the given scale.
43-
*/
44-
// eslint-disable-next-line no-unused-vars
45-
getTexture (scale) {
46-
return this._texture || super.getTexture();
85+
if (this._texture === null) {
86+
const textureOptions = {
87+
auto: false,
88+
wrap: gl.CLAMP_TO_EDGE,
89+
};
90+
91+
this._texture = twgl.createTexture(gl, textureOptions);
4792
}
4893

49-
/**
50-
* Set the contents of this skin to a snapshot of the provided bitmap data.
51-
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} bitmapData - new contents for this skin.
52-
* @param {int} [costumeResolution=1] - The resolution to use for this bitmap.
53-
* @param {Array<number>} [rotationCenter] - Optional rotation center for the bitmap. If not supplied, it will be
54-
* calculated from the bounding box
55-
* @fires Skin.event:WasAltered
56-
*/
57-
setBitmap (bitmapData, costumeResolution, rotationCenter) {
58-
if (!bitmapData.width || !bitmapData.height) {
59-
super.setEmptyImageData();
60-
return;
61-
}
62-
const gl = this._renderer.gl;
63-
64-
// TW: We want to use <canvas> as-is because reading ImageData wastes memory.
65-
// However, vanilla LLK/scratch-vm will reuse any canvas that we get here for other costumes,
66-
// which will cause bugs when Silhouette lazily reads the canvas data.
67-
// Turbo Warp/scratch-vm does not reuse canvases and will set canvas.reusable = false.
68-
let textureData = bitmapData;
69-
if (bitmapData instanceof HTMLCanvasElement && bitmapData.reusable !== false) {
70-
const context = bitmapData.getContext('2d');
71-
textureData = context.getImageData(0, 0, bitmapData.width, bitmapData.height);
72-
}
73-
74-
if (this._texture === null) {
75-
const textureOptions = {
76-
auto: false,
77-
wrap: gl.CLAMP_TO_EDGE
78-
};
79-
80-
this._texture = twgl.createTexture(gl, textureOptions);
81-
}
82-
83-
this._setTexture(textureData);
84-
85-
// Do these last in case any of the above throws an exception
86-
this._costumeResolution = costumeResolution || 2;
87-
this._textureSize = BitmapSkin._getBitmapSize(bitmapData);
88-
89-
if (typeof rotationCenter === 'undefined') rotationCenter = this.calculateRotationCenter();
90-
this._rotationCenter[0] = rotationCenter[0];
91-
this._rotationCenter[1] = rotationCenter[1];
92-
93-
this.emitWasAltered();
94+
this._setTexture(textureData);
95+
96+
// Do these last in case any of the above throws an exception
97+
this._costumeResolution = costumeResolution || 2;
98+
this._textureSize = BitmapSkin._getBitmapSize(bitmapData);
99+
100+
if (typeof rotationCenter === "undefined")
101+
rotationCenter = this.calculateRotationCenter();
102+
this._rotationCenter[0] = rotationCenter[0];
103+
this._rotationCenter[1] = rotationCenter[1];
104+
105+
this.emitWasAltered();
106+
}
107+
108+
/**
109+
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} bitmapData - bitmap data to inspect.
110+
* @returns {Array<int>} the width and height of the bitmap data, in pixels.
111+
* @private
112+
*/
113+
static _getBitmapSize(bitmapData) {
114+
if (bitmapData instanceof HTMLImageElement) {
115+
return [
116+
bitmapData.naturalWidth || bitmapData.width,
117+
bitmapData.naturalHeight || bitmapData.height,
118+
];
94119
}
95120

96-
/**
97-
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} bitmapData - bitmap data to inspect.
98-
* @returns {Array<int>} the width and height of the bitmap data, in pixels.
99-
* @private
100-
*/
101-
static _getBitmapSize (bitmapData) {
102-
if (bitmapData instanceof HTMLImageElement) {
103-
return [bitmapData.naturalWidth || bitmapData.width, bitmapData.naturalHeight || bitmapData.height];
104-
}
105-
106-
if (bitmapData instanceof HTMLVideoElement) {
107-
return [bitmapData.videoWidth || bitmapData.width, bitmapData.videoHeight || bitmapData.height];
108-
}
109-
110-
// ImageData or HTMLCanvasElement
111-
return [bitmapData.width, bitmapData.height];
121+
if (bitmapData instanceof HTMLVideoElement) {
122+
return [
123+
bitmapData.videoWidth || bitmapData.width,
124+
bitmapData.videoHeight || bitmapData.height,
125+
];
112126
}
113127

128+
// ImageData or HTMLCanvasElement
129+
return [bitmapData.width, bitmapData.height];
130+
}
114131
}
115132

116133
module.exports = BitmapSkin;

0 commit comments

Comments
 (0)