Use eslint-config-scratch, fix linting errors

This commit is contained in:
Christopher Willis-Ford 2016-12-12 10:18:21 -08:00
parent 47b46fb1aa
commit 5db860efed
11 changed files with 149 additions and 160 deletions

View file

@ -1,5 +1,3 @@
dist.js
dist/*
node_modules/*
playground/*
render.js
render.min.js

View file

@ -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
View file

@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ['scratch', 'scratch/node']
};

2
.gitattributes vendored
View file

@ -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

View file

@ -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
View 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?
}
};

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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]);
};

View file

@ -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
);