mirror of
https://github.com/scratchfoundation/scratch-render.git
synced 2025-06-27 07:21:54 -04:00
Use eslint-config-scratch, fix linting errors
This commit is contained in:
parent
47b46fb1aa
commit
5db860efed
11 changed files with 149 additions and 160 deletions
|
@ -1,5 +1,3 @@
|
|||
dist.js
|
||||
dist/*
|
||||
node_modules/*
|
||||
playground/*
|
||||
render.js
|
||||
render.min.js
|
||||
|
|
21
.eslintrc
21
.eslintrc
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6
|
||||
},
|
||||
"rules": {
|
||||
"curly": [2, "multi-line"],
|
||||
"eol-last": [2],
|
||||
"indent": [2, 4],
|
||||
"quotes": [2, "single"],
|
||||
"linebreak-style": [2, "unix"],
|
||||
"max-len": [2, 80, 4],
|
||||
"semi": [2, "always"],
|
||||
"strict": [2, "never"]
|
||||
},
|
||||
"env": {
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"worker": true
|
||||
},
|
||||
"extends": "eslint:recommended"
|
||||
}
|
4
.eslintrc.js
Normal file
4
.eslintrc.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
extends: ['scratch', 'scratch/node']
|
||||
};
|
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -20,7 +20,7 @@
|
|||
|
||||
# Prefer LF for these files
|
||||
.editorconfig text eol=lf
|
||||
.eslintrc text eol=lf
|
||||
.eslintignore text eol=lf
|
||||
.gitattributes text eol=lf
|
||||
.gitignore text eol=lf
|
||||
.gitmodules text eol=lf
|
||||
|
|
|
@ -22,12 +22,13 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "6.9.1",
|
||||
"babel-eslint": "6.0.4",
|
||||
"babel-eslint": "7.1.1",
|
||||
"babel-loader": "6.2.4",
|
||||
"babel-polyfill": "6.9.1",
|
||||
"babel-preset-es2015": "6.9.0",
|
||||
"base64-loader": "1.0.0",
|
||||
"eslint": "2.7.0",
|
||||
"eslint": "3.12.0",
|
||||
"eslint-config-scratch": "3.1.0",
|
||||
"gh-pages": "0.11.0",
|
||||
"hull.js": "0.2.10",
|
||||
"json": "9.0.4",
|
||||
|
|
11
src/.eslintrc.js
Normal file
11
src/.eslintrc.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
extends: ['scratch', 'scratch/es6', 'scratch/node'],
|
||||
env: {
|
||||
node: false,
|
||||
browser: true // TODO: disable this
|
||||
},
|
||||
globals: {
|
||||
Buffer: true // TODO: remove this?
|
||||
}
|
||||
};
|
103
src/Drawable.js
103
src/Drawable.js
|
@ -9,13 +9,14 @@ class Drawable {
|
|||
/**
|
||||
* An object which can be drawn by the renderer.
|
||||
* TODO: double-buffer all rendering state (position, skin, effects, etc.)
|
||||
* @param gl The OpenGL context.
|
||||
* @param {WebGLRenderingContext} gl The OpenGL context.
|
||||
* @constructor
|
||||
*/
|
||||
constructor(gl) {
|
||||
constructor (gl) {
|
||||
this._id = Drawable._nextDrawable++;
|
||||
Drawable._allDrawables[this._id] = this;
|
||||
|
||||
/** @type {WebGLRenderingContext} */
|
||||
this._gl = gl;
|
||||
|
||||
/**
|
||||
|
@ -56,7 +57,7 @@ class Drawable {
|
|||
for (var index = 0; index < numEffects; ++index) {
|
||||
var effectName = ShaderManager.EFFECTS[index];
|
||||
var converter = ShaderManager.EFFECT_INFO[effectName].converter;
|
||||
this._uniforms['u_' + effectName] = converter(0);
|
||||
this._uniforms[`u_${effectName}`] = converter(0);
|
||||
}
|
||||
|
||||
this._position = twgl.v3.create(0, 0);
|
||||
|
@ -109,7 +110,7 @@ Drawable._allDrawables = {};
|
|||
|
||||
/**
|
||||
* Fetch a Drawable by its ID number.
|
||||
* @param drawableID {int} The ID of the Drawable to fetch.
|
||||
* @param {int} drawableID The ID of the Drawable to fetch.
|
||||
* @returns {?Drawable} The specified Drawable if found, otherwise null.
|
||||
*/
|
||||
Drawable.getDrawableByID = function (drawableID) {
|
||||
|
@ -158,27 +159,26 @@ Drawable.prototype.getID = function () {
|
|||
* Set this Drawable's skin.
|
||||
* The Drawable will continue using the existing skin until the new one loads.
|
||||
* If there is no existing skin, the Drawable will use a 1x1 transparent image.
|
||||
* @param {string} skin_url The URL of the skin.
|
||||
* @param {number=} opt_costumeResolution Optionally, a resolution for the skin.
|
||||
* @param {string} skinUrl The URL of the skin.
|
||||
* @param {number=} optCostumeResolution Optionally, a resolution for the skin.
|
||||
*/
|
||||
Drawable.prototype.setSkin = function (skin_url, opt_costumeResolution) {
|
||||
Drawable.prototype.setSkin = function (skinUrl, optCostumeResolution) {
|
||||
// TODO: cache Skins instead of loading each time. Ref count them?
|
||||
// TODO: share Skins across Drawables - see also destroy()
|
||||
if (skin_url) {
|
||||
var ext = skin_url.substring(skin_url.lastIndexOf('.')+1);
|
||||
if (skinUrl) {
|
||||
var ext = skinUrl.substring(skinUrl.lastIndexOf('.') + 1);
|
||||
switch (ext) {
|
||||
case 'svg':
|
||||
case 'svg/get/':
|
||||
case 'svgz':
|
||||
case 'svgz/get/':
|
||||
this._setSkinSVG(skin_url);
|
||||
this._setSkinSVG(skinUrl);
|
||||
break;
|
||||
default:
|
||||
this._setSkinBitmap(skin_url, opt_costumeResolution);
|
||||
this._setSkinBitmap(skinUrl, optCostumeResolution);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this._useSkin(null, 0, 0, 1, true);
|
||||
}
|
||||
};
|
||||
|
@ -190,15 +190,15 @@ Drawable.prototype.setSkin = function (skin_url, opt_costumeResolution) {
|
|||
* @param {int} width The width of the skin.
|
||||
* @param {int} height The height of the skin.
|
||||
* @param {int} costumeResolution The resolution to use for this skin.
|
||||
* @param {Boolean} [skipPendingCheck] If true, don't compare to _pendingSkin.
|
||||
* @param {boolean} [skipPendingCheck] If true, don't compare to _pendingSkin.
|
||||
* @private
|
||||
*/
|
||||
Drawable.prototype._useSkin = function(
|
||||
Drawable.prototype._useSkin = function (
|
||||
skin, width, height, costumeResolution, skipPendingCheck) {
|
||||
|
||||
if (skipPendingCheck || (skin == this._pendingSkin)) {
|
||||
if (skipPendingCheck || (skin === this._pendingSkin)) {
|
||||
this._pendingSkin = null;
|
||||
if (this._uniforms.u_skin && (this._uniforms.u_skin != skin)) {
|
||||
if (this._uniforms.u_skin && (this._uniforms.u_skin !== skin)) {
|
||||
this._gl.deleteTexture(this._uniforms.u_skin);
|
||||
}
|
||||
this._setSkinSize(width, height, costumeResolution);
|
||||
|
@ -215,14 +215,13 @@ Drawable.prototype.getEnabledEffects = function () {
|
|||
|
||||
/**
|
||||
* Load a bitmap skin. Supports the same formats as the Image element.
|
||||
* @param {string} skin_md5ext The MD5 and file extension of the bitmap skin.
|
||||
* @param {number=} opt_costumeResolution Optionally, a resolution for the skin.
|
||||
* @param {string} skinMd5ext The MD5 and file extension of the bitmap skin.
|
||||
* @param {number=} optCostumeResolution Optionally, a resolution for the skin.
|
||||
* @private
|
||||
*/
|
||||
Drawable.prototype._setSkinBitmap = function (skin_md5ext,
|
||||
opt_costumeResolution) {
|
||||
var url = skin_md5ext;
|
||||
this._setSkinCore(url, opt_costumeResolution);
|
||||
Drawable.prototype._setSkinBitmap = function (skinMd5ext, optCostumeResolution) {
|
||||
var url = skinMd5ext;
|
||||
this._setSkinCore(url, optCostumeResolution);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -233,23 +232,23 @@ Drawable.prototype._setSkinBitmap = function (skin_md5ext,
|
|||
* - Colors seem a little off. This may be browser-specific.
|
||||
* - This method works in Chrome, Firefox, Safari, and Edge but causes a
|
||||
* security error in IE.
|
||||
* @param {string} skin_md5ext The MD5 and file extension of the SVG skin.
|
||||
* @param {string} skinMd5ext The MD5 and file extension of the SVG skin.
|
||||
* @private
|
||||
*/
|
||||
Drawable.prototype._setSkinSVG = function (skin_md5ext) {
|
||||
var url = skin_md5ext;
|
||||
Drawable.prototype._setSkinSVG = function (skinMd5ext) {
|
||||
var url = skinMd5ext;
|
||||
var instance = this;
|
||||
|
||||
let svgCanvas = document.createElement('canvas');
|
||||
let svgRenderer = new SvgRenderer(svgCanvas);
|
||||
|
||||
function gotSVG(err, response, body) {
|
||||
const gotSVG = (err, response, body) => {
|
||||
if (!err) {
|
||||
svgRenderer.fromString(body, function () {
|
||||
svgRenderer.fromString(body, () => {
|
||||
instance._setSkinCore(svgCanvas, svgRenderer.getDrawRatio());
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.get({
|
||||
useXDR: true,
|
||||
url: url
|
||||
|
@ -265,10 +264,10 @@ Drawable.prototype._setSkinSVG = function (skin_md5ext) {
|
|||
*/
|
||||
Drawable.prototype._setSkinCore = function (source, costumeResolution) {
|
||||
var instance = this;
|
||||
var callback = function (err, texture, source) {
|
||||
if (!err && (instance._pendingSkin == texture)) {
|
||||
var callback = function (err, texture, sourceInCallback) {
|
||||
if (!err && (instance._pendingSkin === texture)) {
|
||||
instance._useSkin(
|
||||
texture, source.width, source.height, costumeResolution);
|
||||
texture, sourceInCallback.width, sourceInCallback.height, costumeResolution);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -280,7 +279,7 @@ Drawable.prototype._setSkinCore = function (source, costumeResolution) {
|
|||
wrap: gl.CLAMP_TO_EDGE,
|
||||
src: source
|
||||
};
|
||||
var willCallCallback = typeof source == 'string';
|
||||
var willCallCallback = typeof source === 'string';
|
||||
instance._pendingSkin = twgl.createTexture(
|
||||
gl, options, willCallCallback ? callback : null);
|
||||
|
||||
|
@ -292,8 +291,7 @@ Drawable.prototype._setSkinCore = function (source, costumeResolution) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Retrieve the shader uniforms to be used when rendering this Drawable.
|
||||
* @returns {Object.<string, *>}
|
||||
* @returns {object.<string, *>} the shader uniforms to be used when rendering this Drawable.
|
||||
*/
|
||||
Drawable.prototype.getUniforms = function () {
|
||||
if (this._transformDirty) {
|
||||
|
@ -303,8 +301,7 @@ Drawable.prototype.getUniforms = function () {
|
|||
};
|
||||
|
||||
/**
|
||||
* Retrieve whether this Drawable is visible.
|
||||
* @returns {boolean}
|
||||
* @returns {boolean} whether this Drawable is visible.
|
||||
*/
|
||||
Drawable.prototype.getVisible = function () {
|
||||
return this._visible;
|
||||
|
@ -312,7 +309,7 @@ Drawable.prototype.getVisible = function () {
|
|||
|
||||
/**
|
||||
* Update the position, direction, scale, or effect properties of this Drawable.
|
||||
* @param {Object.<string,*>} properties The new property values to set.
|
||||
* @param {object.<string,*>} properties The new property values to set.
|
||||
*/
|
||||
Drawable.prototype.updateProperties = function (properties) {
|
||||
var dirty = false;
|
||||
|
@ -321,26 +318,26 @@ Drawable.prototype.updateProperties = function (properties) {
|
|||
this.setConvexHullDirty();
|
||||
}
|
||||
if ('position' in properties && (
|
||||
this._position[0] != properties.position[0] ||
|
||||
this._position[1] != properties.position[1])) {
|
||||
this._position[0] !== properties.position[0] ||
|
||||
this._position[1] !== properties.position[1])) {
|
||||
this._position[0] = properties.position[0];
|
||||
this._position[1] = properties.position[1];
|
||||
dirty = true;
|
||||
}
|
||||
if ('direction' in properties && this._direction != properties.direction) {
|
||||
if ('direction' in properties && this._direction !== properties.direction) {
|
||||
this._direction = properties.direction;
|
||||
dirty = true;
|
||||
}
|
||||
if ('scale' in properties && (
|
||||
this._scale[0] != properties.scale[0] ||
|
||||
this._scale[1] != properties.scale[1])) {
|
||||
this._scale[0] !== properties.scale[0] ||
|
||||
this._scale[1] !== properties.scale[1])) {
|
||||
this._scale[0] = properties.scale[0];
|
||||
this._scale[1] = properties.scale[1];
|
||||
dirty = true;
|
||||
}
|
||||
if ('rotationCenter' in properties && (
|
||||
this._rotationCenter[0] != properties.rotationCenter[0] ||
|
||||
this._rotationCenter[1] != properties.rotationCenter[1])) {
|
||||
this._rotationCenter[0] !== properties.rotationCenter[0] ||
|
||||
this._rotationCenter[1] !== properties.rotationCenter[1])) {
|
||||
this._rotationCenter[0] = properties.rotationCenter[0];
|
||||
this._rotationCenter[1] = properties.rotationCenter[1];
|
||||
dirty = true;
|
||||
|
@ -358,14 +355,13 @@ Drawable.prototype.updateProperties = function (properties) {
|
|||
if (effectName in properties) {
|
||||
var rawValue = properties[effectName];
|
||||
var effectInfo = ShaderManager.EFFECT_INFO[effectName];
|
||||
if (rawValue != 0) {
|
||||
if (rawValue !== 0) {
|
||||
this._effectBits |= effectInfo.mask;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this._effectBits &= ~effectInfo.mask;
|
||||
}
|
||||
var converter = effectInfo.converter;
|
||||
this._uniforms['u_' + effectName] = converter(rawValue);
|
||||
this._uniforms[`u_${effectName}`] = converter(rawValue);
|
||||
if (effectInfo.shapeChanges) {
|
||||
this.setConvexHullDirty();
|
||||
}
|
||||
|
@ -384,8 +380,7 @@ Drawable.prototype._setSkinSize = function (width, height, costumeResolution) {
|
|||
costumeResolution = costumeResolution || 1;
|
||||
width /= costumeResolution;
|
||||
height /= costumeResolution;
|
||||
if (this._uniforms.u_skinSize[0] != width
|
||||
|| this._uniforms.u_skinSize[1] != height) {
|
||||
if (this._uniforms.u_skinSize[0] !== width || this._uniforms.u_skinSize[1] !== height) {
|
||||
this._uniforms.u_skinSize[0] = width;
|
||||
this._uniforms.u_skinSize[1] = height;
|
||||
this.setTransformDirty();
|
||||
|
@ -467,7 +462,7 @@ Drawable.prototype.setConvexHullPoints = function (points) {
|
|||
*/
|
||||
Drawable.prototype.getBounds = function () {
|
||||
if (this.needsConvexHullPoints()) {
|
||||
throw 'Needs updated convex hull points before bounds calculation.';
|
||||
throw new Error('Needs updated convex hull points before bounds calculation.');
|
||||
}
|
||||
if (this._transformDirty) {
|
||||
this._calculateTransform();
|
||||
|
@ -538,7 +533,7 @@ Drawable.prototype.getFastBounds = function () {
|
|||
* @param {int} id The ID to convert.
|
||||
* @returns {number[]} An array of [r,g,b,a], each component in the range [0,1].
|
||||
*/
|
||||
Drawable.color4fFromID = function(id) {
|
||||
Drawable.color4fFromID = function (id) {
|
||||
id -= Drawable.NONE;
|
||||
var r = ((id >> 0) & 255) / 255.0;
|
||||
var g = ((id >> 8) & 255) / 255.0;
|
||||
|
@ -557,7 +552,7 @@ Drawable.color4fFromID = function(id) {
|
|||
* @returns {int} The ID represented by that color.
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
Drawable.color4bToID = function(r, g, b, a) {
|
||||
Drawable.color4bToID = function (r, g, b, a) {
|
||||
var id;
|
||||
id = (r & 255) << 0;
|
||||
id |= (g & 255) << 8;
|
||||
|
|
|
@ -62,7 +62,7 @@ class Rectangle {
|
|||
* Note that this is a comparison assuming the Rectangle was
|
||||
* initialized with Scratch-space bounds or points.
|
||||
* @param {!Rectangle} other Rectangle to check if intersecting.
|
||||
* @return {Boolean} True if this Rectangle intersects other.
|
||||
* @return {boolean} True if this Rectangle intersects other.
|
||||
*/
|
||||
intersects (other) {
|
||||
return (
|
||||
|
@ -78,7 +78,7 @@ class Rectangle {
|
|||
* Note that this is a comparison assuming the Rectangle was
|
||||
* initialized with Scratch-space bounds or points.
|
||||
* @param {!Rectangle} other Rectangle to check if fully contained.
|
||||
* @return {Boolean} True if this Rectangle fully contains other.
|
||||
* @return {boolean} True if this Rectangle fully contains other.
|
||||
*/
|
||||
contains (other) {
|
||||
return (
|
||||
|
@ -111,7 +111,7 @@ class Rectangle {
|
|||
/**
|
||||
* Push out the Rectangle to integer bounds.
|
||||
*/
|
||||
snapToInt() {
|
||||
snapToInt () {
|
||||
this.left = Math.floor(this.left);
|
||||
this.right = Math.ceil(this.right);
|
||||
this.bottom = Math.floor(this.bottom);
|
||||
|
|
|
@ -21,7 +21,7 @@ class RenderWebGL {
|
|||
* @param {int} [yTop=180] The y-coordinate of the top edge.
|
||||
* @constructor
|
||||
*/
|
||||
constructor(canvas, xLeft, xRight, yBottom, yTop) {
|
||||
constructor (canvas, xLeft, xRight, yBottom, yTop) {
|
||||
// TODO: remove?
|
||||
twgl.setDefaults({crossOrigin: true});
|
||||
|
||||
|
@ -63,9 +63,9 @@ RenderWebGL.MAX_TOUCH_SIZE = [3, 3];
|
|||
RenderWebGL.TOLERANCE_TOUCHING_COLOR = 2;
|
||||
|
||||
|
||||
/********
|
||||
* Functions called only locally: these are not available from a worker.
|
||||
********/
|
||||
/* *******
|
||||
* Functions called only locally: these are not available from a worker.
|
||||
*********/
|
||||
|
||||
/**
|
||||
* Set the physical size of the stage in device-independent pixels.
|
||||
|
@ -86,7 +86,7 @@ RenderWebGL.prototype.resize = function (pixelsWide, pixelsTall) {
|
|||
* @param {number} green The green component for the background.
|
||||
* @param {number} blue The blue component for the background.
|
||||
*/
|
||||
RenderWebGL.prototype.setBackgroundColor = function(red, green, blue) {
|
||||
RenderWebGL.prototype.setBackgroundColor = function (red, green, blue) {
|
||||
this._backgroundColor = [red, green, blue, 1];
|
||||
};
|
||||
|
||||
|
@ -130,7 +130,7 @@ RenderWebGL.prototype.createDrawable = function () {
|
|||
/**
|
||||
* Destroy a Drawable, removing it from the scene.
|
||||
* @param {int} drawableID The ID of the Drawable to remove.
|
||||
* @returns {Boolean} True iff the drawable was found and removed.
|
||||
* @returns {boolean} True iff the drawable was found and removed.
|
||||
*/
|
||||
RenderWebGL.prototype.destroyDrawable = function (drawableID) {
|
||||
var index = this._drawables.indexOf(drawableID);
|
||||
|
@ -150,24 +150,24 @@ RenderWebGL.prototype.destroyDrawable = function (drawableID) {
|
|||
* "go to back": setDrawableOrder(id, 1); (assuming stage at 0).
|
||||
* "go to front": setDrawableOrder(id, Infinity);
|
||||
* @param {int} drawableID ID of Drawable to reorder.
|
||||
* @param {Number} order New absolute order or relative order adjusment.
|
||||
* @param {Boolean=} opt_isRelative If set, `order` refers to a relative change.
|
||||
* @param {Number=} opt_min If set, order constrained to be at least `opt_min`.
|
||||
* @return {?Number} New order if changed, or null.
|
||||
* @param {number} order New absolute order or relative order adjusment.
|
||||
* @param {boolean=} optIsRelative If set, `order` refers to a relative change.
|
||||
* @param {number=} optMin If set, order constrained to be at least `optMin`.
|
||||
* @return {?number} New order if changed, or null.
|
||||
*/
|
||||
RenderWebGL.prototype.setDrawableOrder = function (
|
||||
drawableID, order, opt_isRelative, opt_min) {
|
||||
drawableID, order, optIsRelative, optMin) {
|
||||
var oldIndex = this._drawables.indexOf(drawableID);
|
||||
if (oldIndex >= 0) {
|
||||
// Remove drawable from the list.
|
||||
var drawable = this._drawables.splice(oldIndex, 1)[0];
|
||||
// Determine new index.
|
||||
var newIndex = order;
|
||||
if (opt_isRelative) {
|
||||
if (optIsRelative) {
|
||||
newIndex += oldIndex;
|
||||
}
|
||||
if (opt_min) {
|
||||
newIndex = Math.max(newIndex, opt_min);
|
||||
if (optMin) {
|
||||
newIndex = Math.max(newIndex, optMin);
|
||||
}
|
||||
newIndex = Math.max(newIndex, 0);
|
||||
// Insert at new index.
|
||||
|
@ -196,7 +196,7 @@ RenderWebGL.prototype.draw = function () {
|
|||
/**
|
||||
* Get the precise bounds for a Drawable.
|
||||
* @param {int} drawableID ID of Drawable to get bounds for.
|
||||
* @return {Object} Bounds for a tight box around the Drawable.
|
||||
* @return {object} Bounds for a tight box around the Drawable.
|
||||
*/
|
||||
RenderWebGL.prototype.getBounds = function (drawableID) {
|
||||
const drawable = Drawable.getDrawableByID(drawableID);
|
||||
|
@ -216,8 +216,8 @@ RenderWebGL.prototype.getBounds = function (drawableID) {
|
|||
context.strokeStyle = '#FF0000';
|
||||
let pr = window.devicePixelRatio;
|
||||
context.strokeRect(
|
||||
pr * (bounds.left + this._nativeSize[0]/2),
|
||||
pr * (-bounds.top + this._nativeSize[1]/2),
|
||||
pr * (bounds.left + this._nativeSize[0] / 2),
|
||||
pr * (-bounds.top + this._nativeSize[1] / 2),
|
||||
pr * (bounds.right - bounds.left),
|
||||
pr * (-bounds.bottom + bounds.top)
|
||||
);
|
||||
|
@ -240,9 +240,9 @@ RenderWebGL.prototype.getSkinSize = function (drawableID) {
|
|||
* @param {int} drawableID The ID of the Drawable to check.
|
||||
* @param {int[]} color3b Test if the Drawable is touching this color.
|
||||
* @param {int[]} [mask3b] Optionally mask the check to this part of Drawable.
|
||||
* @returns {Boolean} True iff the Drawable is touching the color.
|
||||
* @returns {boolean} True iff the Drawable is touching the color.
|
||||
*/
|
||||
RenderWebGL.prototype.isTouchingColor = function(drawableID, color3b, mask3b) {
|
||||
RenderWebGL.prototype.isTouchingColor = function (drawableID, color3b, mask3b) {
|
||||
const gl = this._gl;
|
||||
twgl.bindFramebufferInfo(gl, this._queryBufferInfo);
|
||||
|
||||
|
@ -285,7 +285,7 @@ RenderWebGL.prototype.isTouchingColor = function(drawableID, color3b, mask3b) {
|
|||
ShaderManager.DRAW_MODE.colorMask :
|
||||
ShaderManager.DRAW_MODE.silhouette,
|
||||
projection,
|
||||
undefined,
|
||||
null,
|
||||
extraUniforms);
|
||||
|
||||
gl.stencilFunc(gl.EQUAL, 1, 1);
|
||||
|
@ -294,11 +294,9 @@ RenderWebGL.prototype.isTouchingColor = function(drawableID, color3b, mask3b) {
|
|||
|
||||
this._drawThese(
|
||||
candidateIDs, ShaderManager.DRAW_MODE.default, projection,
|
||||
function (testID) {
|
||||
return testID != drawableID;
|
||||
});
|
||||
}
|
||||
finally {
|
||||
testID => testID !== drawableID
|
||||
);
|
||||
} finally {
|
||||
gl.colorMask(true, true, true, true);
|
||||
gl.disable(gl.STENCIL_TEST);
|
||||
}
|
||||
|
@ -339,9 +337,9 @@ RenderWebGL.prototype.isTouchingColor = function(drawableID, color3b, mask3b) {
|
|||
* Check if a particular Drawable is touching any in a set of Drawables.
|
||||
* @param {int} drawableID The ID of the Drawable to check.
|
||||
* @param {int[]} candidateIDs The Drawable IDs to check, otherwise all.
|
||||
* @returns {Boolean} True iff the Drawable is touching one of candidateIDs.
|
||||
* @returns {boolean} True iff the Drawable is touching one of candidateIDs.
|
||||
*/
|
||||
RenderWebGL.prototype.isTouchingDrawables = function(drawableID, candidateIDs) {
|
||||
RenderWebGL.prototype.isTouchingDrawables = function (drawableID, candidateIDs) {
|
||||
candidateIDs = candidateIDs || this._drawables;
|
||||
|
||||
const gl = this._gl;
|
||||
|
@ -383,9 +381,7 @@ RenderWebGL.prototype.isTouchingDrawables = function(drawableID, candidateIDs) {
|
|||
|
||||
this._drawThese(
|
||||
candidateIDs, ShaderManager.DRAW_MODE.silhouette, projection,
|
||||
function (testID) {
|
||||
return testID != drawableID;
|
||||
}
|
||||
testID => testID !== drawableID
|
||||
);
|
||||
} finally {
|
||||
gl.colorMask(true, true, true, true);
|
||||
|
@ -534,7 +530,7 @@ RenderWebGL.prototype._touchingBounds = function (drawableID) {
|
|||
// when you provide float width/heights to gl.viewport and projection.
|
||||
bounds.snapToInt();
|
||||
|
||||
if (bounds.width == 0 || bounds.height == 0) {
|
||||
if (bounds.width === 0 || bounds.height === 0) {
|
||||
// No space to query.
|
||||
return null;
|
||||
}
|
||||
|
@ -544,9 +540,9 @@ RenderWebGL.prototype._touchingBounds = function (drawableID) {
|
|||
/**
|
||||
* Filter a list of candidates for a touching query into only those that
|
||||
* could possibly intersect the given bounds.
|
||||
* @param {int} drawableID ID for drawable of query.
|
||||
* @param {Array.<int>} candidateIDs Candidates for touching query.
|
||||
* @param {Rectangle} Bounds to limit candidates to.
|
||||
* @param {int} drawableID - ID for drawable of query.
|
||||
* @param {Array.<int>} candidateIDs - Candidates for touching query.
|
||||
* @param {Rectangle} bounds - Bounds to limit candidates to.
|
||||
* @return {?Array.<int>} Filtered candidateIDs, or null if none.
|
||||
*/
|
||||
RenderWebGL.prototype._filterCandidatesTouching = function (
|
||||
|
@ -554,14 +550,14 @@ RenderWebGL.prototype._filterCandidatesTouching = function (
|
|||
// Filter candidates by rough bounding box intersection.
|
||||
// Do this before _drawThese, so we can prevent any GL operations
|
||||
// and readback by returning early.
|
||||
candidateIDs = candidateIDs.filter(function (testID) {
|
||||
if (testID == drawableID) return false;
|
||||
candidateIDs = candidateIDs.filter(testID => {
|
||||
if (testID === drawableID) return false;
|
||||
// Only draw items which could possibly overlap target Drawable.
|
||||
let candidate = Drawable.getDrawableByID(testID);
|
||||
let candidateBounds = candidate.getFastBounds();
|
||||
return bounds.intersects(candidateBounds);
|
||||
});
|
||||
if (candidateIDs.length == 0) {
|
||||
if (candidateIDs.length === 0) {
|
||||
// No possible intersections based on bounding boxes.
|
||||
return null;
|
||||
}
|
||||
|
@ -571,7 +567,7 @@ RenderWebGL.prototype._filterCandidatesTouching = function (
|
|||
/**
|
||||
* Update the position, direction, scale, or effect properties of this Drawable.
|
||||
* @param {int} drawableID The ID of the Drawable to update.
|
||||
* @param {Object.<string,*>} properties The new property values to set.
|
||||
* @param {object.<string,*>} properties The new property values to set.
|
||||
*/
|
||||
RenderWebGL.prototype.updateDrawableProperties = function (
|
||||
drawableID, properties) {
|
||||
|
@ -579,9 +575,9 @@ RenderWebGL.prototype.updateDrawableProperties = function (
|
|||
drawable.updateProperties(properties);
|
||||
};
|
||||
|
||||
/********
|
||||
* Truly internal functions: these support the functions above.
|
||||
********/
|
||||
/* ********
|
||||
* Truly internal functions: these support the functions above.
|
||||
********/
|
||||
|
||||
/**
|
||||
* Build geometry (vertex and index) buffers.
|
||||
|
@ -625,8 +621,8 @@ RenderWebGL.prototype._createGeometry = function () {
|
|||
RenderWebGL.prototype._createQueryBuffers = function () {
|
||||
var gl = this._gl;
|
||||
var attachments = [
|
||||
{format: gl.RGBA },
|
||||
{format: gl.DEPTH_STENCIL }
|
||||
{format: gl.RGBA},
|
||||
{format: gl.DEPTH_STENCIL}
|
||||
];
|
||||
|
||||
this._pickBufferInfo = twgl.createFramebufferInfo(
|
||||
|
@ -648,7 +644,7 @@ RenderWebGL.prototype._createQueryBuffers = function () {
|
|||
* @param {Object.<string,*>} [extraUniforms] Extra uniforms for the shaders.
|
||||
* @private
|
||||
*/
|
||||
RenderWebGL.prototype._drawThese = function(
|
||||
RenderWebGL.prototype._drawThese = function (
|
||||
drawables, drawMode, projection, filter, extraUniforms) {
|
||||
|
||||
var gl = this._gl;
|
||||
|
@ -669,7 +665,7 @@ RenderWebGL.prototype._drawThese = function(
|
|||
|
||||
var effectBits = drawable.getEnabledEffects();
|
||||
var newShader = this._shaderManager.getShader(drawMode, effectBits);
|
||||
if (currentShader != newShader) {
|
||||
if (currentShader !== newShader) {
|
||||
currentShader = newShader;
|
||||
gl.useProgram(currentShader.program);
|
||||
twgl.setBuffersAndAttributes(gl, currentShader, this._bufferInfo);
|
||||
|
@ -693,14 +689,14 @@ RenderWebGL.prototype._drawThese = function(
|
|||
* To do this, draw the Drawable unrotated, unscaled, and untranslated.
|
||||
* Read back the pixels and find all boundary points.
|
||||
* Finally, apply a convex hull algorithm to simplify the set.
|
||||
* @param {int} drawablesID The Drawable IDs calculate convex hull for.
|
||||
* @param {int} drawableID The Drawable IDs calculate convex hull for.
|
||||
* @return {Array.<Array.<number>>} points Convex hull points, as [[x, y], ...]
|
||||
*/
|
||||
RenderWebGL.prototype._getConvexHullPointsForDrawable = function (drawableID) {
|
||||
const drawable = Drawable.getDrawableByID(drawableID);
|
||||
const [width, height] = drawable._uniforms.u_skinSize;
|
||||
// No points in the hull if invisible or size is 0.
|
||||
if (!drawable.getVisible() || width == 0 || height == 0) {
|
||||
if (!drawable.getVisible() || width === 0 || height === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -728,7 +724,7 @@ RenderWebGL.prototype._getConvexHullPointsForDrawable = function (drawableID) {
|
|||
this._drawThese([drawableID],
|
||||
ShaderManager.DRAW_MODE.silhouette,
|
||||
projection,
|
||||
undefined,
|
||||
null,
|
||||
{u_modelMatrix: modelMatrix}
|
||||
);
|
||||
|
||||
|
@ -744,7 +740,7 @@ RenderWebGL.prototype._getConvexHullPointsForDrawable = function (drawableID) {
|
|||
* Helper method to look up a pixel.
|
||||
* @param {int} x X coordinate of the pixel in `pixels`.
|
||||
* @param {int} y Y coordinate of the pixel in `pixels`.
|
||||
* @return Known ID at that pixel, or Drawable.NONE.
|
||||
* @return {int} Known ID at that pixel, or Drawable.NONE.
|
||||
*/
|
||||
const _getPixel = function (x, y) {
|
||||
var pixelBase = ((width * y) + x) * 4;
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
var twgl = require('twgl.js');
|
||||
|
||||
const vertexShaderText = require('./shaders/sprite.vert');
|
||||
const fragmentShaderText = require('./shaders/sprite.frag');
|
||||
|
||||
|
||||
class ShaderManager {
|
||||
constructor(gl) {
|
||||
constructor (gl) {
|
||||
this._gl = gl;
|
||||
|
||||
/**
|
||||
|
@ -33,35 +37,35 @@ module.exports = ShaderManager;
|
|||
ShaderManager.EFFECT_INFO = {
|
||||
color: {
|
||||
mask: 1 << 0,
|
||||
converter: function(x) {
|
||||
converter: function (x) {
|
||||
return (x / 200) % 1;
|
||||
},
|
||||
shapeChanges: false
|
||||
},
|
||||
fisheye: {
|
||||
mask: 1 << 1,
|
||||
converter: function(x) {
|
||||
converter: function (x) {
|
||||
return Math.max(0, (x + 100) / 100);
|
||||
},
|
||||
shapeChanges: true
|
||||
},
|
||||
whirl: {
|
||||
mask: 1 << 2,
|
||||
converter: function(x) {
|
||||
converter: function (x) {
|
||||
return -x * Math.PI / 180;
|
||||
},
|
||||
shapeChanges: true
|
||||
},
|
||||
pixelate: {
|
||||
mask: 1 << 3,
|
||||
converter: function(x) {
|
||||
converter: function (x) {
|
||||
return Math.abs(x) / 10;
|
||||
},
|
||||
shapeChanges: true
|
||||
},
|
||||
mosaic: {
|
||||
mask: 1 << 4,
|
||||
converter: function(x) {
|
||||
converter: function (x) {
|
||||
x = Math.round((Math.abs(x) + 10) / 10);
|
||||
// TODO: cap by Math.min(srcWidth, srcHeight)
|
||||
return Math.max(1, Math.min(x, 512));
|
||||
|
@ -70,14 +74,14 @@ ShaderManager.EFFECT_INFO = {
|
|||
},
|
||||
brightness: {
|
||||
mask: 1 << 5,
|
||||
converter: function(x) {
|
||||
converter: function (x) {
|
||||
return Math.max(-100, Math.min(x, 100)) / 100;
|
||||
},
|
||||
shapeChanges: false
|
||||
},
|
||||
ghost: {
|
||||
mask: 1 << 6,
|
||||
converter: function(x) {
|
||||
converter: function (x) {
|
||||
return 1 - Math.max(0, Math.min(x, 100)) / 100;
|
||||
},
|
||||
shapeChanges: false
|
||||
|
@ -121,7 +125,7 @@ ShaderManager.DRAW_MODE = {
|
|||
*/
|
||||
ShaderManager.prototype.getShader = function (drawMode, effectBits) {
|
||||
var cache = this._shaderCache[drawMode];
|
||||
if (drawMode == ShaderManager.DRAW_MODE.silhouette) {
|
||||
if (drawMode === ShaderManager.DRAW_MODE.silhouette) {
|
||||
// Silhouette mode isn't affected by these effects.
|
||||
effectBits &= ~(
|
||||
ShaderManager.EFFECT_INFO.color.mask |
|
||||
|
@ -146,17 +150,17 @@ ShaderManager.prototype._buildShader = function (drawMode, effectBits) {
|
|||
var numEffects = ShaderManager.EFFECTS.length;
|
||||
|
||||
var defines = [
|
||||
'#define DRAW_MODE_' + drawMode
|
||||
`#define DRAW_MODE_${drawMode}`
|
||||
];
|
||||
for (var index = 0; index < numEffects; ++index) {
|
||||
if ((effectBits & (1 << index)) != 0) {
|
||||
defines.push('#define ENABLE_' + ShaderManager.EFFECTS[index]);
|
||||
if ((effectBits & (1 << index)) !== 0) {
|
||||
defines.push(`#define ENABLE_${ShaderManager.EFFECTS[index]}`);
|
||||
}
|
||||
}
|
||||
|
||||
var definesText = defines.join('\n') + '\n';
|
||||
var vsFullText = definesText + require('./shaders/sprite.vert');
|
||||
var fsFullText = definesText + require('./shaders/sprite.frag');
|
||||
var definesText = `${defines.join('\n')}\n`;
|
||||
var vsFullText = definesText + vertexShaderText;
|
||||
var fsFullText = definesText + fragmentShaderText;
|
||||
|
||||
return twgl.createProgramInfo(this._gl, [vsFullText, fsFullText]);
|
||||
};
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
// Synchronously load TTF fonts.
|
||||
// First, have Webpack load their data as Base 64 strings.
|
||||
/* eslint-disable global-require */
|
||||
let FONTS = {
|
||||
'Donegal': require('base64!scratch-render-fonts/DonegalOne-Regular.ttf'),
|
||||
'Gloria': require('base64!scratch-render-fonts/GloriaHallelujah.ttf'),
|
||||
'Mystery': require('base64!scratch-render-fonts/MysteryQuest-Regular.ttf'),
|
||||
'Marker': require('base64!scratch-render-fonts/PermanentMarker.ttf'),
|
||||
'Scratch': require('base64!scratch-render-fonts/Scratch.ttf')
|
||||
Donegal: require('base64!scratch-render-fonts/DonegalOne-Regular.ttf'),
|
||||
Gloria: require('base64!scratch-render-fonts/GloriaHallelujah.ttf'),
|
||||
Mystery: require('base64!scratch-render-fonts/MysteryQuest-Regular.ttf'),
|
||||
Marker: require('base64!scratch-render-fonts/PermanentMarker.ttf'),
|
||||
Scratch: require('base64!scratch-render-fonts/Scratch.ttf')
|
||||
};
|
||||
/* eslint-enable global-require */
|
||||
|
||||
// For each Base 64 string,
|
||||
// 1. Replace each with a usable @font-face tag that points to a Data URI.
|
||||
|
@ -16,9 +18,8 @@ let documentStyleTag = document.createElement('style');
|
|||
documentStyleTag.id = 'scratch-font-styles';
|
||||
for (var fontName in FONTS) {
|
||||
var fontData = FONTS[fontName];
|
||||
FONTS[fontName] = '@font-face {font-family: "' + fontName + '";' +
|
||||
'src: url("data:application/x-font-ttf;charset=utf-8;base64,' +
|
||||
fontData + '");}';
|
||||
FONTS[fontName] = '@font-face {' +
|
||||
`font-family: "${fontName}";src: url("data:application/x-font-ttf;charset=utf-8;base64,${fontData}");}`;
|
||||
documentStyleTag.textContent += FONTS[fontName];
|
||||
}
|
||||
document.body.insertBefore(documentStyleTag, document.body.firstChild);
|
||||
|
@ -74,8 +75,8 @@ class SvgRenderer {
|
|||
_transformText () {
|
||||
// Collect all text elements into a list.
|
||||
let textElements = [];
|
||||
let collectText = (domElement) => {
|
||||
if (domElement.localName == 'text') {
|
||||
let collectText = domElement => {
|
||||
if (domElement.localName === 'text') {
|
||||
textElements.push(domElement);
|
||||
}
|
||||
for (let i = 0; i < domElement.children.length; i++) {
|
||||
|
@ -238,7 +239,7 @@ class SvgRenderer {
|
|||
}
|
||||
};
|
||||
let svgText = this._toString();
|
||||
img.src = 'data:image/svg+xml;utf8,' + encodeURIComponent(svgText);
|
||||
img.src = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,7 +247,7 @@ class SvgRenderer {
|
|||
* @param {string} tagName Tag name for the element.
|
||||
* @return {!DOMElement} Element created.
|
||||
*/
|
||||
_createSVGElement(tagName) {
|
||||
_createSVGElement (tagName) {
|
||||
return document.createElementNS(
|
||||
'http://www.w3.org/2000/svg', tagName
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue