mirror of
https://github.com/scratchfoundation/scratch-render.git
synced 2025-06-25 22:41:45 -04:00
Generate docs from src, publish to gh-pages
Fix any broken JSDoc syntax. Unfortunately there is no way to document tuples like `{[int, int]}` for a `[width, height]` array. We could possibly fix this and make the code more readable with `{width: number, height: number}` instead of tuples. Remove single `@fileoverview` from Rectangle.js, since it was the only file with one and was weird to have that one module show up on the docs home page. Add a `docs` script to `package.json`, run it from `npm test`, so invalid docs will cause tests to fail (eventually we may want to start using eslint-plugin-jsdoc to catch these errors with the linter alone).
This commit is contained in:
parent
b7d5610b23
commit
3c6511d94e
13 changed files with 159 additions and 85 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -16,3 +16,4 @@ npm-*
|
|||
/dist
|
||||
/playground/scratch-render.js
|
||||
/playground/scratch-render.js.map
|
||||
/playground/docs
|
||||
|
|
20
.jsdoc.json
Normal file
20
.jsdoc.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"plugins": ["plugins/markdown"],
|
||||
"templates": {
|
||||
"default": {
|
||||
"includeDate": false,
|
||||
"outputSourceFiles": false
|
||||
}
|
||||
},
|
||||
"source": {
|
||||
"include": ["src"]
|
||||
},
|
||||
"opts": {
|
||||
"destination": "playground/docs",
|
||||
"pedantic": true,
|
||||
"private": true,
|
||||
"readme": "README.md",
|
||||
"recurse": true,
|
||||
"template": "node_modules/docdash"
|
||||
}
|
||||
}
|
15
package.json
15
package.json
|
@ -11,14 +11,15 @@
|
|||
},
|
||||
"main": "./dist/node/scratch-render.js",
|
||||
"scripts": {
|
||||
"build": "./node_modules/.bin/webpack --progress --colors",
|
||||
"lint": "./node_modules/.bin/eslint .",
|
||||
"build": "webpack --progress --colors",
|
||||
"docs": "jsdoc -c .jsdoc.json",
|
||||
"lint": "eslint .",
|
||||
"prepublish": "npm run build",
|
||||
"prepublish-watch": "npm run watch",
|
||||
"start": "./node_modules/.bin/webpack-dev-server",
|
||||
"test": "npm run lint",
|
||||
"version": "./node_modules/.bin/json -f package.json -I -e \"this.repository.sha = '$(git log -n1 --pretty=format:%H)'\"",
|
||||
"watch": "./node_modules/.bin/webpack --progress --colors --watch --watch-poll"
|
||||
"start": "webpack-dev-server",
|
||||
"test": "npm run lint && npm run docs",
|
||||
"version": "json -f package.json -I -e \"this.repository.sha = '$(git log -n1 --pretty=format:%H)'\"",
|
||||
"watch": "webpack --progress --colors --watch --watch-poll"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "6.22.1",
|
||||
|
@ -27,10 +28,12 @@
|
|||
"babel-polyfill": "6.22.0",
|
||||
"babel-preset-es2015": "6.22.0",
|
||||
"base64-loader": "1.0.0",
|
||||
"docdash": "0.4.0",
|
||||
"eslint": "3.16.0",
|
||||
"eslint-config-scratch": "3.1.0",
|
||||
"gh-pages": "0.12.0",
|
||||
"hull.js": "0.2.10",
|
||||
"jsdoc": "3.4.3",
|
||||
"json": "9.0.4",
|
||||
"json-loader": "0.5.4",
|
||||
"lodash.defaultsdeep": "4.6.0",
|
||||
|
|
|
@ -5,6 +5,7 @@ const Skin = require('./Skin');
|
|||
class BitmapSkin extends Skin {
|
||||
/**
|
||||
* Create a new Bitmap Skin.
|
||||
* @extends Skin
|
||||
* @param {!int} id - The ID for this Skin.
|
||||
* @param {!RenderWebGL} renderer - The renderer which will use this skin.
|
||||
*/
|
||||
|
@ -20,7 +21,7 @@ class BitmapSkin extends Skin {
|
|||
/** @type {WebGLTexture} */
|
||||
this._texture = null;
|
||||
|
||||
/** @type {[int, int]} */
|
||||
/** @type {Array<int>} */
|
||||
this._textureSize = [0, 0];
|
||||
}
|
||||
|
||||
|
@ -36,14 +37,14 @@ class BitmapSkin extends Skin {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return {[number,number]} the "native" size, in texels, of this skin.
|
||||
* @return {Array<number>} the "native" size, in texels, of this skin.
|
||||
*/
|
||||
get size () {
|
||||
return [this._textureSize[0] / this._costumeResolution, this._textureSize[1] / this._costumeResolution];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {[number,number]} scale - The scaling factors to be used.
|
||||
* @param {Array<number>} scale - The scaling factors to be used.
|
||||
* @return {WebGLTexture} The GL texture representation of this skin when drawing at the given scale.
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
@ -55,8 +56,9 @@ class BitmapSkin extends Skin {
|
|||
* Set the contents of this skin to a snapshot of the provided bitmap data.
|
||||
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} bitmapData - new contents for this skin.
|
||||
* @param {int} [costumeResolution=1] - The resolution to use for this bitmap.
|
||||
* @param {number[]=} rotationCenter - Optional rotation center for the bitmap. If not supplied, it will be
|
||||
* @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
|
||||
*/
|
||||
setBitmap (bitmapData, costumeResolution, rotationCenter) {
|
||||
const gl = this._renderer.gl;
|
||||
|
@ -68,7 +70,8 @@ class BitmapSkin extends Skin {
|
|||
const textureOptions = {
|
||||
auto: true,
|
||||
mag: gl.NEAREST,
|
||||
min: gl.NEAREST, // TODO: mipmaps, linear (except pixelate)
|
||||
/** @todo mipmaps, linear (except pixelate) */
|
||||
min: gl.NEAREST,
|
||||
wrap: gl.CLAMP_TO_EDGE,
|
||||
src: bitmapData
|
||||
};
|
||||
|
@ -88,7 +91,7 @@ class BitmapSkin extends Skin {
|
|||
|
||||
/**
|
||||
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} bitmapData - bitmap data to inspect.
|
||||
* @returns {[int,int]} the width and height of the bitmap data, in pixels.
|
||||
* @returns {Array<int>} the width and height of the bitmap data, in pixels.
|
||||
* @private
|
||||
*/
|
||||
static _getBitmapSize (bitmapData) {
|
||||
|
|
|
@ -9,7 +9,7 @@ const Skin = require('./Skin');
|
|||
class Drawable {
|
||||
/**
|
||||
* An object which can be drawn by the renderer.
|
||||
* TODO: double-buffer all rendering state (position, skin, effects, etc.)
|
||||
* @todo double-buffer all rendering state (position, skin, effects, etc.)
|
||||
* @param {!int} id - This Drawable's unique ID.
|
||||
* @constructor
|
||||
*/
|
||||
|
@ -32,7 +32,7 @@ class Drawable {
|
|||
|
||||
/**
|
||||
* The color to use in the silhouette draw mode.
|
||||
* @type {number[]}
|
||||
* @type {Array<number>}
|
||||
*/
|
||||
u_silhouetteColor: Drawable.color4fFromID(this._id)
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ class Drawable {
|
|||
this._visible = true;
|
||||
this._effectBits = 0;
|
||||
|
||||
// TODO: move convex hull functionality, maybe bounds functionality overall, to Skin classes
|
||||
/** @todo move convex hull functionality, maybe bounds functionality overall, to Skin classes */
|
||||
this._convexHullPoints = null;
|
||||
this._convexHullDirty = true;
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Drawable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @returns {[number,number]} the current scaling percentages applied to this Drawable. [100,100] is normal size.
|
||||
* @returns {Array<number>} the current scaling percentages applied to this Drawable. [100,100] is normal size.
|
||||
*/
|
||||
get scale () {
|
||||
return [this._scale[0], this._scale[1]];
|
||||
|
@ -232,7 +232,7 @@ class Drawable {
|
|||
|
||||
/**
|
||||
* Set the convex hull points for the Drawable.
|
||||
* @param {Array.<Array.<number>>} points Convex hull points, as [[x, y], ...]
|
||||
* @param {Array<Array<number>>} points Convex hull points, as [[x, y], ...]
|
||||
*/
|
||||
setConvexHullPoints (points) {
|
||||
this._convexHullPoints = points;
|
||||
|
@ -326,7 +326,7 @@ class Drawable {
|
|||
* Calculate a color to represent the given ID number. At least one component of
|
||||
* the resulting color will be non-zero if the ID is not RenderConstants.ID_NONE.
|
||||
* @param {int} id The ID to convert.
|
||||
* @returns {number[]} An array of [r,g,b,a], each component in the range [0,1].
|
||||
* @returns {Array<number>} An array of [r,g,b,a], each component in the range [0,1].
|
||||
*/
|
||||
static color4fFromID (id) {
|
||||
id -= RenderConstants.ID_NONE;
|
||||
|
|
|
@ -6,14 +6,17 @@ const Skin = require('./Skin');
|
|||
|
||||
/**
|
||||
* Attributes to use when drawing with the pen
|
||||
* @typedef {object} PenAttributes
|
||||
* @typedef {object} PenSkin#PenAttributes
|
||||
* @property {number} [diameter] - The size (diameter) of the pen.
|
||||
* @property {number[]} [color4f] - The pen color as an array of [r,g,b,a], each component in the range [0,1].
|
||||
* @property {Array<number>} [color4f] - The pen color as an array of [r,g,b,a], each component in the range [0,1].
|
||||
*/
|
||||
|
||||
/**
|
||||
* The pen attributes to use when unspecified.
|
||||
* @type {PenAttributes}
|
||||
* @type {PenSkin#PenAttributes}
|
||||
* @memberof PenSkin
|
||||
* @private
|
||||
* @const
|
||||
*/
|
||||
const DefaultPenAttributes = {
|
||||
color4f: [0, 0, 1, 1],
|
||||
|
@ -26,11 +29,16 @@ class PenSkin extends Skin {
|
|||
* Create a Skin which implements a Scratch pen layer.
|
||||
* @param {int} id - The unique ID for this Skin.
|
||||
* @param {RenderWebGL} renderer - The renderer which will use this Skin.
|
||||
* @extends Skin
|
||||
* @listens RenderWebGL#event:NativeSizeChanged
|
||||
*/
|
||||
constructor (id, renderer) {
|
||||
super(id);
|
||||
|
||||
/** @type {RenderWebGL} */
|
||||
/**
|
||||
* @private
|
||||
* @type {RenderWebGL}
|
||||
*/
|
||||
this._renderer = renderer;
|
||||
|
||||
/** @type {HTMLCanvasElement} */
|
||||
|
@ -59,7 +67,7 @@ class PenSkin extends Skin {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return {[number,number]} the "native" size, in texels, of this skin.
|
||||
* @return {Array<number>} the "native" size, in texels, of this skin. [width, height]
|
||||
*/
|
||||
get size () {
|
||||
return [this._canvas.width, this._canvas.height];
|
||||
|
@ -143,7 +151,7 @@ class PenSkin extends Skin {
|
|||
|
||||
/**
|
||||
* Set the size of the pen canvas.
|
||||
* @param {[int,int]} canvasSize - the new width and height for the canvas.
|
||||
* @param {Array<int>} canvasSize - the new width and height for the canvas.
|
||||
* @private
|
||||
*/
|
||||
_setCanvasSize (canvasSize) {
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
/**
|
||||
* @fileoverview
|
||||
* A utility for creating and comparing axis-aligned rectangles.
|
||||
*/
|
||||
|
||||
class Rectangle {
|
||||
/**
|
||||
* A utility for creating and comparing axis-aligned rectangles.
|
||||
* Rectangles are always initialized to the "largest possible rectangle";
|
||||
* use one of the init* methods below to set up a particular rectangle.
|
||||
* @constructor
|
||||
|
@ -32,7 +28,7 @@ class Rectangle {
|
|||
|
||||
/**
|
||||
* Initialize a Rectangle to the minimum AABB around a set of points.
|
||||
* @param {Array.<Array.<number>>} points Array of [x, y] points.
|
||||
* @param {Array<Array<number>>} points Array of [x, y] points.
|
||||
*/
|
||||
initFromPointsAABB (points) {
|
||||
this.left = Infinity;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/** @module RenderConstants */
|
||||
const DEFAULT_SKIN = {
|
||||
squirrel: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/7e24c99c1b853e52f8e7f9004416fa34.png/get/',
|
||||
bus: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/66895930177178ea01d9e610917f8acf.png/get/',
|
||||
|
@ -7,29 +8,40 @@ const DEFAULT_SKIN = {
|
|||
|
||||
/**
|
||||
* Various constants meant for use throughout the renderer.
|
||||
* @type {object}
|
||||
* @enum
|
||||
*/
|
||||
module.exports = {
|
||||
/**
|
||||
* The ID value to use for "no item" or when an object has been disposed.
|
||||
* @type {int}
|
||||
* @const {int}
|
||||
*/
|
||||
ID_NONE: -1,
|
||||
|
||||
/**
|
||||
* The URL to use as the default skin for a Drawable.
|
||||
* TODO: Remove this in favor of falling back on a built-in skin.
|
||||
* @type {string}
|
||||
* @todo Remove this in favor of falling back on a built-in skin.
|
||||
* @const {string}
|
||||
*/
|
||||
DEFAULT_SKIN: DEFAULT_SKIN,
|
||||
|
||||
/**
|
||||
* Optimize for fewer than this number of Drawables sharing the same Skin.
|
||||
* Going above this may cause middleware warnings or a performance penalty but should otherwise behave correctly.
|
||||
* @const {int}
|
||||
*/
|
||||
SKIN_SHARE_SOFT_LIMIT: 300,
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
Events: {
|
||||
/**
|
||||
* NativeSizeChanged event
|
||||
*
|
||||
* @event RenderWebGL#event:NativeSizeChanged
|
||||
* @type {object}
|
||||
* @property {Array<int>} newSize - the new size of the renderer
|
||||
*/
|
||||
NativeSizeChanged: 'NativeSizeChanged'
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,15 +12,16 @@ const ShaderManager = require('./ShaderManager');
|
|||
const SVGSkin = require('./SVGSkin');
|
||||
|
||||
/**
|
||||
* @callback idFilterFunc
|
||||
* @callback RenderWebGL#idFilterFunc
|
||||
* @param {int} drawableID The ID to filter.
|
||||
* @return {bool} True if the ID passes the filter, otherwise false.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maximum touch size for a picking check.
|
||||
* TODO: Figure out a reasonable max size. Maybe this should be configurable?
|
||||
* @type {int[]}
|
||||
* @todo Figure out a reasonable max size. Maybe this should be configurable?
|
||||
* @type {Array<int>}
|
||||
* @memberof RenderWebGL
|
||||
*/
|
||||
const MAX_TOUCH_SIZE = [3, 3];
|
||||
|
||||
|
@ -28,7 +29,9 @@ const MAX_TOUCH_SIZE = [3, 3];
|
|||
* "touching {color}?" or "{color} touching {color}?" tests will be true if the
|
||||
* target is touching a color whose components are each within this tolerance of
|
||||
* the corresponding component of the query color.
|
||||
* @type {int} between 0 (exact matches only) and 255 (match anything).
|
||||
* between 0 (exact matches only) and 255 (match anything).
|
||||
* @type {int}
|
||||
* @memberof RenderWebGL
|
||||
*/
|
||||
const TOLERANCE_TOUCHING_COLOR = 2;
|
||||
|
||||
|
@ -40,14 +43,15 @@ class RenderWebGL extends EventEmitter {
|
|||
* The stage's "native" size will be calculated from the these coordinates.
|
||||
* For example, the defaults result in a native size of 480x360.
|
||||
* Queries such as "touching color?" will always execute at the native size.
|
||||
* @see setStageSize
|
||||
* @see resize
|
||||
* @see RenderWebGL#setStageSize
|
||||
* @see RenderWebGL#resize
|
||||
* @param {canvas} canvas The canvas to draw onto.
|
||||
* @param {int} [xLeft=-240] The x-coordinate of the left edge.
|
||||
* @param {int} [xRight=240] The x-coordinate of the right edge.
|
||||
* @param {int} [yBottom=-180] The y-coordinate of the bottom edge.
|
||||
* @param {int} [yTop=180] The y-coordinate of the top edge.
|
||||
* @constructor
|
||||
* @listens RenderWebGL#event:NativeSizeChanged
|
||||
*/
|
||||
constructor (canvas, xLeft, xRight, yBottom, yTop) {
|
||||
super();
|
||||
|
@ -58,7 +62,7 @@ class RenderWebGL extends EventEmitter {
|
|||
/** @type {Skin[]} */
|
||||
this._allSkins = [];
|
||||
|
||||
/** @type {int[]} */
|
||||
/** @type {Array<int>} */
|
||||
this._drawList = [];
|
||||
|
||||
/** @type {WebGLRenderingContext} */
|
||||
|
@ -76,6 +80,7 @@ class RenderWebGL extends EventEmitter {
|
|||
/** @type {Object.<string,int>} */
|
||||
this._skinUrlMap = {};
|
||||
|
||||
/** @type {ShaderManager} */
|
||||
this._shaderManager = new ShaderManager(gl);
|
||||
|
||||
/** @type {HTMLCanvasElement} */
|
||||
|
@ -90,7 +95,8 @@ class RenderWebGL extends EventEmitter {
|
|||
this.resize(this._nativeSize[0], this._nativeSize[1]);
|
||||
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.enable(gl.BLEND); // TODO: disable when no partial transparency?
|
||||
/** @todo disable when no partial transparency? */
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE);
|
||||
}
|
||||
|
||||
|
@ -153,7 +159,7 @@ class RenderWebGL extends EventEmitter {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return {[int,int]} the "native" size of the stage, which is used for pen, query renders, etc.
|
||||
* @return {Array<int>} the "native" size of the stage, which is used for pen, query renders, etc.
|
||||
*/
|
||||
getNativeSize () {
|
||||
return [this._nativeSize[0], this._nativeSize[1]];
|
||||
|
@ -164,6 +170,7 @@ class RenderWebGL extends EventEmitter {
|
|||
* @param {int} width - the new width to set.
|
||||
* @param {int} height - the new height to set.
|
||||
* @private
|
||||
* @fires RenderWebGL#event:NativeSizeChanged
|
||||
*/
|
||||
_setNativeSize (width, height) {
|
||||
this._nativeSize = [width, height];
|
||||
|
@ -176,8 +183,8 @@ class RenderWebGL extends EventEmitter {
|
|||
* Use `createBitmapSkin` or `createSVGSkin` instead.
|
||||
* @param {!string} skinUrl The URL of the skin.
|
||||
* @param {!int} [costumeResolution] Optional: resolution for the skin. Ignored unless creating a new Bitmap skin.
|
||||
* @param {number[]=} rotationCenter Optional: rotation center of the skin. If not supplied, the center of the skin
|
||||
* will be used.
|
||||
* @param {?Array<number>} rotationCenter Optional: rotation center of the skin. If not supplied, the center of the
|
||||
* skin will be used.
|
||||
* @returns {!int} The ID of the Skin.
|
||||
* @deprecated
|
||||
*/
|
||||
|
@ -238,7 +245,8 @@ class RenderWebGL extends EventEmitter {
|
|||
* Create a new bitmap skin from a snapshot of the provided bitmap data.
|
||||
* @param {ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} bitmapData - new contents for this skin.
|
||||
* @param {!int} [costumeResolution=1] - The resolution to use for this bitmap.
|
||||
* @param {number[]=} rotationCenter Optional: rotation center of the skin. If not supplied, the center of the skin
|
||||
* @param {?Array<number>} rotationCenter Optional: rotation center of the skin. If not supplied, the center of the
|
||||
* skin will be used
|
||||
* @returns {!int} the ID for the new skin.
|
||||
*/
|
||||
createBitmapSkin (bitmapData, costumeResolution, rotationCenter) {
|
||||
|
@ -252,7 +260,8 @@ class RenderWebGL extends EventEmitter {
|
|||
/**
|
||||
* Create a new SVG skin.
|
||||
* @param {!string} svgData - new SVG to use.
|
||||
* @param {number[]=} rotationCenter Optional: rotation center of the skin. If not supplied, the center of the skin
|
||||
* @param {?Array<number>} rotationCenter Optional: rotation center of the skin. If not supplied, the center of the
|
||||
* skin will be used
|
||||
* @returns {!int} the ID for the new skin.
|
||||
*/
|
||||
createSVGSkin (svgData, rotationCenter) {
|
||||
|
@ -398,7 +407,7 @@ class RenderWebGL extends EventEmitter {
|
|||
/**
|
||||
* Get the current skin (costume) size of a Drawable.
|
||||
* @param {int} drawableID The ID of the Drawable to measure.
|
||||
* @return {Array.<number>} Skin size, width and height.
|
||||
* @return {Array<number>} Skin size, width and height.
|
||||
*/
|
||||
getSkinSize (drawableID) {
|
||||
const drawable = this._allDrawables[drawableID];
|
||||
|
@ -408,8 +417,8 @@ class RenderWebGL extends EventEmitter {
|
|||
/**
|
||||
* Check if a particular Drawable is touching a particular color.
|
||||
* @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.
|
||||
* @param {Array<int>} color3b Test if the Drawable is touching this color.
|
||||
* @param {Array<int>} [mask3b] Optionally mask the check to this part of Drawable.
|
||||
* @returns {boolean} True iff the Drawable is touching the color.
|
||||
*/
|
||||
isTouchingColor (drawableID, color3b, mask3b) {
|
||||
|
@ -496,7 +505,7 @@ class RenderWebGL extends EventEmitter {
|
|||
/**
|
||||
* 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.
|
||||
* @param {Array<int>} candidateIDs The Drawable IDs to check, otherwise all.
|
||||
* @returns {boolean} True iff the Drawable is touching one of candidateIDs.
|
||||
*/
|
||||
isTouchingDrawables (drawableID, candidateIDs) {
|
||||
|
@ -574,7 +583,7 @@ class RenderWebGL extends EventEmitter {
|
|||
* @param {int} centerY The client y coordinate of the picking location.
|
||||
* @param {int} touchWidth The client width of the touch event (optional).
|
||||
* @param {int} touchHeight The client height of the touch event (optional).
|
||||
* @param {int[]} candidateIDs The Drawable IDs to pick from, otherwise all.
|
||||
* @param {Array<int>} candidateIDs The Drawable IDs to pick from, otherwise all.
|
||||
* @returns {int} The ID of the topmost Drawable under the picking location, or
|
||||
* RenderConstants.ID_NONE if there is no Drawable at that location.
|
||||
*/
|
||||
|
@ -735,7 +744,7 @@ class RenderWebGL extends EventEmitter {
|
|||
_touchingBounds (drawableID) {
|
||||
const drawable = this._allDrawables[drawableID];
|
||||
|
||||
// TODO: remove this once URL-based skin setting is removed.
|
||||
/** @todo remove this once URL-based skin setting is removed. */
|
||||
if (!drawable.skin || !drawable.skin.getTexture([100, 100])) return null;
|
||||
|
||||
const bounds = drawable.getFastBounds();
|
||||
|
@ -758,9 +767,9 @@ class RenderWebGL extends EventEmitter {
|
|||
* 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 {Array<int>} candidateIDs - Candidates for touching query.
|
||||
* @param {Rectangle} bounds - Bounds to limit candidates to.
|
||||
* @return {?Array.<int>} Filtered candidateIDs, or null if none.
|
||||
* @return {?Array<int>} Filtered candidateIDs, or null if none.
|
||||
*/
|
||||
_filterCandidatesTouching (drawableID, candidateIDs, bounds) {
|
||||
// Filter candidates by rough bounding box intersection.
|
||||
|
@ -788,11 +797,13 @@ class RenderWebGL extends EventEmitter {
|
|||
updateDrawableProperties (drawableID, properties) {
|
||||
const drawable = this._allDrawables[drawableID];
|
||||
if (!drawable) {
|
||||
// TODO: fix whatever's wrong in the VM which causes this, then add a warning or throw here.
|
||||
// Right now this happens so much on some projects that a warning or exception here can hang the browser.
|
||||
/**
|
||||
* @todo fix whatever's wrong in the VM which causes this, then add a warning or throw here.
|
||||
* Right now this happens so much on some projects that a warning or exception here can hang the browser.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
// TODO: remove this after fully deprecating URL-based skin paths
|
||||
/** @todo remove this after fully deprecating URL-based skin paths */
|
||||
if ('skin' in properties) {
|
||||
const {skin, costumeResolution, rotationCenter} = properties;
|
||||
const skinId = this.createSkinFromURL(skin, costumeResolution, rotationCenter);
|
||||
|
@ -949,7 +960,7 @@ class RenderWebGL extends EventEmitter {
|
|||
this._pickBufferInfo = twgl.createFramebufferInfo(gl, attachments, MAX_TOUCH_SIZE[0], MAX_TOUCH_SIZE[1]);
|
||||
}
|
||||
|
||||
// TODO: should we create this on demand to save memory?
|
||||
/** @todo should we create this on demand to save memory? */
|
||||
// A 480x360 32-bpp buffer is 675 KiB.
|
||||
if (this._queryBufferInfo) {
|
||||
twgl.resizeFramebufferInfo(gl, this._queryBufferInfo, attachments, width, height);
|
||||
|
@ -959,8 +970,8 @@ class RenderWebGL extends EventEmitter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Draw all Drawables, with the possible exception of
|
||||
* @param {int[]} drawables The Drawable IDs to draw, possibly this._drawList.
|
||||
* Draw a set of Drawables, by drawable ID
|
||||
* @param {Array<int>} drawables The Drawable IDs to draw, possibly this._drawList.
|
||||
* @param {ShaderManager.DRAW_MODE} drawMode Draw normally, silhouette, etc.
|
||||
* @param {module:twgl/m4.Mat4} projection The projection matrix to use.
|
||||
* @param {object} [opts] Options for drawing
|
||||
|
@ -981,7 +992,7 @@ class RenderWebGL extends EventEmitter {
|
|||
if (opts.filter && !opts.filter(drawableID)) continue;
|
||||
|
||||
const drawable = this._allDrawables[drawableID];
|
||||
// TODO: check if drawable is inside the viewport before anything else
|
||||
/** @todo check if drawable is inside the viewport before anything else */
|
||||
|
||||
// Hidden drawables (e.g., by a "hide" block) are never drawn.
|
||||
if (!drawable.getVisible()) continue;
|
||||
|
@ -1020,7 +1031,7 @@ class RenderWebGL extends EventEmitter {
|
|||
* Read back the pixels and find all boundary points.
|
||||
* Finally, apply a convex hull algorithm to simplify the set.
|
||||
* @param {int} drawableID The Drawable IDs calculate convex hull for.
|
||||
* @return {Array.<Array.<number>>} points Convex hull points, as [[x, y], ...]
|
||||
* @return {Array<Array<number>>} points Convex hull points, as [[x, y], ...]
|
||||
*/
|
||||
_getConvexHullPointsForDrawable (drawableID) {
|
||||
const drawable = this._allDrawables[drawableID];
|
||||
|
|
|
@ -8,6 +8,8 @@ class SVGSkin extends Skin {
|
|||
* Create a new SVG skin.
|
||||
* @param {!int} id - The ID for this Skin.
|
||||
* @param {!RenderWebGL} renderer - The renderer which will use this skin.
|
||||
* @constructor
|
||||
* @extends Skin
|
||||
*/
|
||||
constructor (id, renderer) {
|
||||
super(id);
|
||||
|
@ -34,7 +36,7 @@ class SVGSkin extends Skin {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return {[number,number]} the natural size, in Scratch units, of this skin.
|
||||
* @return {Array<number>} the natural size, in Scratch units, of this skin.
|
||||
*/
|
||||
get size () {
|
||||
return this._svgRenderer.size;
|
||||
|
@ -51,20 +53,21 @@ class SVGSkin extends Skin {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {[number,number]} scale - The scaling factors to be used.
|
||||
* @param {Array<number>} scale - The scaling factors to be used.
|
||||
* @return {WebGLTexture} The GL texture representation of this skin when drawing at the given scale.
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
getTexture (scale) {
|
||||
// TODO: re-render a scaled version if the requested scale is significantly larger than the current render
|
||||
/** @todo re-render a scaled version if the requested scale is significantly larger than the current render */
|
||||
return this._texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the contents of this skin to a snapshot of the provided SVG data.
|
||||
* @param {string} svgData - new SVG to use.
|
||||
* @param {number[]=} rotationCenter - Optional rotation center for the SVG. If not supplied, it will be
|
||||
* @param {Array<number>} [rotationCenter] - Optional rotation center for the SVG. If not supplied, it will be
|
||||
* calculated from the bounding box
|
||||
* @fires Skin.event:WasAltered
|
||||
*/
|
||||
setSVG (svgData, rotationCenter) {
|
||||
this._svgRenderer.fromString(svgData, () => {
|
||||
|
@ -76,7 +79,7 @@ class SVGSkin extends Skin {
|
|||
const textureOptions = {
|
||||
auto: true,
|
||||
mag: gl.NEAREST,
|
||||
min: gl.NEAREST, // TODO: mipmaps, linear (except pixelate)
|
||||
min: gl.NEAREST, /** @todo mipmaps, linear (except pixelate) */
|
||||
wrap: gl.CLAMP_TO_EDGE,
|
||||
src: this._svgRenderer.canvas
|
||||
};
|
||||
|
|
|
@ -5,12 +5,16 @@ const fragmentShaderText = require('./shaders/sprite.frag');
|
|||
|
||||
|
||||
class ShaderManager {
|
||||
/**
|
||||
* @param {WebGLRenderingContext} gl WebGL rendering context to create shaders for
|
||||
* @constructor
|
||||
*/
|
||||
constructor (gl) {
|
||||
this._gl = gl;
|
||||
|
||||
/**
|
||||
* The cache of all shaders compiled so far, filled on demand.
|
||||
* @type {Object.<ShaderManager.DRAW_MODE, Array.<ProgramInfo>>}
|
||||
* @type {Object<ShaderManager.DRAW_MODE, Array<ProgramInfo>>}
|
||||
* @private
|
||||
*/
|
||||
this._shaderCache = {};
|
||||
|
@ -69,50 +73,60 @@ class ShaderManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Mapping of each effect name to info about that effect.
|
||||
* The info includes:
|
||||
* - The bit in 'effectBits' representing the effect.
|
||||
* - A conversion function which takes a Scratch value (generally in the range
|
||||
* @typedef {object} ShaderManager.Effect
|
||||
* @prop {int} mask - The bit in 'effectBits' representing the effect.
|
||||
* @prop {function} converter - A conversion function which takes a Scratch value (generally in the range
|
||||
* 0..100 or -100..100) and maps it to a value useful to the shader. This
|
||||
* mapping may not be reversible.
|
||||
* - `shapeChanges`, whether the effect could change the drawn shape.
|
||||
* @type {Object.<string,Object.<string,*>>}
|
||||
* @prop {boolean} shapeChanges - Whether the effect could change the drawn shape.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mapping of each effect name to info about that effect.
|
||||
* @enum {ShaderManager.Effect}
|
||||
*/
|
||||
ShaderManager.EFFECT_INFO = {
|
||||
/** Color effect */
|
||||
color: {
|
||||
mask: 1 << 0,
|
||||
converter: x => (x / 200) % 1,
|
||||
shapeChanges: false
|
||||
},
|
||||
/** Fisheye effect */
|
||||
fisheye: {
|
||||
mask: 1 << 1,
|
||||
converter: x => Math.max(0, (x + 100) / 100),
|
||||
shapeChanges: true
|
||||
},
|
||||
/** Whirl effect */
|
||||
whirl: {
|
||||
mask: 1 << 2,
|
||||
converter: x => -x * Math.PI / 180,
|
||||
shapeChanges: true
|
||||
},
|
||||
/** Pixelate effect */
|
||||
pixelate: {
|
||||
mask: 1 << 3,
|
||||
converter: x => Math.abs(x) / 10,
|
||||
shapeChanges: true
|
||||
},
|
||||
/** Mosaic effect */
|
||||
mosaic: {
|
||||
mask: 1 << 4,
|
||||
converter: x => {
|
||||
x = Math.round((Math.abs(x) + 10) / 10);
|
||||
// TODO: cap by Math.min(srcWidth, srcHeight)
|
||||
/** @todo cap by Math.min(srcWidth, srcHeight) */
|
||||
return Math.max(1, Math.min(x, 512));
|
||||
},
|
||||
shapeChanges: true
|
||||
},
|
||||
/** Brightness effect */
|
||||
brightness: {
|
||||
mask: 1 << 5,
|
||||
converter: x => Math.max(-100, Math.min(x, 100)) / 100,
|
||||
shapeChanges: false
|
||||
},
|
||||
/** Ghost effect */
|
||||
ghost: {
|
||||
mask: 1 << 6,
|
||||
converter: x => 1 - (Math.max(0, Math.min(x, 100)) / 100),
|
||||
|
|
15
src/Skin.js
15
src/Skin.js
|
@ -8,6 +8,7 @@ class Skin extends EventEmitter {
|
|||
/**
|
||||
* Create a Skin, which stores and/or generates textures for use in rendering.
|
||||
* @param {int} id - The unique ID for this Skin.
|
||||
* @constructor
|
||||
*/
|
||||
constructor (id) {
|
||||
super();
|
||||
|
@ -27,7 +28,7 @@ class Skin extends EventEmitter {
|
|||
this._uniforms = {
|
||||
/**
|
||||
* The nominal (not necessarily current) size of the current skin.
|
||||
* @type {number[]}
|
||||
* @type {Array<number>}
|
||||
*/
|
||||
u_skinSize: [0, 0],
|
||||
|
||||
|
@ -64,7 +65,7 @@ class Skin extends EventEmitter {
|
|||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {[number,number]} the "native" size, in texels, of this skin.
|
||||
* @return {Array<number>} the "native" size, in texels, of this skin.
|
||||
*/
|
||||
get size () {
|
||||
return [0, 0];
|
||||
|
@ -74,6 +75,7 @@ class Skin extends EventEmitter {
|
|||
* Set the origin, in object space, about which this Skin should rotate.
|
||||
* @param {number} x - The x coordinate of the new rotation center.
|
||||
* @param {number} y - The y coordinate of the new rotation center.
|
||||
* @fires Skin.event:WasAltered
|
||||
*/
|
||||
setRotationCenter (x, y) {
|
||||
if (x !== this._rotationCenter[0] || y !== this._rotationCenter[1]) {
|
||||
|
@ -85,7 +87,7 @@ class Skin extends EventEmitter {
|
|||
|
||||
/**
|
||||
* Get the center of the current bounding box
|
||||
* @return {[number,number]} the center of the current bounding box
|
||||
* @return {Array<number>} the center of the current bounding box
|
||||
*/
|
||||
calculateRotationCenter () {
|
||||
return [this.size[0] / 2, this.size[1] / 2];
|
||||
|
@ -93,7 +95,7 @@ class Skin extends EventEmitter {
|
|||
|
||||
/**
|
||||
* @abstract
|
||||
* @param {[number,number]} scale - The scaling factors to be used.
|
||||
* @param {Array<number>} scale - The scaling factors to be used.
|
||||
* @return {WebGLTexture} The GL texture representation of this skin when drawing at the given size.
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
|
@ -103,7 +105,7 @@ class Skin extends EventEmitter {
|
|||
|
||||
/**
|
||||
* Update and returns the uniforms for this skin.
|
||||
* @param {[number,number]} scale - The scaling factors to be used.
|
||||
* @param {Array<number>} scale - The scaling factors to be used.
|
||||
* @returns {object.<string, *>} the shader uniforms to be used when rendering with this Skin.
|
||||
*/
|
||||
getUniforms (scale) {
|
||||
|
@ -115,11 +117,12 @@ class Skin extends EventEmitter {
|
|||
|
||||
/**
|
||||
* These are the events which can be emitted by instances of this class.
|
||||
* @type {object.<string,string>}
|
||||
* @enum {string}
|
||||
*/
|
||||
Skin.Events = {
|
||||
/**
|
||||
* Emitted when anything about the Skin has been altered, such as the appearance or rotation center.
|
||||
* @event Skin.event:WasAltered
|
||||
*/
|
||||
WasAltered: 'WasAltered'
|
||||
};
|
||||
|
|
|
@ -52,7 +52,7 @@ class SvgRenderer {
|
|||
* This will be parsed and transformed, and finally drawn.
|
||||
* When drawing is finished, the `onFinish` callback is called.
|
||||
* @param {string} svgString String of SVG data to draw in quirks-mode.
|
||||
* @param {Function=} onFinish Optional callback for when drawing finished.
|
||||
* @param {Function} [onFinish] Optional callback for when drawing finished.
|
||||
*/
|
||||
fromString (svgString, onFinish) {
|
||||
// Store the callback for later.
|
||||
|
@ -74,14 +74,14 @@ class SvgRenderer {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return {[number,number]} the natural size, in Scratch units, of this SVG.
|
||||
* @return {Array<number>} the natural size, in Scratch units, of this SVG.
|
||||
*/
|
||||
get size () {
|
||||
return [this._measurements.width, this._measurements.height];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {[number,number]} the offset (upper left corner) of the SVG's view box.
|
||||
* @return {Array<number>} the offset (upper left corner) of the SVG's view box.
|
||||
*/
|
||||
get viewOffset () {
|
||||
return [this._measurements.x, this._measurements.y];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue