From 6cb40a5d5b4ec1c04c5eb2fc5d9b5670e030c732 Mon Sep 17 00:00:00 2001 From: Spongman Date: Tue, 24 Oct 2017 11:52:48 -0700 Subject: [PATCH 01/31] more thorough parameter validation # Conflicts: # src/core/error_helpers.js # src/webgl/p5.Matrix.js # src/webgl/p5.RendererGL.js --- lib/addons/p5.dom.js | 18 +++- src/color/creating_reading.js | 28 +++-- src/color/setting.js | 1 + src/core/attributes.js | 5 + src/core/curves.js | 3 + src/core/environment.js | 3 + src/core/error_helpers.js | 166 +++++++++++++++++++----------- src/core/rendering.js | 4 + src/core/transform.js | 12 ++- src/core/vertex.js | 4 + src/events/keyboard.js | 1 + src/image/image.js | 3 + src/image/loading_displaying.js | 5 + src/image/p5.Image.js | 2 +- src/image/pixels.js | 5 +- src/math/calculation.js | 8 +- src/math/p5.Vector.js | 8 +- src/utilities/string_functions.js | 8 +- src/webgl/material.js | 4 +- src/webgl/p5.Matrix.js | 14 +-- src/webgl/p5.RendererGL.js | 8 +- 21 files changed, 211 insertions(+), 99 deletions(-) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index 04d7bded1a..05610c96eb 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -69,6 +69,7 @@ * */ p5.prototype.select = function (e, p) { + p5._validateParameters('select', arguments); var res = null; var container = getContainer(p); if (e[0] === '.'){ @@ -135,6 +136,7 @@ * */ p5.prototype.selectAll = function (e, p) { + p5._validateParameters('selectAll', arguments); var arr = []; var res; var container = getContainer(p); @@ -215,6 +217,7 @@ * */ p5.prototype.removeElements = function (e) { + p5._validateParameters('removeElements', arguments); for (var i=0; i */ p5.prototype.createImg = function() { + p5._validateParameters('createImg', arguments); var elt = document.createElement('img'); var args = arguments; var self; @@ -359,6 +363,7 @@ * */ p5.prototype.createA = function(href, html, target) { + p5._validateParameters('createA', arguments); var elt = document.createElement('a'); elt.href = href; elt.innerHTML = html; @@ -412,6 +417,7 @@ * */ p5.prototype.createSlider = function(min, max, value, step) { + p5._validateParameters('createSlider', arguments); var elt = document.createElement('input'); elt.type = 'range'; elt.min = min; @@ -454,6 +460,7 @@ * */ p5.prototype.createButton = function(label, value) { + p5._validateParameters('createButton', arguments); var elt = document.createElement('button'); elt.innerHTML = label; if (value) elt.value = value; @@ -487,6 +494,7 @@ * */ p5.prototype.createCheckbox = function() { + p5._validateParameters('createCheckbox', arguments); var elt = document.createElement('div'); var checkbox = document.createElement('input'); checkbox.type = 'checkbox'; @@ -560,6 +568,7 @@ */ p5.prototype.createSelect = function() { + p5._validateParameters('createSelect', arguments); var elt, self; var arg = arguments[0]; if( typeof arg === 'object' && arg.elt.nodeName === 'SELECT' ) { @@ -680,6 +689,7 @@ * */ p5.prototype.createRadio = function() { + p5._validateParameters('createRadio', arguments); var radios = document.querySelectorAll("input[type=radio]"); var count = 0; if(radios.length > 1){ @@ -780,6 +790,7 @@ * */ p5.prototype.createInput = function(value, type) { + p5._validateParameters('createInput', arguments); var elt = document.createElement('input'); elt.type = type ? type : 'text'; if (value) elt.value = value; @@ -818,7 +829,8 @@ * } */ p5.prototype.createFileInput = function(callback, multiple) { - + p5._validateParameters('createFileInput', arguments); + // Is the file stuff supported? if (window.File && window.FileReader && window.FileList && window.Blob) { // Yup, we're ok and make an input file selector @@ -931,6 +943,7 @@ * @return {p5.MediaElement|p5.Element} pointer to video p5.Element */ p5.prototype.createVideo = function(src, callback) { + p5._validateParameters('createVideo', arguments); return createMedia(this, 'video', src, callback); }; @@ -958,6 +971,7 @@ * @return {p5.MediaElement|p5.Element} pointer to audio p5.Element */ p5.prototype.createAudio = function(src, callback) { + p5._validateParameters('createAudio', arguments); return createMedia(this, 'audio', src, callback); }; @@ -1051,6 +1065,7 @@ * */ p5.prototype.createCapture = function() { + p5._validateParameters('createCapture', arguments); var useVideo = true; var useAudio = true; var constraints; @@ -1123,6 +1138,7 @@ * */ p5.prototype.createElement = function(tag, content) { + p5._validateParameters('createElement', arguments); var elt = document.createElement(tag); if (typeof content !== 'undefined') { elt.innerHTML = content; diff --git a/src/color/creating_reading.js b/src/color/creating_reading.js index d3ba2854f6..ef5e64f9f8 100644 --- a/src/color/creating_reading.js +++ b/src/color/creating_reading.js @@ -17,7 +17,8 @@ require('../core/error_helpers'); * Extracts the alpha value from a color or pixel array. * * @method alpha - * @param {p5.Color|Array} color p5.Color object or pixel array + * @param {p5.Color|Number[]|String} color p5.Color object, color components, + * or CSS color * @return {Number} the alpha value * @example *
@@ -61,7 +62,8 @@ p5.prototype.alpha = function(c) { * Extracts the blue value from a color or pixel array. * * @method blue - * @param {p5.Color|Array} color p5.Color object or pixel array + * @param {p5.Color|Number[]|String} color p5.Color object, color components, + * or CSS color * @return {Number} the blue value * @example *
@@ -90,7 +92,8 @@ p5.prototype.blue = function(c) { * Extracts the HSB brightness value from a color or pixel array. * * @method brightness - * @param {p5.Color|Array} color p5.Color object or pixel array + * @param {p5.Color|Number[]|String} color p5.Color object, color components, + * or CSS color * @return {Number} the brightness value * @example *
@@ -294,7 +297,7 @@ p5.prototype.brightness = function(c) { */ /** * @method color - * @param {Array} values an array containing the red,green,blue & + * @param {Number[]} values an array containing the red,green,blue & * and alpha components of the color * @return {p5.Color} */ @@ -305,6 +308,7 @@ p5.prototype.brightness = function(c) { */ p5.prototype.color = function() { + p5._validateParameters('color', arguments); if (arguments[0] instanceof p5.Color) { return arguments[0]; // Do nothing if argument is already a color object. } else if (arguments[0] instanceof Array) { @@ -314,7 +318,6 @@ p5.prototype.color = function() { return new p5.Color(this._renderer, arguments[0]); } } else { - p5._validateParameters('color', arguments); if (this instanceof p5.Renderer) { return new p5.Color(this, arguments); } else { @@ -327,7 +330,8 @@ p5.prototype.color = function() { * Extracts the green value from a color or pixel array. * * @method green - * @param {p5.Color|Array} color p5.Color object or pixel array + * @param {p5.Color|Number[]|String} color p5.Color object, color components, + * or CSS color * @return {Number} the green value * @example *
@@ -363,7 +367,8 @@ p5.prototype.green = function(c) { * maximum hue setting for each system is different.) * * @method hue - * @param {p5.Color|Array} color p5.Color object or pixel array + * @param {p5.Color|Number[]|String} color p5.Color object, color components, + * or CSS color * @return {Number} the hue * @example *
@@ -490,7 +495,8 @@ p5.prototype.lerpColor = function(c1, c2, amt) { * Extracts the HSL lightness value from a color or pixel array. * * @method lightness - * @param {p5.Color|Array} color p5.Color object or pixel array + * @param {p5.Color|Number[]|String} color p5.Color object, color components, + * or CSS color * @return {Number} the lightness * @example *
@@ -519,7 +525,8 @@ p5.prototype.lightness = function(c) { * Extracts the red value from a color or pixel array. * * @method red - * @param {p5.Color|Array} color p5.Color object or pixel array + * @param {p5.Color|Number[]|String} color p5.Color object, color components, + * or CSS color * @return {Number} the red value * @example *
@@ -563,7 +570,8 @@ p5.prototype.red = function(c) { * HSL saturation otherwise. * * @method saturation - * @param {p5.Color|Array} color p5.Color object or pixel array + * @param {p5.Color|Number[]|String} color p5.Color object, color components, + * or CSS color * @return {Number} the saturation value * @example *
diff --git a/src/color/setting.js b/src/color/setting.js index 0eb1739995..6a1c9565c9 100644 --- a/src/color/setting.js +++ b/src/color/setting.js @@ -303,6 +303,7 @@ p5.prototype.clear = function() { * */ p5.prototype.colorMode = function() { + p5._validateParameters('colorMode', arguments); if (arguments[0] === constants.RGB || arguments[0] === constants.HSB || arguments[0] === constants.HSL) { diff --git a/src/core/attributes.js b/src/core/attributes.js index 0d9830a590..71e43ccaa8 100644 --- a/src/core/attributes.js +++ b/src/core/attributes.js @@ -68,6 +68,7 @@ var constants = require('./constants'); * */ p5.prototype.ellipseMode = function(m) { + p5._validateParameters('ellipseMode', arguments); if (m === constants.CORNER || m === constants.CORNERS || m === constants.RADIUS || @@ -162,6 +163,7 @@ p5.prototype.noSmooth = function() { * */ p5.prototype.rectMode = function(m) { + p5._validateParameters('rectMode', arguments); if (m === constants.CORNER || m === constants.CORNERS || m === constants.RADIUS || @@ -226,6 +228,7 @@ p5.prototype.smooth = function() { * */ p5.prototype.strokeCap = function(cap) { + p5._validateParameters('strokeCap', arguments); if (cap === constants.ROUND || cap === constants.SQUARE || cap === constants.PROJECT) { @@ -290,6 +293,7 @@ p5.prototype.strokeCap = function(cap) { * */ p5.prototype.strokeJoin = function(join) { + p5._validateParameters('strokeJoin', arguments); if (join === constants.ROUND || join === constants.BEVEL || join === constants.MITER) { @@ -322,6 +326,7 @@ p5.prototype.strokeJoin = function(join) { * */ p5.prototype.strokeWeight = function(w) { + p5._validateParameters('strokeWeight', arguments); this._renderer.strokeWeight(w); return this; }; diff --git a/src/core/curves.js b/src/core/curves.js index 190d708c1b..5b4ad8f76e 100644 --- a/src/core/curves.js +++ b/src/core/curves.js @@ -117,6 +117,7 @@ p5.prototype.bezier = function() { * */ p5.prototype.bezierDetail = function(d) { + p5._validateParameters('bezierDetail', arguments); bezierDetail = d; return this; }; @@ -371,6 +372,7 @@ p5.prototype.curve = function() { * */ p5.prototype.curveDetail = function(d) { + p5._validateParameters('curveDetail', arguments); curveDetail = d; return this; }; @@ -417,6 +419,7 @@ p5.prototype.curveDetail = function(d) { * Line shaped like right-facing arrow,points move with mouse-x and warp shape. */ p5.prototype.curveTightness = function (t) { + p5._validateParameters('curveTightness', arguments); this._renderer._curveTightness = t; }; diff --git a/src/core/environment.js b/src/core/environment.js index 5bb3ffa885..1cb52d2f37 100644 --- a/src/core/environment.js +++ b/src/core/environment.js @@ -227,6 +227,7 @@ p5.prototype.cursor = function(type, x, y) { * */ p5.prototype.frameRate = function(fps) { + p5._validateParameters('frameRate', arguments); if (typeof fps !== 'number' || fps < 0) { return this._frameRate; } else { @@ -457,6 +458,7 @@ p5.prototype.height = 0; * */ p5.prototype.fullscreen = function(val) { + p5._validateParameters('fullscreen', arguments); // no arguments, return fullscreen or not if (typeof val === 'undefined') { return document.fullscreenElement || @@ -509,6 +511,7 @@ p5.prototype.fullscreen = function(val) { * sharp 50x50 white ellipse with black outline in center of canvas. */ p5.prototype.pixelDensity = function(val) { + p5._validateParameters('pixelDensity', arguments); if (typeof val === 'number') { this._pixelDensity = val; } else { diff --git a/src/core/error_helpers.js b/src/core/error_helpers.js index bee8947e96..ad04b2fc8e 100644 --- a/src/core/error_helpers.js +++ b/src/core/error_helpers.js @@ -6,6 +6,16 @@ 'use strict'; var p5 = require('./core'); + +/* +if (typeof IS_MINIFIED !== 'undefined') { + + p5._validateParameters = + p5._friendlyFileLoadError = + function () { }; + +} else */{ + var doFriendlyWelcome = false; // TEMP until we get it all working LM // for parameter validation var dataDoc = require('../../docs/reference/data.json'); @@ -103,6 +113,7 @@ p5._friendlyFileLoadError = function (errorType, filePath) { report(message, errorInfo.method, FILE_LOAD); }; + var docCache = {}; /** * Validates parameters * param {String} func the name of the function @@ -125,10 +136,10 @@ p5._validateParameters = function validateParameters(func, args) { typeof(IS_MINIFIED) !== 'undefined') { return; // skip FES } - var arrDoc = lookupParamDoc(func); + try { + var arrDoc = docCache[func] || (docCache[func] = lookupParamDoc(func)); var errorArray = []; var minErrCount = 999999; - if (arrDoc.length > 1){ // func has multiple formats for (var i = 0; i < arrDoc.length; i++) { var arrError = testParamFormat(args, arrDoc[i]); if( arrError.length === 0) { @@ -144,11 +155,9 @@ p5._validateParameters = function validateParameters(func, args) { for (var n = 0; n < errorArray.length; n++) { p5._friendlyParamError(errorArray[n], func); } - } else { // func has a single format - errorArray = testParamFormat(args, arrDoc[0]); - for(var m = 0; m < errorArray.length; m++) { - p5._friendlyParamError(errorArray[m], func); } + catch (err) { + console.log('validation error: ' + err); } }; // validateParameters() helper functions: @@ -157,93 +166,130 @@ function lookupParamDoc(func){ var queryResult = arrDoc.classitems. filter(function (x) { return x.name === func; }); // different JSON structure for funct with multi-format - if (queryResult[0].hasOwnProperty('overloads')){ var res = []; + if (queryResult[0].hasOwnProperty('overloads')){ for(var i = 0; i < queryResult[0].overloads.length; i++) { res.push(queryResult[0].overloads[i].params); } - return res; } else { - return [queryResult[0].params]; + res.push(queryResult[0].params); } + var builtinTypes = [ + 'number', 'string', 'boolean', + 'constant', 'function', 'integer' + ]; + res.forEach(function (formats) { + formats.forEach(function (format) { + format.types = format.type.split('|').map(function ct(type) { + + if (type.substr(type.length - 2, 2) === '[]') { + return { + name: type, + array: ct(type.substr(0, type.length - 2)) + }; } -function testParamFormat(args, format){ - var errorArray = []; - var error; - for (var p = 0; p < format.length; p++) { - var argType = typeof(args[p]); - if ('undefined' === argType || null === argType) { - if (format[p].optional !== true) { - error = {type:'EMPTY_VAR', position: p}; - errorArray.push(error); + + var lowerType = type.toLowerCase(); + if (lowerType.substr(0, 'function'.length) === 'function') { + lowerType = 'function'; } - } else { - var types = format[p].type.split('|'); // case accepting multi-types - if (argType === 'object'){ // if object, test for class - if (!testParamClass(args[p], types)) { // if fails to pass - error = {type:'WRONG_CLASS', position: p, - correctClass: types[p], wrongClass: args[p].name}; - errorArray.push(error); + if (builtinTypes.indexOf(lowerType) >= 0) { + return { name: type, builtin: lowerType }; } - }else{ // not object, test for type - if (!testParamType(args[p], types)) { // if fails to pass - error = {type:'WRONG_TYPE', position: p, - correctType: types[p], wrongType: argType}; - errorArray.push(error); + + var t = window; + type.split('.').forEach(function (p) { t = t && t[p]; }); + if (t) { + return { name: type, prototype: t }; } + + return { name: type, type: lowerType }; + }); + }); + }); + return res; } + function testParamFormat(args, formats) { + var errorArray = []; + for (var p = 0; p < formats.length; p++) { + var arg = args[p]; + var format = formats[p]; + var argType = typeof (arg); + if ('undefined' === argType || null === arg) { + if (format.optional !== true) { + errorArray.push({ + type: 'EMPTY_VAR', + position: p, + correctType: format.type, + }); } + } else if (!testParamTypes(arg, format.types)) { + errorArray.push({ + type: 'WRONG_TYPE', + position: p, + correctType: format.type, + wrongType: arg instanceof Array ? 'array' : arg.name || argType + }); } + } return errorArray; } -// testClass() for object type parameter validation + // testType() for non-object type parameter validation // Returns true if PASS, false if FAIL -function testParamClass(param, types){ + function testParamTypes(param, types) { for (var i = 0; i < types.length; i++) { - if (types[i] === 'Array') { - if(param instanceof Array) { + if (testParamType(param, types[i])) { return true; } - } else { - if (param.name === types[i]) { - return true; // class name match, pass - } else if (types[i] === 'Constant') { - return true; // accepts any constant, pass } + return false; } - } + function testParamType(param, type) { + var isArray = param instanceof Array; + if (type.array && isArray) { + for (var i = 0; i < param.length; i++) { + if (!testParamType(param[i], type.array)) { return false; } -// testType() for non-object type parameter validation -// Returns true if PASS, false if FAIL -function testParamType(param, types){ - for (var i = 0; i < types.length; i++) { - if (typeof(param) === types[i].toLowerCase()) { - return true; // type match, pass - } else if (types[i] === 'Constant') { - return true; // accepts any constant, pass } + return true; } - return false; + else if (type.prototype) { + return param instanceof type.prototype; } + else if (type.builtin) { + switch (type.builtin) { + case 'number': + return (typeof param === 'number' || !!param && !isNaN(param)); + case 'integer': + return (typeof param === 'number' || !!param && !isNaN(param)) && + Number(param) === Math.floor(param); + case 'boolean': + return true; + case 'array': + return isArray; + case 'string': + case 'constant': + return typeof param === 'number' || + typeof param === 'string'; + case 'function': + return param instanceof Function; + } + } + + return typeof param === type.t; + } // function for generating console.log() msg p5._friendlyParamError = function (errorObj, func) { var message; switch (errorObj.type){ case 'EMPTY_VAR': - message = 'It looks like ' + func + - '() received an empty variable in spot #' + errorObj.position + - ' (zero-based index). If not intentional, this is often a problem' + + message = func + '() was expecting ' + errorObj.correctType + + ' for parameter #' + errorObj.position + ' (zero-based index), received' + + ' an empty variable instead. If not intentional, this is often a problem' + ' with scope: [https://p5js.org/examples/data-variable-scope.html].'; report(message, func, ERR_PARAMS); break; - case 'WRONG_CLASS': - message = func + '() was expecting ' + errorObj.correctClass + - ' for parameter #' + errorObj.position + ' (zero-based index), received '; - // Wrap strings in quotes - message += 'an object with name '+ errorObj.wrongClass +' instead.'; - report(message, func, ERR_PARAMS); - break; case 'WRONG_TYPE': message = func + '() was expecting ' + errorObj.correctType + ' for parameter #' + errorObj.position + ' (zero-based index), received '; @@ -411,4 +457,6 @@ if (document.readyState !== 'complete') { }); } +} + module.exports = p5; diff --git a/src/core/rendering.js b/src/core/rendering.js index cb2a9102e4..b7fc3c6480 100644 --- a/src/core/rendering.js +++ b/src/core/rendering.js @@ -48,6 +48,7 @@ var defaultId = 'defaultCanvas0'; // this gets set again in createCanvas */ p5.prototype.createCanvas = function(w, h, renderer) { + p5._validateParameters('createCanvas', arguments); //optional: renderer, otherwise defaults to p2d var r = renderer || constants.P2D; var c; @@ -137,6 +138,7 @@ p5.prototype.createCanvas = function(w, h, renderer) { * */ p5.prototype.resizeCanvas = function (w, h, noRedraw) { + p5._validateParameters('resizeCanvas', arguments); if (this._renderer) { // save canvas properties @@ -217,6 +219,7 @@ p5.prototype.noCanvas = function() { * */ p5.prototype.createGraphics = function(w, h, renderer){ + p5._validateParameters('createGraphics', arguments); return new p5.Graphics(w, h, renderer, this); }; @@ -286,6 +289,7 @@ p5.prototype.createGraphics = function(w, h, renderer){ * */ p5.prototype.blendMode = function(mode) { + p5._validateParameters('blendMode', arguments); if (mode === constants.BLEND || mode === constants.DARKEST || mode === constants.LIGHTEST || mode === constants.DIFFERENCE || mode === constants.MULTIPLY || mode === constants.EXCLUSION || diff --git a/src/core/transform.js b/src/core/transform.js index a0f9828434..1c3129b3bb 100644 --- a/src/core/transform.js +++ b/src/core/transform.js @@ -179,7 +179,7 @@ p5.prototype.resetMatrix = function() { * @method rotate * @param {Number} angle the angle of rotation, specified in radians * or degrees, depending on current angleMode - * @param {p5.Vector|Array} [axis] (in 3d) the axis to rotate around + * @param {p5.Vector|Number[]} [axis] (in 3d) the axis to rotate around * @chainable * @example *
@@ -195,6 +195,7 @@ p5.prototype.resetMatrix = function() { * */ p5.prototype.rotate = function(angle, axis) { + p5._validateParameters('rotate', arguments); var args = new Array(arguments.length); var r; for (var i = 0; i < args.length; ++i) { @@ -222,6 +223,7 @@ p5.prototype.rotate = function(angle, axis) { * @chainable */ p5.prototype.rotateX = function(rad) { + p5._validateParameters('rotateX', arguments); if (this._renderer.isP3D) { this._renderer.rotateX(rad); } else { @@ -237,6 +239,7 @@ p5.prototype.rotateX = function(rad) { * @chainable */ p5.prototype.rotateY = function(rad) { + p5._validateParameters('rotateY', arguments); if (this._renderer.isP3D) { this._renderer.rotateY(rad); } else { @@ -252,6 +255,7 @@ p5.prototype.rotateY = function(rad) { * @chainable */ p5.prototype.rotateZ = function(rad) { + p5._validateParameters('rotateZ', arguments); if (this._renderer.isP3D) { this._renderer.rotateZ(rad); } else { @@ -276,7 +280,7 @@ p5.prototype.rotateZ = function(rad) { * This function can be further controlled with push() and pop(). * * @method scale - * @param {Number|p5.Vector|Array} s + * @param {Number|p5.Vector|Number[]} s * percent to scale the object, or percentage to * scale the object in the x-axis if multiple arguments * are given @@ -306,6 +310,7 @@ p5.prototype.rotateZ = function(rad) { * */ p5.prototype.scale = function() { + p5._validateParameters('scale', arguments); var x,y,z; var args = new Array(arguments.length); for(var i = 0; i < args.length; i++) { @@ -376,6 +381,7 @@ p5.prototype.scale = function() { * */ p5.prototype.shearX = function(angle) { + p5._validateParameters('shearX', arguments); if (this._angleMode === constants.DEGREES) { angle = this.radians(angle); } @@ -417,6 +423,7 @@ p5.prototype.shearX = function(angle) { * */ p5.prototype.shearY = function(angle) { + p5._validateParameters('shearY', arguments); if (this._angleMode === constants.DEGREES) { angle = this.radians(angle); } @@ -465,6 +472,7 @@ p5.prototype.shearY = function(angle) { * */ p5.prototype.translate = function(x, y, z) { + p5._validateParameters('translate', arguments); if (this._renderer.isP3D) { this._renderer.translate(x, y, z); } else { diff --git a/src/core/vertex.js b/src/core/vertex.js index d7f50c5462..009c1d803a 100644 --- a/src/core/vertex.js +++ b/src/core/vertex.js @@ -244,6 +244,7 @@ p5.prototype.beginContour = function() { * */ p5.prototype.beginShape = function(kind) { + p5._validateParameters('beginShape', arguments); if (kind === constants.POINTS || kind === constants.LINES || kind === constants.TRIANGLES || @@ -311,6 +312,7 @@ p5.prototype.beginShape = function(kind) { * */ p5.prototype.bezierVertex = function(x2, y2, x3, y3, x4, y4) { + p5._validateParameters('bezierVertex', arguments); if (vertices.length === 0) { throw 'vertex() must be used once before calling bezierVertex()'; } else { @@ -366,6 +368,7 @@ p5.prototype.bezierVertex = function(x2, y2, x3, y3, x4, y4) { * */ p5.prototype.curveVertex = function(x,y) { + p5._validateParameters('curveVertex', arguments); isCurve = true; this.vertex(x, y); return this; @@ -545,6 +548,7 @@ p5.prototype.endShape = function(mode) { * */ p5.prototype.quadraticVertex = function(cx, cy, x3, y3) { + p5._validateParameters('quadraticVertex', arguments); //if we're drawing a contour, put the points into an // array for inside drawing if(this._contourInited) { diff --git a/src/events/keyboard.js b/src/events/keyboard.js index 398ec55239..3916ed85d1 100644 --- a/src/events/keyboard.js +++ b/src/events/keyboard.js @@ -358,6 +358,7 @@ p5.prototype._onblur = function (e) { * */ p5.prototype.keyIsDown = function(code) { + p5._validateParameters('keyIsDown', arguments); return downKeys[code]; }; diff --git a/src/image/image.js b/src/image/image.js index 70e561f6ae..5afcfc2bfc 100644 --- a/src/image/image.js +++ b/src/image/image.js @@ -97,6 +97,7 @@ var frames = []; * */ p5.prototype.createImage = function(width, height) { + p5._validateParameters('createImage', arguments); return new p5.Image(width, height); }; @@ -151,6 +152,7 @@ p5.prototype.createImage = function(width, height) { * */ p5.prototype.saveCanvas = function() { + p5._validateParameters('saveCanvas', arguments); var cnv, filename, extension; if (arguments.length === 3) { @@ -274,6 +276,7 @@ p5.prototype.saveCanvas = function() { * */ p5.prototype.saveFrames = function(fName, ext, _duration, _fps, callback) { + p5._validateParameters('saveFrames', arguments); var duration = _duration || 3; duration = p5.prototype.constrain(duration, 0, 15); duration = duration * 1000; diff --git a/src/image/loading_displaying.js b/src/image/loading_displaying.js index 694ccda295..dc17ec4a79 100644 --- a/src/image/loading_displaying.js +++ b/src/image/loading_displaying.js @@ -64,6 +64,7 @@ require('../core/error_helpers'); * */ p5.prototype.loadImage = function(path, successCallback, failureCallback) { + p5._validateParameters('loadImage', arguments); var img = new Image(); var pImg = new p5.Image(1, 1, this); @@ -233,6 +234,8 @@ p5.prototype.image = function(img, dx, dy, dWidth, dHeight, sx, sy, sWidth, sHeight) { // set defaults per spec: https://goo.gl/3ykfOq + p5._validateParameters('image', arguments); + var defW = img.width; var defH = img.height; @@ -377,6 +380,7 @@ p5.prototype.image = * */ p5.prototype.tint = function () { + p5._validateParameters('tint', arguments); var c = this.color.apply(this, arguments); this._renderer._tint = c.levels; }; @@ -512,6 +516,7 @@ p5.prototype._getTintedImageCanvas = function(img) { * */ p5.prototype.imageMode = function(m) { + p5._validateParameters('imageMode', arguments); if (m === constants.CORNER || m === constants.CORNERS || m === constants.CENTER) { diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js index ac8309bbb8..bbe98e6bd9 100644 --- a/src/image/p5.Image.js +++ b/src/image/p5.Image.js @@ -323,7 +323,7 @@ p5.Image.prototype.get = function(x, y, w, h){ * @method set * @param {Number} x x-coordinate of the pixel * @param {Number} y y-coordinate of the pixel - * @param {Number|Array|Object} a grayscale value | pixel array | + * @param {Number|Number[]|Object} a grayscale value | pixel array | * a p5.Color | image to copy * @example *
diff --git a/src/image/pixels.js b/src/image/pixels.js index 0c538b759b..f16c667bbb 100644 --- a/src/image/pixels.js +++ b/src/image/pixels.js @@ -171,7 +171,7 @@ p5.prototype.blend = function() { * target region. * * @method copy - * @param {p5.Image|undefined} srcImage source image + * @param {p5.Image|p5.Graphics|undefined} srcImage source image * @param {Integer} sx X coordinate of the source's upper left corner * @param {Integer} sy Y coordinate of the source's upper left corner * @param {Integer} sw source image width @@ -206,6 +206,7 @@ p5.prototype.blend = function() { * */ p5.prototype.copy = function () { + p5._validateParameters('copy', arguments); p5.Renderer2D._copyHelper.apply(this, arguments); }; @@ -519,7 +520,7 @@ p5.prototype.loadPixels = function() { * @method set * @param {Number} x x-coordinate of the pixel * @param {Number} y y-coordinate of the pixel - * @param {Number|Array|Object} c insert a grayscale value | a pixel array | + * @param {Number|Number[]|Object} c insert a grayscale value | a pixel array | * a p5.Color object | a p5.Image to copy * @example *
diff --git a/src/math/calculation.js b/src/math/calculation.js index 91aa6f128f..df71edcd31 100644 --- a/src/math/calculation.js +++ b/src/math/calculation.js @@ -467,8 +467,8 @@ p5.prototype.map = function (n, start1, stop1, start2, stop2, withinBounds) { * of any length. * * @method max - * @param {Number|Array} n0 Numbers to compare - * @return {Number} maximum Number + * @param {Number|Number[]} n0 Numbers to compare + * @return {Number} maximum Number * @example *
* function setup() { @@ -510,8 +510,8 @@ p5.prototype.max = function() { * of any length. * * @method min - * @param {Number|Array} n0 Numbers to compare - * @return {Number} minimum Number + * @param {Number|Number[]} n0 Numbers to compare + * @return {Number} minimum Number * @example *
* function setup() { diff --git a/src/math/p5.Vector.js b/src/math/p5.Vector.js index 6f6d90eb09..e090a3060c 100644 --- a/src/math/p5.Vector.js +++ b/src/math/p5.Vector.js @@ -106,7 +106,7 @@ p5.Vector.prototype.toString = function p5VectorToString() { * Sets the x, y, and z component of the vector using two or three separate * variables, the data from a p5.Vector, or the values from a float array. * @method set - * @param {Number|p5.Vector|Array} [x] the x component of the vector or a + * @param {Number|p5.Vector|Number[]} [x] the x component of the vector or a * p5.Vector or an Array * @param {Number} [y] the y component of the vector * @param {Number} [z] the z component of the vector @@ -174,7 +174,7 @@ p5.Vector.prototype.copy = function () { * acts directly on the vector. See the examples for more context. * * @method add - * @param {Number|p5.Vector|Array} x the x component of the vector to be + * @param {Number|p5.Vector|Number[]} x the x component of the vector to be * added or a p5.Vector or an Array * @param {Number} [y] the y component of the vector to be * added @@ -226,7 +226,7 @@ p5.Vector.prototype.add = function (x, y, z) { * other acts directly on the vector. See the examples for more context. * * @method sub - * @param {Number|p5.Vector|Array} x the x component of the vector or a + * @param {Number|p5.Vector|Number[]} x the x component of the vector or a * p5.Vector or an Array * @param {Number} [y] the y component of the vector * @param {Number} [z] the z component of the vector @@ -731,7 +731,7 @@ p5.Vector.prototype.array = function () { * Equality check against a p5.Vector * * @method equals - * @param {Number|p5.Vector|Array} [x] the x component of the vector or a + * @param {Number|p5.Vector|Number[]} [x] the x component of the vector or a * p5.Vector or an Array * @param {Number} [y] the y component of the vector * @param {Number} [z] the z component of the vector diff --git a/src/utilities/string_functions.js b/src/utilities/string_functions.js index 61c83ac50a..ae8c28ef14 100644 --- a/src/utilities/string_functions.js +++ b/src/utilities/string_functions.js @@ -148,7 +148,7 @@ p5.prototype.matchAll = function(str, reg) { * @param {Array} nums the Numbers to format * @param {Number|String} [left] * @param {Number|String} [right] - * @return {Array} formatted Strings\ + * @return {String[]} formatted Strings * @example *
* @@ -258,7 +258,7 @@ function doNf() { * @method nfc * @param {Array} nums the Numbers to format * @param {Number|String} [right] - * @return {Array} formatted Strings + * @return {String[]} formatted Strings * @example *
* @@ -406,7 +406,7 @@ function addNfp() { * @param {Array} nums the Numbers to format * @param {Number} [left] * @param {Number} [right] - * @return {Array} formatted Strings + * @return {String[]} formatted Strings * @example *
* @@ -550,7 +550,7 @@ p5.prototype.splitTokens = function() { /** * @method trim * @param {Array} strs an Array of Strings to be trimmed - * @return {Array} an Array of trimmed Strings + * @return {String[]} an Array of trimmed Strings * @example *
* diff --git a/src/webgl/material.js b/src/webgl/material.js index 7e808739ab..9088b1ccdd 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -212,7 +212,7 @@ p5.prototype.texture = function(){ * possible materials in this * example. * @method ambientMaterial - * @param {Number|Array|String|p5.Color} v1 gray value, + * @param {Number|Number[]|String|p5.Color} v1 gray value, * red or hue value (depending on the current color mode), * or color Array, or CSS color string * @param {Number} [v2] green or saturation value @@ -255,7 +255,7 @@ p5.prototype.ambientMaterial = function(v1, v2, v3, a) { * possible materials in this * example. * @method specularMaterial - * @param {Number|Array|String|p5.Color} v1 gray value, + * @param {Number|Number[]|String|p5.Color} v1 gray value, * red or hue value (depending on the current color mode), * or color Array, or CSS color string * @param {Number} [v2] green or saturation value diff --git a/src/webgl/p5.Matrix.js b/src/webgl/p5.Matrix.js index c3980675e7..adcdea02be 100644 --- a/src/webgl/p5.Matrix.js +++ b/src/webgl/p5.Matrix.js @@ -76,7 +76,7 @@ p5.Matrix = function() { * Sets the x, y, and z component of the vector using two or three separate * variables, the data from a p5.Matrix, or the values from a float array. * - * @param {p5.Matrix|Float32Array|Array} [inMatrix] the input p5.Matrix or + * @param {p5.Matrix|Float32Array|Number[]} [inMatrix] the input p5.Matrix or * an Array of length 16 * @param {Number} [n00..n33] 16 numbers passed by value to avoid * array copying. @@ -154,7 +154,8 @@ p5.Matrix.identity = function(){ /** * transpose according to a given matrix - * @param {p5.Matrix|Float32Array|Array} a the matrix to be based on to transpose + * @param {p5.Matrix|Float32Array|Number[]} a the matrix to be based + * on to transpose * @chainable */ p5.Matrix.prototype.transpose = function(a){ @@ -214,7 +215,8 @@ p5.Matrix.prototype.transpose = function(a){ /** * invert matrix according to a give matrix - * @param {p5.Matrix|Float32Array|Array} a the matrix to be based on to invert + * @param {p5.Matrix|Float32Array|Number[]} a the matrix to be based on to + * invert * @chainable */ p5.Matrix.prototype.invert = function(a){ @@ -402,7 +404,7 @@ p5.Matrix.prototype.determinant = function(){ /** * multiply two mat4s - * @param {p5.Matrix|Float32Array|Array} multMatrix The matrix + * @param {p5.Matrix|Float32Array|Number[]} multMatrix The matrix * we want to multiply by * @chainable */ @@ -459,7 +461,7 @@ p5.Matrix.prototype.mult = function(multMatrix){ /** * scales a p5.Matrix by scalars or a vector - * @param {p5.Vector|Float32Array|Array} s vector to scale by + * @param {p5.Vector|Float32Array|Number[]} s vector to scale by * @chainable */ p5.Matrix.prototype.scale = function() { @@ -505,7 +507,7 @@ p5.Matrix.prototype.scale = function() { /** * rotate our Matrix around an axis by the given angle. * @param {Number} a The angle of rotation in radians - * @param {p5.Vector|Array} axis the axis(es) to rotate around + * @param {p5.Vector|Number[]} axis the axis(es) to rotate around * @chainable * inspired by Toji's gl-matrix lib, mat4 rotation */ diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 91b52ab6b2..fc4d626fd8 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -352,7 +352,7 @@ p5.RendererGL.prototype.background = function() { /** * Basic fill material for geometry with a given color * @method fill - * @param {Number|Array|String|p5.Color} v1 gray value, + * @param {Number|Number[]|String|p5.Color} v1 gray value, * red or hue value (depending on the current color mode), * or color Array, or CSS color string * @param {Number} [v2] green or saturation value @@ -460,7 +460,7 @@ p5.RendererGL.prototype.noStroke = function() { /** * Basic stroke material for geometry with a given color * @method stroke - * @param {Number|Array|String|p5.Color} v1 gray value, + * @param {Number|Number[]|String|p5.Color} v1 gray value, * red or hue value (depending on the current color mode), * or color Array, or CSS color string * @param {Number} [v2] green or saturation value @@ -917,8 +917,8 @@ p5.RendererGL.prototype._flatten = function(arr){ /** * turn a p5.Vector Array into a one dimensional number array - * @param {Array} arr an array of p5.Vector - * @return {Array]} a one dimensional array of numbers + * @param {p5.Vector[]} arr an array of p5.Vector + * @return {Number[]} a one dimensional array of numbers * [p5.Vector(1, 2, 3), p5.Vector(4, 5, 6)] -> * [1, 2, 3, 4, 5, 6] */ From 0631eba3390bbbcb96674aab85c328c5150f312b Mon Sep 17 00:00:00 2001 From: Spongman Date: Tue, 24 Oct 2017 15:53:26 -0700 Subject: [PATCH 02/31] validate constant values, remove some of the debug code from minified build # Conflicts: # src/core/error_helpers.js --- src/core/error_helpers.js | 624 +++++++++++++++++++++----------------- 1 file changed, 341 insertions(+), 283 deletions(-) diff --git a/src/core/error_helpers.js b/src/core/error_helpers.js index ad04b2fc8e..f8b318fb0d 100644 --- a/src/core/error_helpers.js +++ b/src/core/error_helpers.js @@ -7,256 +7,241 @@ var p5 = require('./core'); -/* if (typeof IS_MINIFIED !== 'undefined') { p5._validateParameters = p5._friendlyFileLoadError = function () { }; - -} else */{ - -var doFriendlyWelcome = false; // TEMP until we get it all working LM -// for parameter validation -var dataDoc = require('../../docs/reference/data.json'); -var arrDoc = JSON.parse(JSON.stringify(dataDoc)); - -// -- Borrowed from jQuery 1.11.3 -- -var class2type = {}; -var toString = class2type.toString; -var names = ['Boolean', 'Number', 'String', 'Function', - 'Array', 'Date', 'RegExp', 'Object', 'Error']; -for (var n=0; n p5.js says: '+message+ - '[https://github.com/processing/p5.js/wiki/Local-server]' - ); - } - else{ + var getType = function (obj) { + if (obj == null) { + return obj + ''; + } + return typeof obj === 'object' || typeof obj === 'function' ? + class2type[toString.call(obj)] || 'object' : + typeof obj; + }; + + // -- End borrow -- + + + var friendlyWelcome = function () { + // p5.js brand - magenta: #ED225D + //var astrixBgColor = 'transparent'; + //var astrixTxtColor = '#ED225D'; + //var welcomeBgColor = '#ED225D'; + //var welcomeTextColor = 'white'; console.log( - '> p5.js says: '+message+' [http://p5js.org/reference/#p5/'+func+ - ']' + ' _ \n' + + ' /\\| |/\\ \n' + + ' \\ ` \' / \n' + + ' / , . \\ \n' + + ' \\/|_|\\/ ' + + '\n\n> p5.js says: Welcome! ' + + 'This is your friendly debugger. ' + + 'To turn me off switch to using “p5.min.js”.' ); - } -} - -var errorCases = { - '0': { - fileType: 'image', - method: 'loadImage', - message: ' hosting the image online,' - }, - '1': { - fileType: 'XML file', - method: 'loadXML' - }, - '2': { - fileType: 'table file', - method: 'loadTable' - }, - '3': { - fileType: 'text file', - method: 'loadStrings' - }, - '4': { - fileType: 'font', - method: 'loadFont', - message: ' hosting the font online,' - }, -}; -p5._friendlyFileLoadError = function (errorType, filePath) { - var errorInfo = errorCases[ errorType ]; - var message = 'It looks like there was a problem' + - ' loading your ' + errorInfo.fileType + '.' + - ' Try checking if the file path [' + filePath + '] is correct,' + - (errorInfo.message || '') + ' or running a local server.'; - report(message, errorInfo.method, FILE_LOAD); -}; + }; - var docCache = {}; -/** -* Validates parameters -* param {String} func the name of the function -* param {Array} args user input arguments -* -* example: -* var a; -* ellipse(10,10,a,5); -* console ouput: -* "It looks like ellipse received an empty variable in spot #2." -* -* example: -* ellipse(10,"foo",5,5); -* console output: -* "ellipse was expecting a number for parameter #1, -* received "foo" instead." -*/ -p5._validateParameters = function validateParameters(func, args) { - if (p5.disableFriendlyErrors || - typeof(IS_MINIFIED) !== 'undefined') { - return; // skip FES - } - try { - var arrDoc = docCache[func] || (docCache[func] = lookupParamDoc(func)); - var errorArray = []; - var minErrCount = 999999; - for (var i = 0; i < arrDoc.length; i++) { - var arrError = testParamFormat(args, arrDoc[i]); - if( arrError.length === 0) { - return; // no error - } - // see if this is the format with min number of err - if( minErrCount > arrError.length) { - minErrCount = arrError.length; - errorArray = arrError; - } + /** + * Prints out a fancy, colorful message to the console log + * + * @private + * @param {String} message the words to be said + * @param {String} func the name of the function to link + * @param {Number|String} color CSS color string or error type + * + * @return console logs + */ + // Wrong number of params, undefined param, wrong type + var FILE_LOAD = 3; + var ERR_PARAMS = 3; + // p5.js blue, p5.js orange, auto dark green; fallback p5.js darkened magenta + // See testColors below for all the color codes and names + var typeColors = ['#2D7BB6', '#EE9900', '#4DB200', '#C83C00']; + var report = function (message, func, color) { + if (doFriendlyWelcome) { + friendlyWelcome(); + doFriendlyWelcome = false; } - // generate err msg - for (var n = 0; n < errorArray.length; n++) { - p5._friendlyParamError(errorArray[n], func); + if ('undefined' === getType(color)) { + color = '#B40033'; // dark magenta + } else if (getType(color) === 'number') { // Type to color + color = typeColors[color]; } + if (func.substring(0, 4) === 'load') { + console.log( + '> p5.js says: ' + message + + '[https://github.com/processing/p5.js/wiki/Local-server]' + ); } - catch (err) { - console.log('validation error: ' + err); - } -}; -// validateParameters() helper functions: -// lookupParamDoc() for querying data.json -function lookupParamDoc(func){ - var queryResult = arrDoc.classitems. - filter(function (x) { return x.name === func; }); - // different JSON structure for funct with multi-format - var res = []; - if (queryResult[0].hasOwnProperty('overloads')){ - for(var i = 0; i < queryResult[0].overloads.length; i++) { - res.push(queryResult[0].overloads[i].params); + else { + console.log( + '> p5.js says: ' + message + ' [http://p5js.org/reference/#p5/' + func + + ']' + ); } - } else { + }; + + var errorCases = { + '0': { + fileType: 'image', + method: 'loadImage', + message: ' hosting the image online,' + }, + '1': { + fileType: 'XML file', + method: 'loadXML' + }, + '2': { + fileType: 'table file', + method: 'loadTable' + }, + '3': { + fileType: 'text file', + method: 'loadStrings' + }, + '4': { + fileType: 'font', + method: 'loadFont', + message: ' hosting the font online,' + }, + }; + p5._friendlyFileLoadError = function (errorType, filePath) { + var errorInfo = errorCases[errorType]; + var message = 'It looks like there was a problem' + + ' loading your ' + errorInfo.fileType + '.' + + ' Try checking if the file path [' + filePath + '] is correct,' + + (errorInfo.message || '') + ' or running a local server.'; + report(message, errorInfo.method, FILE_LOAD); + }; + + var docCache = {}; + var builtinTypes = [ + 'number', 'string', 'boolean', + 'constant', 'function', 'integer' + ]; + + // validateParameters() helper functions: + // lookupParamDoc() for querying data.json + var lookupParamDoc = function (func) { + var queryResult = arrDoc.classitems. + filter(function (x) { return x.name === func; }); + // different JSON structure for funct with multi-format + var res = []; + if (queryResult[0].hasOwnProperty('overloads')) { + for (var i = 0; i < queryResult[0].overloads.length; i++) { + res.push(queryResult[0].overloads[i].params); + } + } else { res.push(queryResult[0].params); - } - var builtinTypes = [ - 'number', 'string', 'boolean', - 'constant', 'function', 'integer' - ]; + } + + var mapConstants = {}; res.forEach(function (formats) { formats.forEach(function (format) { format.types = format.type.split('|').map(function ct(type) { + // array if (type.substr(type.length - 2, 2) === '[]') { return { name: type, array: ct(type.substr(0, type.length - 2)) }; -} + } var lowerType = type.toLowerCase(); + + // contant + if (lowerType === 'constant') { + + var constant; + if (mapConstants.hasOwnProperty(format.name)) { + constant = mapConstants[format.name]; + } else { + // parse possible constant values from description + var myRe = /either\s+(?:[A-Z0-9_]+\s*,?\s*(?:or)?\s*)+/g; + var values = {}; + var names = []; + + constant = mapConstants[format.name] = { + values: values, names: names + }; + + var myArray = myRe.exec(format.description); + if (func === 'endShape' && format.name === 'mode') { + values[p5.CLOSE] = true; + names.push('CLOSE'); + } else { + var match = myArray[0]; + var reConst = /[A-Z0-9_]+/g; + var matchConst; + while ((matchConst = reConst.exec(match)) !== null) { + var name = matchConst[0]; + if (p5.prototype.hasOwnProperty(name)) { + values[p5.prototype[name]] = true; + names.push(name); + } + } + } + } + return { + name: type, builtin: lowerType, + names: constant.names, values: constant.values + }; + } + + // function if (lowerType.substr(0, 'function'.length) === 'function') { lowerType = 'function'; - } + } + // builtin if (builtinTypes.indexOf(lowerType) >= 0) { return { name: type, builtin: lowerType }; - } + } + // p5 class type var t = window; type.split('.').forEach(function (p) { t = t && t[p]; }); if (t) { return { name: type, prototype: t }; - } + } return { name: type, type: lowerType }; }); }); }); return res; - } - function testParamFormat(args, formats) { - var errorArray = []; - for (var p = 0; p < formats.length; p++) { - var arg = args[p]; - var format = formats[p]; - var argType = typeof (arg); - if ('undefined' === argType || null === arg) { - if (format.optional !== true) { - errorArray.push({ - type: 'EMPTY_VAR', - position: p, - correctType: format.type, - }); - } - } else if (!testParamTypes(arg, format.types)) { - errorArray.push({ - type: 'WRONG_TYPE', - position: p, - correctType: format.type, - wrongType: arg instanceof Array ? 'array' : arg.name || argType - }); - } - } - return errorArray; -} - // testType() for non-object type parameter validation -// Returns true if PASS, false if FAIL - function testParamTypes(param, types) { - for (var i = 0; i < types.length; i++) { - if (testParamType(param, types[i])) { - return true; - } - } - return false; - } - function testParamType(param, type) { + }; + + var testParamType = function (param, type) { var isArray = param instanceof Array; if (type.array && isArray) { for (var i = 0; i < param.length; i++) { if (!testParamType(param[i], type.array)) { - return false; -} - } + return false; + } + } return true; - } + } else if (type.prototype) { return param instanceof type.prototype; -} + } else if (type.builtin) { switch (type.builtin) { case 'number': @@ -269,76 +254,152 @@ function lookupParamDoc(func){ case 'array': return isArray; case 'string': - case 'constant': return typeof param === 'number' || typeof param === 'string'; + case 'constant': + return type.values.hasOwnProperty(param); case 'function': return param instanceof Function; } } return typeof param === type.t; - } -// function for generating console.log() msg -p5._friendlyParamError = function (errorObj, func) { - var message; - switch (errorObj.type){ - case 'EMPTY_VAR': - message = func + '() was expecting ' + errorObj.correctType + - ' for parameter #' + errorObj.position + ' (zero-based index), received' + - ' an empty variable instead. If not intentional, this is often a problem' + - ' with scope: [https://p5js.org/examples/data-variable-scope.html].'; - report(message, func, ERR_PARAMS); - break; - case 'WRONG_TYPE': - message = func + '() was expecting ' + errorObj.correctType + - ' for parameter #' + errorObj.position + ' (zero-based index), received '; - // Wrap strings in quotes - message += errorObj.wrongType + ' instead.'; - report(message, func, ERR_PARAMS); - } -}; -function friendlyWelcome() { - // p5.js brand - magenta: #ED225D - //var astrixBgColor = 'transparent'; - //var astrixTxtColor = '#ED225D'; - //var welcomeBgColor = '#ED225D'; - //var welcomeTextColor = 'white'; - console.log( - ' _ \n'+ - ' /\\| |/\\ \n'+ - ' \\ ` \' / \n'+ - ' / , . \\ \n'+ - ' \\/|_|\\/ '+ - '\n\n> p5.js says: Welcome! '+ - 'This is your friendly debugger. ' + - 'To turn me off switch to using “p5.min.js”.' - ); + }; + + // testType() for non-object type parameter validation + // Returns true if PASS, false if FAIL + var testParamTypes = function (param, types) { + for (var i = 0; i < types.length; i++) { + if (testParamType(param, types[i])) { + return true; + } + } + return false; + }; + + var testParamFormat = function (args, formats) { + var errorArray = []; + for (var p = 0; p < formats.length; p++) { + var arg = args[p]; + var format = formats[p]; + var argType = typeof (arg); + if ('undefined' === argType || null === arg) { + if (format.optional !== true) { + errorArray.push({ + type: 'EMPTY_VAR', + position: p, + format: format, + }); + } + } else if (!testParamTypes(arg, format.types)) { + errorArray.push({ + type: 'WRONG_TYPE', + position: p, + format: format, + arg: arg + }); + } + } + return errorArray; + }; + + // function for generating console.log() msg + p5._friendlyParamError = function (errorObj, func) { + var message; + var format = errorObj.format; + var formatType = format.types.map(function (type) { + return type.names ? type.names.join('|') : type.name; + }).join('|'); + + switch (errorObj.type) { + case 'EMPTY_VAR': + message = func + '() was expecting ' + formatType + + ' for parameter #' + errorObj.position + + ' (zero-based index), received an empty variable instead.' + + ' If not intentional, this is often a problem with scope:' + + ' [https://p5js.org/examples/data-variable-scope.html].'; + report(message, func, ERR_PARAMS); + break; + case 'WRONG_TYPE': + var arg = errorObj.arg; + var argType = arg instanceof Array ? 'array' : arg.name || typeof arg; + message = func + '() was expecting ' + formatType + + ' for parameter #' + errorObj.position + + ' (zero-based index), received ' + argType + ' instead.'; + report(message, func, ERR_PARAMS); + } + }; + + /** + * Validates parameters + * param {String} func the name of the function + * param {Array} args user input arguments + * + * example: + * var a; + * ellipse(10,10,a,5); + * console ouput: + * "It looks like ellipse received an empty variable in spot #2." + * + * example: + * ellipse(10,"foo",5,5); + * console output: + * "ellipse was expecting a number for parameter #1, + * received "foo" instead." + */ + p5._validateParameters = function validateParameters(func, args) { + if (p5.disableFriendlyErrors) { + return; // skip FES + } + + var arrDoc = docCache[func] || (docCache[func] = lookupParamDoc(func)); + var errorArray = []; + var minErrCount = 999999; + for (var i = 0; i < arrDoc.length; i++) { + var arrError = testParamFormat(args, arrDoc[i]); + if (arrError.length === 0) { + return; // no error + } + // see if this is the format with min number of err + if (minErrCount > arrError.length) { + minErrCount = arrError.length; + errorArray = arrError; + } + } + // generate err msg + for (var n = 0; n < errorArray.length; n++) { + p5._friendlyParamError(errorArray[n], func); + } + }; + + + /** + * Prints out all the colors in the color pallete with white text. + * For color blindness testing. + */ + /* function testColors() { + var str = 'A box of biscuits, a box of mixed biscuits and a biscuit mixer'; + report(str, 'print', '#ED225D'); // p5.js magenta + report(str, 'print', '#2D7BB6'); // p5.js blue + report(str, 'print', '#EE9900'); // p5.js orange + report(str, 'print', '#A67F59'); // p5.js light brown + report(str, 'print', '#704F21'); // p5.js gold + report(str, 'print', '#1CC581'); // auto cyan + report(str, 'print', '#FF6625'); // auto orange + report(str, 'print', '#79EB22'); // auto green + report(str, 'print', '#B40033'); // p5.js darkened magenta + report(str, 'print', '#084B7F'); // p5.js darkened blue + report(str, 'print', '#945F00'); // p5.js darkened orange + report(str, 'print', '#6B441D'); // p5.js darkened brown + report(str, 'print', '#2E1B00'); // p5.js darkened gold + report(str, 'print', '#008851'); // auto dark cyan + report(str, 'print', '#C83C00'); // auto dark orange + report(str, 'print', '#4DB200'); // auto dark green + } */ + + p5.prototype._validateParameters = p5.validateParameters; } -/** - * Prints out all the colors in the color pallete with white text. - * For color blindness testing. - */ -/* function testColors() { - var str = 'A box of biscuits, a box of mixed biscuits and a biscuit mixer'; - report(str, 'print', '#ED225D'); // p5.js magenta - report(str, 'print', '#2D7BB6'); // p5.js blue - report(str, 'print', '#EE9900'); // p5.js orange - report(str, 'print', '#A67F59'); // p5.js light brown - report(str, 'print', '#704F21'); // p5.js gold - report(str, 'print', '#1CC581'); // auto cyan - report(str, 'print', '#FF6625'); // auto orange - report(str, 'print', '#79EB22'); // auto green - report(str, 'print', '#B40033'); // p5.js darkened magenta - report(str, 'print', '#084B7F'); // p5.js darkened blue - report(str, 'print', '#945F00'); // p5.js darkened orange - report(str, 'print', '#6B441D'); // p5.js darkened brown - report(str, 'print', '#2E1B00'); // p5.js darkened gold - report(str, 'print', '#008851'); // auto dark cyan - report(str, 'print', '#C83C00'); // auto dark orange - report(str, 'print', '#4DB200'); // auto dark green -} */ // This is a lazily-defined list of p5 symbols that may be // misused by beginners at top-level code, outside of setup/draw. We'd like @@ -348,15 +409,15 @@ function friendlyWelcome() { // For more details, see https://github.com/processing/p5.js/issues/1121. var misusedAtTopLevelCode = null; var FAQ_URL = 'https://github.com/processing/p5.js/wiki/' + - 'Frequently-Asked-Questions' + - '#why-cant-i-assign-variables-using-p5-functions-and-' + - 'variables-before-setup'; + 'Frequently-Asked-Questions' + + '#why-cant-i-assign-variables-using-p5-functions-and-' + + 'variables-before-setup'; -function defineMisusedAtTopLevelCode() { +var defineMisusedAtTopLevelCode = function () { var uniqueNamesFound = {}; - var getSymbols = function(obj) { - return Object.getOwnPropertyNames(obj).filter(function(name) { + var getSymbols = function (obj) { + return Object.getOwnPropertyNames(obj).filter(function (name) { if (name[0] === '_') { return false; } @@ -367,10 +428,10 @@ function defineMisusedAtTopLevelCode() { uniqueNamesFound[name] = true; return true; - }).map(function(name) { + }).map(function (name) { var type; - if (typeof(obj[name]) === 'function') { + if (typeof (obj[name]) === 'function') { type = 'function'; } else if (name === name.toUpperCase()) { type = 'constant'; @@ -378,7 +439,7 @@ function defineMisusedAtTopLevelCode() { type = 'variable'; } - return {name: name, type: type}; + return { name: name, type: type }; }); }; @@ -393,12 +454,12 @@ function defineMisusedAtTopLevelCode() { // This will ultimately ensure that we report the most specific error // possible to the user, e.g. advising them about HALF_PI instead of PI // when their code misuses the former. - misusedAtTopLevelCode.sort(function(a, b) { + misusedAtTopLevelCode.sort(function (a, b) { return b.name.length - a.name.length; }); -} +}; -function helpForMisusedAtTopLevelCode(e, log) { +var helpForMisusedAtTopLevelCode = function (e, log) { if (!log) { log = console.log.bind(console); } @@ -416,7 +477,7 @@ function helpForMisusedAtTopLevelCode(e, log) { // return; //} - misusedAtTopLevelCode.some(function(symbol) { + misusedAtTopLevelCode.some(function (symbol) { // Note that while just checking for the occurrence of the // symbol name in the error message could result in false positives, // a more rigorous test is difficult because different browsers @@ -430,20 +491,19 @@ function helpForMisusedAtTopLevelCode(e, log) { // * ReferenceError: PI is undefined (Firefox) // * Uncaught ReferenceError: PI is not defined (Chrome) - if (e.message && e.message.match('\\W?'+symbol.name+'\\W') !== null) { + if (e.message && e.message.match('\\W?' + symbol.name + '\\W') !== null) { log('Did you just try to use p5.js\'s ' + symbol.name + - (symbol.type === 'function' ? '() ' : ' ') + symbol.type + - '? If so, you may want to ' + - 'move it into your sketch\'s setup() function.\n\n' + - 'For more details, see: ' + FAQ_URL); + (symbol.type === 'function' ? '() ' : ' ') + symbol.type + + '? If so, you may want to ' + + 'move it into your sketch\'s setup() function.\n\n' + + 'For more details, see: ' + FAQ_URL); return true; } }); -} +}; // Exposing this primarily for unit testing. p5.prototype._helpForMisusedAtTopLevelCode = helpForMisusedAtTopLevelCode; -p5.prototype._validateParameters = p5.validateParameters; if (document.readyState !== 'complete') { window.addEventListener('error', helpForMisusedAtTopLevelCode, false); @@ -452,11 +512,9 @@ if (document.readyState !== 'complete') { // global (non-instance mode) p5 APIs are used at the top-level // scope of a file, so we'll unbind our error listener now to make // sure we don't log false positives later. - window.addEventListener('load', function() { + window.addEventListener('load', function () { window.removeEventListener('error', helpForMisusedAtTopLevelCode, false); }); } -} - module.exports = p5; From defb773f45c8bb79e8149c5d74e5cb52bb50575d Mon Sep 17 00:00:00 2001 From: Spongman Date: Tue, 24 Oct 2017 15:54:12 -0700 Subject: [PATCH 03/31] specify {Integer} numeric parameter types, where appropriate # Conflicts: # src/io/p5.Table.js --- src/core/environment.js | 2 +- src/events/keyboard.js | 2 +- src/io/p5.Table.js | 44 +++++++++++++++---------------- src/io/p5.TableRow.js | 12 ++++----- src/io/p5.XML.js | 6 ++--- src/math/calculation.js | 14 +++++++--- src/utilities/array_functions.js | 16 +++++------ src/utilities/string_functions.js | 28 ++++++++++---------- src/utilities/time_date.js | 12 ++++----- 9 files changed, 72 insertions(+), 64 deletions(-) diff --git a/src/core/environment.js b/src/core/environment.js index 1cb52d2f37..faf10c8bef 100644 --- a/src/core/environment.js +++ b/src/core/environment.js @@ -53,7 +53,7 @@ p5.prototype.print = function(args) { * been displayed since the program started. Inside setup() the value is 0, * after the first iteration of draw it is 1, etc. * - * @property {Number} frameCount + * @property {Integer} frameCount * @readOnly * @example *
diff --git a/src/events/keyboard.js b/src/events/keyboard.js index 3916ed85d1..e8a010c8fc 100644 --- a/src/events/keyboard.js +++ b/src/events/keyboard.js @@ -79,7 +79,7 @@ p5.prototype.key = ''; * You can also check for custom keys by looking up the keyCode of any key * on a site like this: keycode.info. * - * @property {Number} keyCode + * @property {Integer} keyCode * @readOnly * @example *
diff --git a/src/io/p5.Table.js b/src/io/p5.Table.js index 13017c8615..c5c6b8dc19 100644 --- a/src/io/p5.Table.js +++ b/src/io/p5.Table.js @@ -122,7 +122,7 @@ p5.Table.prototype.addRow = function(row) { * Removes a row from the table object. * * @method removeRow - * @param {Number} id ID number of the row to remove + * @param {Integer} id ID number of the row to remove * * @example *
@@ -172,7 +172,7 @@ p5.Table.prototype.removeRow = function(id) { * can then be used to get and set values of the selected row. * * @method getRow - * @param {Number} rowID ID number of the row to get + * @param {Integer} rowID ID number of the row to get * @return {p5.TableRow} p5.TableRow object * * @example @@ -269,7 +269,7 @@ p5.Table.prototype.getRows = function() { * * @method findRow * @param {String} value The value to match - * @param {Number|String} column ID number or title of the + * @param {Integer|String} column ID number or title of the * column to search * @return {p5.TableRow} * @@ -335,7 +335,7 @@ p5.Table.prototype.findRow = function(value, column) { * * @method findRows * @param {String} value The value to match - * @param {Number|String} column ID number or title of the + * @param {Integer|String} column ID number or title of the * column to search * @return {p5.TableRow[]} An Array of TableRow objects * @@ -405,7 +405,7 @@ p5.Table.prototype.findRows = function(value, column) { * * @method matchRow * @param {String} regexp The regular expression to match - * @param {String|Number} column The column ID (number) or + * @param {String|Integer} column The column ID (number) or * title (string) * @return {p5.TableRow} TableRow object */ @@ -436,7 +436,7 @@ p5.Table.prototype.matchRow = function(regexp, column) { * * @method matchRows * @param {String} regexp The regular expression to match - * @param {String|Number} [column] The column ID (number) or + * @param {String|Integer} [column] The column ID (number) or * title (string) * @return {p5.TableRow[]} An Array of TableRow objects * @example @@ -644,7 +644,7 @@ p5.Table.prototype.addColumn = function(title) { /** * Returns the total number of columns in a Table. * - * @return {Number} Number of columns in this table + * @return {Integer} Number of columns in this table */ p5.Table.prototype.getColumnCount = function() { return this.columns.length; @@ -654,7 +654,7 @@ p5.Table.prototype.getColumnCount = function() { * Returns the total number of rows in a Table. * * @method getRowCount - * @return {Number} Number of rows in this table + * @return {Integer} Number of rows in this table */ p5.Table.prototype.getRowCount = function() { @@ -670,7 +670,7 @@ p5.Table.prototype.getRowCount = function() { * * @method removeTokens * @param {String} chars String listing characters to be removed - * @param {String|Number} [column] Column ID (number) + * @param {String|Integer} [column] Column ID (number) * or name (string) */ p5.Table.prototype.removeTokens = function(chars, column) { @@ -719,7 +719,7 @@ p5.Table.prototype.removeTokens = function(chars, column) { * may be referenced by either its ID or title. * * @method trim - * @param {String|Number} column Column ID (number) + * @param {String|Integer} column Column ID (number) * or name (string) */ p5.Table.prototype.trim = function(column) { @@ -762,7 +762,7 @@ p5.Table.prototype.trim = function(column) { * would remove the second column, and so on. * * @method removeColumn - * @param {String|Number} column columnName (string) or ID (number) + * @param {String|Integer} column columnName (string) or ID (number) * * @example *
@@ -829,7 +829,7 @@ p5.Table.prototype.removeColumn = function(c) { * by either its ID or title. * * @method set - * @param {String|Number} column column ID (Number) + * @param {String|Integer} column column ID (Number) * or title (String) * @param {String|Number} value value to assign * @@ -878,8 +878,8 @@ p5.Table.prototype.set = function(row, column, value) { * by either its ID or title. * * @method setNum - * @param {Number} row row ID - * @param {String|Number} column column ID (Number) + * @param {Integer} row row ID + * @param {String|Integer} column column ID (Number) * or title (String) * @param {Number} value value to assign * @@ -925,8 +925,8 @@ p5.Table.prototype.setNum = function(row, column, value){ * by either its ID or title. * * @method setString - * @param {Number} row row ID - * @param {String|Number} column column ID (Number) + * @param {Integer} row row ID + * @param {String|Integer} column column ID (Number) * or title (String) * @param {String} value value to assign */ @@ -940,8 +940,8 @@ p5.Table.prototype.setString = function(row, column, value){ * either its ID or title. * * @method get - * @param {Number} row row ID - * @param {String|Number} column columnName (string) or + * @param {Integer} row row ID + * @param {String|Integer} column columnName (string) or * ID (number) * @return {String|Number} * @@ -987,8 +987,8 @@ p5.Table.prototype.get = function(row, column) { * either its ID or title. * * @method getNum - * @param {Number} row row ID - * @param {String|Number} column columnName (string) or + * @param {Integer} row row ID + * @param {String|Integer} column columnName (string) or * ID (number) * @return {Number} * @@ -1032,8 +1032,8 @@ p5.Table.prototype.getNum = function(row, column) { * either its ID or title. * * @method getString - * @param {Number} row row ID - * @param {String|Number} column columnName (string) or + * @param {Integer} row row ID + * @param {String|Integer} column columnName (string) or * ID (number) * @return {String} * diff --git a/src/io/p5.TableRow.js b/src/io/p5.TableRow.js index 0218bd92db..f72d4787b0 100644 --- a/src/io/p5.TableRow.js +++ b/src/io/p5.TableRow.js @@ -45,7 +45,7 @@ p5.TableRow = function (str, separator) { * The column may be specified by either its ID or title. * * @method set - * @param {String|Number} column Column ID (Number) + * @param {String|Integer} column Column ID (Number) * or Title (String) * @param {String|Number} value The value to be stored */ @@ -81,7 +81,7 @@ p5.TableRow.prototype.set = function(column, value) { * The column may be specified by either its ID or title. * * @method setNum - * @param {String|Number} column Column ID (Number) + * @param {String|Integer} column Column ID (Number) * or Title (String) * @param {Number} value The value to be stored * as a Float @@ -97,7 +97,7 @@ p5.TableRow.prototype.setNum = function(column, value){ * The column may be specified by either its ID or title. * * @method setString - * @param {String|Number} column Column ID (Number) + * @param {String|Integer} column Column ID (Number) * or Title (String) * @param {String} value The value to be stored * as a String @@ -112,7 +112,7 @@ p5.TableRow.prototype.setString = function(column, value){ * The column may be specified by either its ID or title. * * @method get - * @param {String|Number} column columnName (string) or + * @param {String|Integer} column columnName (string) or * ID (number) * @return {String|Number} */ @@ -130,7 +130,7 @@ p5.TableRow.prototype.get = function(column) { * title. * * @method getNum - * @param {String|Number} column columnName (string) or + * @param {String|Integer} column columnName (string) or * ID (number) * @return {Number} Float Floating point number */ @@ -154,7 +154,7 @@ p5.TableRow.prototype.getNum = function(column) { * title. * * @method getString - * @param {String|Number} column columnName (string) or + * @param {String|Integer} column columnName (string) or * ID (number) * @return {String} String */ diff --git a/src/io/p5.XML.js b/src/io/p5.XML.js index 05d989af84..9e28b1b29f 100644 --- a/src/io/p5.XML.js +++ b/src/io/p5.XML.js @@ -302,7 +302,7 @@ p5.XML.prototype.getChildren = function(param) { * child is found. * * @method getChild - * @param {String|Number} name element name or index + * @param {String|Integer} name element name or index * @return {p5.XML} * @example<animal *
@@ -378,7 +378,7 @@ p5.XML.prototype.addChild = function(node) { * Removes the element specified by name or index. * * @method removeChild - * @param {String|Number} name element name or index + * @param {String|Integer} name element name or index * @example *
* // The following short XML file called "mammals.xml" is parsed @@ -451,7 +451,7 @@ p5.XML.prototype.removeChild = function(param) { * Counts the specified element's number of attributes, returned as an Number. * * @method getAttributeCount - * @return {Number} + * @return {Integer} * @example *
* // The following short XML file called "mammals.xml" is parsed diff --git a/src/math/calculation.js b/src/math/calculation.js index df71edcd31..ff9229028e 100644 --- a/src/math/calculation.js +++ b/src/math/calculation.js @@ -40,7 +40,7 @@ p5.prototype.abs = Math.abs; * * @method ceil * @param {Number} n number to round up - * @return {Number} rounded up number + * @return {Integer} rounded up number * @example *
* function draw() { @@ -114,6 +114,7 @@ p5.prototype.ceil = Math.ceil; * */ p5.prototype.constrain = function(n, low, high) { + p5._validateParameters('constrain', arguments); return Math.max(Math.min(n, high), low); }; @@ -172,6 +173,7 @@ p5.prototype.constrain = function(n, low, high) { * */ p5.prototype.dist = function() { + p5._validateParameters('dist', arguments); if (arguments.length === 4) { //2D return hypot(arguments[2]-arguments[0], arguments[3]-arguments[1]); } else if (arguments.length === 6) { //3D @@ -237,7 +239,7 @@ p5.prototype.exp = Math.exp; * * @method floor * @param {Number} n number to round down - * @return {Number} rounded down number + * @return {Integer} rounded down number * @example *
* function draw() { @@ -311,6 +313,7 @@ p5.prototype.floor = Math.floor; * */ p5.prototype.lerp = function(start, stop, amt) { + p5._validateParameters('lerp', arguments); return amt*(stop-start)+start; }; @@ -403,6 +406,7 @@ p5.prototype.log = Math.log; * */ p5.prototype.mag = function(x, y) { + p5._validateParameters('mag', arguments); return hypot(x, y); }; @@ -450,6 +454,7 @@ p5.prototype.mag = function(x, y) { * */ p5.prototype.map = function (n, start1, stop1, start2, stop2, withinBounds) { + p5._validateParameters('map', arguments); var newval = ((n - start1)/(stop1 - start1)) * (stop2 - start2) + start2; if (!withinBounds) { return newval; @@ -497,6 +502,7 @@ p5.prototype.map = function (n, start1, stop1, start2, stop2, withinBounds) { * */ p5.prototype.max = function() { + p5._validateParameters('max', arguments); if (arguments[0] instanceof Array) { return Math.max.apply(null,arguments[0]); } else { @@ -540,6 +546,7 @@ p5.prototype.max = function() { * */ p5.prototype.min = function() { + p5._validateParameters('min', arguments); if (arguments[0] instanceof Array) { return Math.min.apply(null,arguments[0]); } else { @@ -596,6 +603,7 @@ p5.prototype.min = function() { * */ p5.prototype.norm = function(n, start, stop) { + p5._validateParameters('norm', arguments); return this.map(n, start, stop, 0, 1); }; @@ -639,7 +647,7 @@ p5.prototype.pow = Math.pow; * * @method round * @param {Number} n number to round - * @return {Number} rounded number + * @return {Integer} rounded number * @example *
* function draw() { diff --git a/src/utilities/array_functions.js b/src/utilities/array_functions.js index b46c6bd570..3a578e10e9 100644 --- a/src/utilities/array_functions.js +++ b/src/utilities/array_functions.js @@ -51,16 +51,16 @@ p5.prototype.append = function(array, value) { * * @method arrayCopy * @param {Array} src the source Array - * @param {Number} srcPosition starting position in the source Array + * @param {Integer} srcPosition starting position in the source Array * @param {Array} dst the destination Array - * @param {Number} dstPosition starting position in the destination Array - * @param {Number} length number of Array elements to be copied + * @param {Integer} dstPosition starting position in the destination Array + * @param {Integer} length number of Array elements to be copied */ /** * @method arrayCopy * @param {Array} src * @param {Array} dst - * @param {Number} [length] + * @param {Integer} [length] * * @example *
@@ -245,7 +245,7 @@ p5.prototype.shuffle = function(arr, bool) { * * @method sort * @param {Array} list Array to sort - * @param {Number} [count] number of elements to sort, starting from 0 + * @param {Integer} [count] number of elements to sort, starting from 0 * * @example *
@@ -291,7 +291,7 @@ p5.prototype.sort = function(list, count) { * @method splice * @param {Array} list Array to splice into * @param {any} value value to be spliced in - * @param {Number} position in the array from which to insert data + * @param {Integer} position in the array from which to insert data * * @example *
@@ -324,8 +324,8 @@ p5.prototype.splice = function(list, value, index) { * * @method subset * @param {Array} list Array to extract from - * @param {Number} start position to begin - * @param {Number} [count] number of values to extract + * @param {Integer} start position to begin + * @param {Integer} [count] number of values to extract * @return {Array} Array of extracted elements * * @example diff --git a/src/utilities/string_functions.js b/src/utilities/string_functions.js index ae8c28ef14..7b971849b1 100644 --- a/src/utilities/string_functions.js +++ b/src/utilities/string_functions.js @@ -137,17 +137,17 @@ p5.prototype.matchAll = function(str, reg) { * * @method nf * @param {Number|String} num the Number to format - * @param {Number|String} [left] number of digits to the left of the + * @param {Integer|String} [left] number of digits to the left of the * decimal point - * @param {Number|String} [right] number of digits to the right of the + * @param {Integer|String} [right] number of digits to the right of the * decimal point * @return {String} formatted String */ /** * @method nf * @param {Array} nums the Numbers to format - * @param {Number|String} [left] - * @param {Number|String} [right] + * @param {Integer|String} [left] + * @param {Integer|String} [right] * @return {String[]} formatted Strings * @example *
@@ -250,14 +250,14 @@ function doNf() { * * @method nfc * @param {Number|String} num the Number to format - * @param {Number|String} [right] number of digits to the right of the + * @param {Integer|String} [right] number of digits to the right of the * decimal point * @return {String} formatted String */ /** * @method nfc * @param {Array} nums the Numbers to format - * @param {Number|String} [right] + * @param {Integer|String} [right] * @return {String[]} formatted Strings * @example *
@@ -330,17 +330,17 @@ function doNfc() { * * @method nfp * @param {Number} num the Number to format - * @param {Number} [left] number of digits to the left of the decimal + * @param {Integer} [left] number of digits to the left of the decimal * point - * @param {Number} [right] number of digits to the right of the + * @param {Integer} [right] number of digits to the right of the * decimal point * @return {String} formatted String */ /** * @method nfp * @param {Number[]} nums the Numbers to format - * @param {Number} [left] - * @param {Number} [right] + * @param {Integer} [left] + * @param {Integer} [right] * @return {String[]} formatted Strings * @example *
@@ -395,17 +395,17 @@ function addNfp() { * * @method nfs * @param {Number} num the Number to format - * @param {Number} [left] number of digits to the left of the decimal + * @param {Integer} [left] number of digits to the left of the decimal * point - * @param {Number} [right] number of digits to the right of the + * @param {Integer} [right] number of digits to the right of the * decimal point * @return {String} formatted String */ /** * @method nfs * @param {Array} nums the Numbers to format - * @param {Number} [left] - * @param {Number} [right] + * @param {Integer} [left] + * @param {Integer} [right] * @return {String[]} formatted Strings * @example *
diff --git a/src/utilities/time_date.js b/src/utilities/time_date.js index 956df51f3e..03cb306670 100644 --- a/src/utilities/time_date.js +++ b/src/utilities/time_date.js @@ -14,7 +14,7 @@ var p5 = require('../core/core'); * returns the current day as a value from 1 - 31. * * @method day - * @return {Number} the current day + * @return {Integer} the current day * @example *
* @@ -36,7 +36,7 @@ p5.prototype.day = function() { * returns the current hour as a value from 0 - 23. * * @method hour - * @return {Number} the current hour + * @return {Integer} the current hour * @example *
* @@ -58,7 +58,7 @@ p5.prototype.hour = function() { * returns the current minute as a value from 0 - 59. * * @method minute - * @return {Number} the current minute + * @return {Integer} the current minute * @example *
* @@ -103,7 +103,7 @@ p5.prototype.millis = function() { * returns the current month as a value from 1 - 12. * * @method month - * @return {Number} the current month + * @return {Integer} the current month * @example *
* @@ -125,7 +125,7 @@ p5.prototype.month = function() { * returns the current second as a value from 0 - 59. * * @method second - * @return {Number} the current second + * @return {Integer} the current second * @example *
* @@ -147,7 +147,7 @@ p5.prototype.second = function() { * returns the current year as an integer (2014, 2015, 2016, etc). * * @method year - * @return {Number} the current year + * @return {Integer} the current year * @example *
* From 65facf9fc943caeb888368408346086786f92aa8 Mon Sep 17 00:00:00 2001 From: Spongman Date: Tue, 24 Oct 2017 17:45:36 -0700 Subject: [PATCH 04/31] add 'OPEN' to list of arc-mode constants --- src/core/2d_primitives.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/2d_primitives.js b/src/core/2d_primitives.js index 0e39a6f69c..222404dd55 100644 --- a/src/core/2d_primitives.js +++ b/src/core/2d_primitives.js @@ -32,7 +32,7 @@ require('./error_helpers'); * @param {Number} start angle to start the arc, specified in radians * @param {Number} stop angle to stop the arc, specified in radians * @param {Constant} [mode] optional parameter to determine the way of drawing - * the arc. either CHORD or PIE + * the arc. either CHORD, PIE or OPEN * @chainable * @example *
From 32ec2590770dc9f04095d2e03666110f505a5ffe Mon Sep 17 00:00:00 2001 From: Spongman Date: Tue, 24 Oct 2017 21:51:08 -0700 Subject: [PATCH 05/31] remove data.json from minified version --- Gruntfile.js | 4 ++-- tasks/build/browserify.js | 24 +++++++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index ed99cbdea1..95fe664f4e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -265,7 +265,7 @@ module.exports = function(grunt) { }, dist: { files: { - 'lib/p5.min.js': 'lib/p5.js', + 'lib/p5.min.js': 'lib/p5.pre-min.js', 'lib/addons/p5.dom.min.js': 'lib/addons/p5.dom.js' } } @@ -352,7 +352,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-update-json'); // Create the multitasks. - grunt.registerTask('build', ['browserify', 'uglify', 'requirejs']); + grunt.registerTask('build', ['browserify', 'browserify:min', 'uglify', 'requirejs']); grunt.registerTask('test', ['jshint', 'jscs', 'yuidoc:prod', 'build', 'connect', 'mocha', 'mochaTest']); grunt.registerTask('test:nobuild', ['jshint:test', 'jscs:test', 'connect', 'mocha']); grunt.registerTask('yui', ['yuidoc:prod', 'minjson']); diff --git a/tasks/build/browserify.js b/tasks/build/browserify.js index 23c2403913..51ff980810 100644 --- a/tasks/build/browserify.js +++ b/tasks/build/browserify.js @@ -10,10 +10,14 @@ module.exports = function(grunt) { var srcFilePath = require.resolve('../../src/app.js'); - // This file will not exist until it has been built - var libFilePath = path.resolve('lib/p5.js'); + grunt.registerTask('browserify', 'Compile the p5.js source with Browserify', function(param) { + + var isMin = param === 'min'; + var filename = isMin ? 'p5.pre-min.js' : 'p5.js'; + + // This file will not exist until it has been built + var libFilePath = path.resolve('lib/' + filename); - grunt.registerTask('browserify', 'Compile the p5.js source with Browserify', function() { // Reading and writing files is asynchronous var done = this.async(); @@ -21,9 +25,15 @@ module.exports = function(grunt) { var banner = grunt.template.process(bannerTemplate); // Invoke Browserify programatically to bundle the code - var bundle = browserify(srcFilePath, { - standalone: 'p5' - }) + var browseified = browserify(srcFilePath, { + standalone: 'p5' + }); + + if (isMin) { + browseified = browseified.exclude('../../docs/reference/data.json'); + } + + var bundle = browseified .transform('brfs') .bundle(); @@ -43,7 +53,7 @@ module.exports = function(grunt) { grunt.file.write(libFilePath, derequire(code)); // Print a success message - grunt.log.writeln('>>'.green + ' Bundle ' + 'lib/p5.js'.cyan + ' created.'); + grunt.log.writeln('>>'.green + ' Bundle ' + ('lib/' + filename).cyan + ' created.'); // Complete the task done(); From ff9737cbb9c4d93de2f24b1328361dbdbf2e457d Mon Sep 17 00:00:00 2001 From: Spongman Date: Wed, 25 Oct 2017 13:26:34 -0700 Subject: [PATCH 06/31] add FES warning for too many arguments, show error location --- src/core/error_helpers.js | 77 ++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/src/core/error_helpers.js b/src/core/error_helpers.js index f8b318fb0d..e4ae5df698 100644 --- a/src/core/error_helpers.js +++ b/src/core/error_helpers.js @@ -143,17 +143,21 @@ if (typeof IS_MINIFIED !== 'undefined') { var queryResult = arrDoc.classitems. filter(function (x) { return x.name === func; }); // different JSON structure for funct with multi-format - var res = []; + var overloads = []; if (queryResult[0].hasOwnProperty('overloads')) { for (var i = 0; i < queryResult[0].overloads.length; i++) { - res.push(queryResult[0].overloads[i].params); + overloads.push(queryResult[0].overloads[i].params); } } else { - res.push(queryResult[0].params); + overloads.push(queryResult[0].params); } var mapConstants = {}; - res.forEach(function (formats) { + var maxParams = 0; + overloads.forEach(function (formats) { + if (maxParams < formats.length) { + maxParams = formats.length; + } formats.forEach(function (format) { format.types = format.type.split('|').map(function ct(type) { @@ -226,7 +230,10 @@ if (typeof IS_MINIFIED !== 'undefined') { }); }); }); - return res; + return { + overloads: overloads, + maxParams: maxParams, + }; }; var testParamType = function (param, type) { @@ -306,27 +313,45 @@ if (typeof IS_MINIFIED !== 'undefined') { // function for generating console.log() msg p5._friendlyParamError = function (errorObj, func) { var message; - var format = errorObj.format; - var formatType = format.types.map(function (type) { - return type.names ? type.names.join('|') : type.name; - }).join('|'); + + function formatType() { + var format = errorObj.format; + return format.types.map(function (type) { + return type.names ? type.names.join('|') : type.name; + }).join('|'); + } switch (errorObj.type) { case 'EMPTY_VAR': - message = func + '() was expecting ' + formatType + + message = func + '() was expecting ' + formatType() + ' for parameter #' + errorObj.position + ' (zero-based index), received an empty variable instead.' + ' If not intentional, this is often a problem with scope:' + - ' [https://p5js.org/examples/data-variable-scope.html].'; - report(message, func, ERR_PARAMS); + ' [https://p5js.org/examples/data-variable-scope.html]'; break; case 'WRONG_TYPE': var arg = errorObj.arg; var argType = arg instanceof Array ? 'array' : arg.name || typeof arg; - message = func + '() was expecting ' + formatType + + message = func + '() was expecting ' + formatType() + ' for parameter #' + errorObj.position + - ' (zero-based index), received ' + argType + ' instead.'; - report(message, func, ERR_PARAMS); + ' (zero-based index), received ' + argType + ' instead'; + break; + case 'WRONG_ARGUMENT_COUNT': + message = func + '() was expecting ' + errorObj.maxParams + + ' arguments, but received ' + errorObj.argCount; + break; + } + + if (message) { + try { + var re = /Function\.validateParameters.*[\r\n].*[\r\n].*\(([^)]*)/; + var location = re.exec((new Error()).stack)[1]; + if (location) { + message += ' at ' + location; + } + } catch (err) { } + + report(message + '.', func, ERR_PARAMS); } }; @@ -352,20 +377,30 @@ if (typeof IS_MINIFIED !== 'undefined') { return; // skip FES } - var arrDoc = docCache[func] || (docCache[func] = lookupParamDoc(func)); + var docs = docCache[func] || (docCache[func] = lookupParamDoc(func)); var errorArray = []; var minErrCount = 999999; - for (var i = 0; i < arrDoc.length; i++) { - var arrError = testParamFormat(args, arrDoc[i]); - if (arrError.length === 0) { - return; // no error - } + var overloads = docs.overloads; + for (var i = 0; i < overloads.length; i++) { + var arrError = testParamFormat(args, overloads[i]); // see if this is the format with min number of err if (minErrCount > arrError.length) { minErrCount = arrError.length; errorArray = arrError; } + if (arrError.length === 0) { + break; // no error + } } + + if (!errorArray.length && args.length > docs.maxParams) { + errorArray.push({ + type: 'WRONG_ARGUMENT_COUNT', + argCount: args.length, + maxParams: docs.maxParams, + }); + } + // generate err msg for (var n = 0; n < errorArray.length; n++) { p5._friendlyParamError(errorArray[n], func); From a56ad1e80ab8d8b6518a798ac321da6a47b2b0cd Mon Sep 17 00:00:00 2001 From: Spongman Date: Wed, 25 Oct 2017 13:27:53 -0700 Subject: [PATCH 07/31] fix up docs for 3d primitives --- src/core/2d_primitives.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/core/2d_primitives.js b/src/core/2d_primitives.js index 222404dd55..9ae17c943a 100644 --- a/src/core/2d_primitives.js +++ b/src/core/2d_primitives.js @@ -220,6 +220,16 @@ p5.prototype.ellipse = function() { *3 lines of various stroke sizes. Form top, bottom and right sides of a square. * */ +/** + * @method line + * @param {Number} x1 + * @param {Number} y1 + * @param {Number} z1 the z-coordinate of the first point + * @param {Number} x2 + * @param {Number} y2 + * @param {Number} z2 the z-coordinate of the second point + * @chainable + */ p5.prototype.line = function() { if (!this._renderer._doStroke) { return this; @@ -252,6 +262,7 @@ p5.prototype.line = function() { * @method point * @param {Number} x the x-coordinate * @param {Number} y the y-coordinate + * @param {Number} [z] the z-coordinate * @chainable * @example *
@@ -326,12 +337,16 @@ p5.prototype.point = function() { * @method quad * @param {Number} x1 * @param {Number} y1 + * @param {Number} z1 * @param {Number} x2 * @param {Number} y2 + * @param {Number} z2 * @param {Number} x3 * @param {Number} y3 + * @param {Number} z3 * @param {Number} x4 * @param {Number} y4 + * @param {Number} z4 * @chainable */ p5.prototype.quad = function() { From 19b5a8e23617e0f35348e739050caf0dcdd2c6cd Mon Sep 17 00:00:00 2001 From: Spongman Date: Wed, 25 Oct 2017 13:28:19 -0700 Subject: [PATCH 08/31] fix nfc tests, min/max docs --- src/math/calculation.js | 30 +++++++++++++++++++++--------- src/math/p5.Vector.js | 2 +- src/utilities/string_functions.js | 4 ++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/math/calculation.js b/src/math/calculation.js index ff9229028e..072eddb76c 100644 --- a/src/math/calculation.js +++ b/src/math/calculation.js @@ -62,8 +62,8 @@ p5.prototype.abs = Math.abs; * * // Reformat the float returned by map and draw it. * noStroke(); - * text(nfc(ax, 2,2), ax, ay - 5); - * text(nfc(bx,1,1), bx, by - 5); + * text(nfc(ax, 2), ax, ay - 5); + * text(nfc(bx, 1), bx, by - 5); * } *
* @@ -162,7 +162,7 @@ p5.prototype.constrain = function(n, low, high) { * push(); * translate( (x1+x2)/2, (y1+y2)/2 ); * rotate( atan2(y2-y1,x2-x1) ); - * text(nfc(d,1,1), 0, -5); + * text(nfc(d,1), 0, -5); * pop(); * // Fancy! * } @@ -261,8 +261,8 @@ p5.prototype.exp = Math.exp; * * // Reformat the float returned by map and draw it. * noStroke(); - * text(nfc(ax, 2,2), ax, ay - 5); - * text(nfc(bx,1,1), bx, by - 5); + * text(nfc(ax, 2), ax, ay - 5); + * text(nfc(bx, 1), bx, by - 5); * } *
* @@ -472,7 +472,8 @@ p5.prototype.map = function (n, start1, stop1, start2, stop2, withinBounds) { * of any length. * * @method max - * @param {Number|Number[]} n0 Numbers to compare + * @param {Number} n0 Number to compare + * @param {Number} n1 Number to compare * @return {Number} maximum Number * @example *
@@ -501,6 +502,11 @@ p5.prototype.map = function (n, start1, stop1, start2, stop2, withinBounds) { * Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9 * */ +/** + * @method max + * @param {Number[]} nums Numbers to compare + * @return {Number} + */ p5.prototype.max = function() { p5._validateParameters('max', arguments); if (arguments[0] instanceof Array) { @@ -516,7 +522,8 @@ p5.prototype.max = function() { * of any length. * * @method min - * @param {Number|Number[]} n0 Numbers to compare + * @param {Number} n0 Number to compare + * @param {Number} n1 Number to compare * @return {Number} minimum Number * @example *
@@ -545,6 +552,11 @@ p5.prototype.max = function() { * Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1 * */ +/** + * @method min + * @param {Number[]} nums Numbers to compare + * @return {Number} + */ p5.prototype.min = function() { p5._validateParameters('min', arguments); if (arguments[0] instanceof Array) { @@ -669,8 +681,8 @@ p5.prototype.pow = Math.pow; * * // Reformat the float returned by map and draw it. * noStroke(); - * text(nfc(ax, 2,2), ax, ay - 5); - * text(nfc(bx,1,1), bx, by - 5); + * text(nfc(ax, 2), ax, ay - 5); + * text(nfc(bx, 1), bx, by - 5); * } *
* diff --git a/src/math/p5.Vector.js b/src/math/p5.Vector.js index e090a3060c..61789815fa 100644 --- a/src/math/p5.Vector.js +++ b/src/math/p5.Vector.js @@ -798,7 +798,7 @@ p5.Vector.prototype.equals = function (x, y, z) { * // Display that variable in an onscreen text. * // (Note the nfc() function to truncate additional decimal places, * // and the "\xB0" character for the degree symbol.) - * var readout = "angle = " + nfc(myDegrees,1,1) + "\xB0" + * var readout = "angle = " + nfc(myDegrees,1) + "\xB0" * noStroke(); * fill (0); * text (readout, 5, 15); diff --git a/src/utilities/string_functions.js b/src/utilities/string_functions.js index 7b971849b1..c519c6f206 100644 --- a/src/utilities/string_functions.js +++ b/src/utilities/string_functions.js @@ -272,8 +272,8 @@ function doNf() { * textSize(12); * * // Draw formatted numbers - * text(nfc(num, 4, 2), 10, 30); - * text(nfc(numArr, 2, 1), 10, 80); + * text(nfc(num, 4), 10, 30); + * text(nfc(numArr, 2), 10, 80); * * // Draw dividing line * stroke(120); From 2a5beec0cd78370d4ef7f1d1dd7bfd1c6c24fcac Mon Sep 17 00:00:00 2001 From: Spongman Date: Wed, 25 Oct 2017 13:29:01 -0700 Subject: [PATCH 09/31] remove unused argument from createCanvas call --- src/core/core.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/core.js b/src/core/core.js index c976e6a381..a55cd12dc2 100644 --- a/src/core/core.js +++ b/src/core/core.js @@ -304,8 +304,7 @@ var p5 = function(sketch, node, sync) { this.createCanvas( this._defaultCanvasSize.width, this._defaultCanvasSize.height, - 'p2d', - true + 'p2d' ); // return preload functions to their normal vals if switched by preload From 2e733f771ff434bb1ab51629a93a52e834d0494c Mon Sep 17 00:00:00 2001 From: Spongman Date: Mon, 6 Nov 2017 13:38:05 -0800 Subject: [PATCH 10/31] fix bad merge of parameter docs --- src/math/p5.Vector.js | 13 +++++-------- src/webgl/material.js | 22 ++++++++++------------ 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/math/p5.Vector.js b/src/math/p5.Vector.js index c9dd6789a5..3ded9b6216 100644 --- a/src/math/p5.Vector.js +++ b/src/math/p5.Vector.js @@ -107,8 +107,7 @@ p5.Vector.prototype.toString = function p5VectorToString() { * Sets the x, y, and z component of the vector using two or three separate * variables, the data from a p5.Vector, or the values from a float array. * @method set - * @param {Number|p5.Vector|Number[]} [x] the x component of the vector or a - * p5.Vector or an Array + * @param {Number} [x] the x component of the vector * @param {Number} [y] the y component of the vector * @param {Number} [z] the z component of the vector * @chainable @@ -180,8 +179,8 @@ p5.Vector.prototype.copy = function () { * acts directly on the vector. See the examples for more context. * * @method add - * @param {Number|p5.Vector|Number[]} x the x component of the vector to be - * added or a p5.Vector or an Array + * @param {Number} x the x component of the vector to be + * added * @param {Number} [y] the y component of the vector to be * added * @param {Number} [z] the z component of the vector to be @@ -237,8 +236,7 @@ p5.Vector.prototype.add = function (x, y, z) { * other acts directly on the vector. See the examples for more context. * * @method sub - * @param {Number|p5.Vector|Number[]} x the x component of the vector or a - * p5.Vector or an Array + * @param {Number} x the x component of the vector * @param {Number} [y] the y component of the vector * @param {Number} [z] the z component of the vector * @chainable @@ -752,8 +750,7 @@ p5.Vector.prototype.array = function () { * Equality check against a p5.Vector * * @method equals - * @param {Number|p5.Vector|Number[]} [x] the x component of the vector or a - * p5.Vector or an Array + * @param {Number} [x] the x component of the vector * @param {Number} [y] the y component of the vector * @param {Number} [z] the z component of the vector * @return {Boolean} whether the vectors are equals diff --git a/src/webgl/material.js b/src/webgl/material.js index 6ef3a94d58..97c350a797 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -211,12 +211,11 @@ p5.prototype.texture = function(){ * possible materials in this * example. * @method ambientMaterial - * @param {Number|Number[]|String|p5.Color} v1 gray value, - * red or hue value (depending on the current color mode), - * or color Array, or CSS color string - * @param {Number} [v2] green or saturation value - * @param {Number} [v3] blue or brightness value - * @param {Number} [a] opacity + * @param {Number} v1 gray value, red or hue value + * (depending on the current color mode), + * @param {Number} [v2] green or saturation value + * @param {Number} [v3] blue or brightness value + * @param {Number} [a] opacity * @chainable * @example *
@@ -259,12 +258,11 @@ p5.prototype.ambientMaterial = function(v1, v2, v3, a) { * possible materials in this * example. * @method specularMaterial - * @param {Number|Number[]|String|p5.Color} v1 gray value, - * red or hue value (depending on the current color mode), - * or color Array, or CSS color string - * @param {Number} [v2] green or saturation value - * @param {Number} [v3] blue or brightness value - * @param {Number} [a] opacity + * @param {Number} v1 gray value, red or hue value + * (depending on the current color mode), + * @param {Number} [v2] green or saturation value + * @param {Number} [v3] blue or brightness value + * @param {Number} [a] opacity * @chainable * @example *
From c3a0b7722b2c1477966948b9d447b0a5ce7e3552 Mon Sep 17 00:00:00 2001 From: Spongman Date: Mon, 6 Nov 2017 13:39:35 -0800 Subject: [PATCH 11/31] fix bad merge of parameter docs --- src/math/p5.Vector.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/math/p5.Vector.js b/src/math/p5.Vector.js index 3ded9b6216..f235988380 100644 --- a/src/math/p5.Vector.js +++ b/src/math/p5.Vector.js @@ -107,9 +107,9 @@ p5.Vector.prototype.toString = function p5VectorToString() { * Sets the x, y, and z component of the vector using two or three separate * variables, the data from a p5.Vector, or the values from a float array. * @method set - * @param {Number} [x] the x component of the vector - * @param {Number} [y] the y component of the vector - * @param {Number} [z] the z component of the vector + * @param {Number} [x] the x component of the vector + * @param {Number} [y] the y component of the vector + * @param {Number} [z] the z component of the vector * @chainable * @example *
@@ -179,12 +179,9 @@ p5.Vector.prototype.copy = function () { * acts directly on the vector. See the examples for more context. * * @method add - * @param {Number} x the x component of the vector to be - * added - * @param {Number} [y] the y component of the vector to be - * added - * @param {Number} [z] the z component of the vector to be - * added + * @param {Number} x the x component of the vector to be added + * @param {Number} [y] the y component of the vector to be added + * @param {Number} [z] the z component of the vector to be added * @chainable * @example *
From b809cb54e559ca01e6d6fc2313c7b07d3ed93a25 Mon Sep 17 00:00:00 2001 From: Spongman Date: Mon, 6 Nov 2017 13:42:23 -0800 Subject: [PATCH 12/31] more bad merge cleanup --- src/math/p5.Vector.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/math/p5.Vector.js b/src/math/p5.Vector.js index f235988380..b3ccb06512 100644 --- a/src/math/p5.Vector.js +++ b/src/math/p5.Vector.js @@ -233,9 +233,9 @@ p5.Vector.prototype.add = function (x, y, z) { * other acts directly on the vector. See the examples for more context. * * @method sub - * @param {Number} x the x component of the vector - * @param {Number} [y] the y component of the vector - * @param {Number} [z] the z component of the vector + * @param {Number} x the x component of the vector to subtract + * @param {Number} [y] the y component of the vector to subtract + * @param {Number} [z] the z component of the vector to subtract * @chainable * @example *
@@ -747,9 +747,9 @@ p5.Vector.prototype.array = function () { * Equality check against a p5.Vector * * @method equals - * @param {Number} [x] the x component of the vector - * @param {Number} [y] the y component of the vector - * @param {Number} [z] the z component of the vector + * @param {Number} [x] the x component of the vector + * @param {Number} [y] the y component of the vector + * @param {Number} [z] the z component of the vector * @return {Boolean} whether the vectors are equals * @example *
From be11e31492c9a0bcb08f4cf3838710744131b205 Mon Sep 17 00:00:00 2001 From: Spongman Date: Wed, 29 Nov 2017 18:53:32 -0800 Subject: [PATCH 13/31] prettify --- .eslintrc | 1 + Gruntfile.js | 7 +- src/core/error_helpers.js | 297 ++++++++++++++++++-------------- src/image/loading_displaying.js | 2 +- tasks/build/browserify.js | 100 +++++------ 5 files changed, 228 insertions(+), 179 deletions(-) diff --git a/.eslintrc b/.eslintrc index dbae927077..06335b169c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -35,6 +35,7 @@ "no-caller": 2, "no-undef": 2, "no-unused-vars": ["error", { "args": "none" }], + "no-empty": ["error", { "allowEmptyCatch": true }], "no-console": "off" } } diff --git a/Gruntfile.js b/Gruntfile.js index d56ab9e649..30eafaf6ec 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -354,7 +354,12 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-karma'); // Create the multitasks. - grunt.registerTask('build', ['browserify', 'browserify:min', 'uglify', 'requirejs']); + grunt.registerTask('build', [ + 'browserify', + 'browserify:min', + 'uglify', + 'requirejs' + ]); grunt.registerTask('lint-no-fix', [ 'eslint:build', 'eslint:source', diff --git a/src/core/error_helpers.js b/src/core/error_helpers.js index 9d1502a637..6ffbe5ab8a 100644 --- a/src/core/error_helpers.js +++ b/src/core/error_helpers.js @@ -8,13 +8,8 @@ var p5 = require('./core'); if (typeof IS_MINIFIED !== 'undefined') { - - p5._validateParameters = - p5._friendlyFileLoadError = - function () { }; - + p5._validateParameters = p5._friendlyFileLoadError = function() {}; } else { - var doFriendlyWelcome = false; // TEMP until we get it all working LM // for parameter validation var dataDoc = require('../../docs/reference/data.json'); @@ -24,25 +19,31 @@ if (typeof IS_MINIFIED !== 'undefined') { var class2type = {}; var toString = class2type.toString; var names = [ - 'Boolean', 'Number', 'String', 'Function', - 'Array', 'Date', 'RegExp', 'Object', 'Error' + 'Boolean', + 'Number', + 'String', + 'Function', + 'Array', + 'Date', + 'RegExp', + 'Object', + 'Error' ]; for (var n = 0; n < names.length; n++) { class2type['[object ' + names[n] + ']'] = names[n].toLowerCase(); } - var getType = function (obj) { + var getType = function(obj) { if (obj == null) { return obj + ''; } - return typeof obj === 'object' || typeof obj === 'function' ? - class2type[toString.call(obj)] || 'object' : - typeof obj; + return typeof obj === 'object' || typeof obj === 'function' + ? class2type[toString.call(obj)] || 'object' + : typeof obj; }; // -- End borrow -- - - var friendlyWelcome = function () { + var friendlyWelcome = function() { // p5.js brand - magenta: #ED225D //var astrixBgColor = 'transparent'; //var astrixTxtColor = '#ED225D'; @@ -50,13 +51,13 @@ if (typeof IS_MINIFIED !== 'undefined') { //var welcomeTextColor = 'white'; console.log( ' _ \n' + - ' /\\| |/\\ \n' + - ' \\ ` \' / \n' + - ' / , . \\ \n' + - ' \\/|_|\\/ ' + - '\n\n> p5.js says: Welcome! ' + - 'This is your friendly debugger. ' + - 'To turn me off switch to using “p5.min.js”.' + ' /\\| |/\\ \n' + + " \\ ` ' / \n" + + ' / , . \\ \n' + + ' \\/|_|\\/ ' + + '\n\n> p5.js says: Welcome! ' + + 'This is your friendly debugger. ' + + 'To turn me off switch to using “p5.min.js”.' ); }; @@ -76,27 +77,30 @@ if (typeof IS_MINIFIED !== 'undefined') { // p5.js blue, p5.js orange, auto dark green; fallback p5.js darkened magenta // See testColors below for all the color codes and names var typeColors = ['#2D7BB6', '#EE9900', '#4DB200', '#C83C00']; - var report = function (message, func, color) { + var report = function(message, func, color) { if (doFriendlyWelcome) { friendlyWelcome(); doFriendlyWelcome = false; - } if ('undefined' === getType(color)) { color = '#B40033'; // dark magenta - } else if (getType(color) === 'number') { // Type to color + } else if (getType(color) === 'number') { + // Type to color color = typeColors[color]; } if (func.substring(0, 4) === 'load') { console.log( - '> p5.js says: ' + message + - '[https://github.com/processing/p5.js/wiki/Local-server]' + '> p5.js says: ' + + message + + '[https://github.com/processing/p5.js/wiki/Local-server]' ); - } - else { + } else { console.log( - '> p5.js says: ' + message + ' [http://p5js.org/reference/#p5/' + func + - ']' + '> p5.js says: ' + + message + + ' [http://p5js.org/reference/#p5/' + + func + + ']' ); } }; @@ -123,28 +127,39 @@ if (typeof IS_MINIFIED !== 'undefined') { fileType: 'font', method: 'loadFont', message: ' hosting the font online,' - }, + } }; - p5._friendlyFileLoadError = function (errorType, filePath) { + p5._friendlyFileLoadError = function(errorType, filePath) { var errorInfo = errorCases[errorType]; - var message = 'It looks like there was a problem' + - ' loading your ' + errorInfo.fileType + '.' + - ' Try checking if the file path [' + filePath + '] is correct,' + - (errorInfo.message || '') + ' or running a local server.'; + var message = + 'It looks like there was a problem' + + ' loading your ' + + errorInfo.fileType + + '.' + + ' Try checking if the file path [' + + filePath + + '] is correct,' + + (errorInfo.message || '') + + ' or running a local server.'; report(message, errorInfo.method, FILE_LOAD); }; var docCache = {}; var builtinTypes = [ - 'number', 'string', 'boolean', - 'constant', 'function', 'integer' + 'number', + 'string', + 'boolean', + 'constant', + 'function', + 'integer' ]; // validateParameters() helper functions: // lookupParamDoc() for querying data.json - var lookupParamDoc = function (func) { - var queryResult = arrDoc.classitems. - filter(function (x) { return x.name === func; }); + var lookupParamDoc = function(func) { + var queryResult = arrDoc.classitems.filter(function(x) { + return x.name === func; + }); // different JSON structure for funct with multi-format var overloads = []; if (queryResult[0].hasOwnProperty('overloads')) { @@ -157,13 +172,12 @@ if (typeof IS_MINIFIED !== 'undefined') { var mapConstants = {}; var maxParams = 0; - overloads.forEach(function (formats) { + overloads.forEach(function(formats) { if (maxParams < formats.length) { maxParams = formats.length; } - formats.forEach(function (format) { + formats.forEach(function(format) { format.types = format.type.split('|').map(function ct(type) { - // array if (type.substr(type.length - 2, 2) === '[]') { return { @@ -176,7 +190,6 @@ if (typeof IS_MINIFIED !== 'undefined') { // contant if (lowerType === 'constant') { - var constant; if (mapConstants.hasOwnProperty(format.name)) { constant = mapConstants[format.name]; @@ -187,7 +200,8 @@ if (typeof IS_MINIFIED !== 'undefined') { var names = []; constant = mapConstants[format.name] = { - values: values, names: names + values: values, + names: names }; var myArray = myRe.exec(format.description); @@ -208,8 +222,10 @@ if (typeof IS_MINIFIED !== 'undefined') { } } return { - name: type, builtin: lowerType, - names: constant.names, values: constant.values + name: type, + builtin: lowerType, + names: constant.names, + values: constant.values }; } @@ -224,7 +240,9 @@ if (typeof IS_MINIFIED !== 'undefined') { // p5 class type var t = window; - type.split('.').forEach(function (p) { t = t && t[p]; }); + type.split('.').forEach(function(p) { + t = t && t[p]; + }); if (t) { return { name: type, prototype: t }; } @@ -235,11 +253,11 @@ if (typeof IS_MINIFIED !== 'undefined') { }); return { overloads: overloads, - maxParams: maxParams, + maxParams: maxParams }; }; - var testParamType = function (param, type) { + var testParamType = function(param, type) { var isArray = param instanceof Array; if (type.array && isArray) { for (var i = 0; i < param.length; i++) { @@ -248,24 +266,23 @@ if (typeof IS_MINIFIED !== 'undefined') { } } return true; - } - else if (type.prototype) { + } else if (type.prototype) { return param instanceof type.prototype; - } - else if (type.builtin) { + } else if (type.builtin) { switch (type.builtin) { case 'number': - return (typeof param === 'number' || !!param && !isNaN(param)); + return typeof param === 'number' || (!!param && !isNaN(param)); case 'integer': - return (typeof param === 'number' || !!param && !isNaN(param)) && - Number(param) === Math.floor(param); + return ( + (typeof param === 'number' || (!!param && !isNaN(param))) && + Number(param) === Math.floor(param) + ); case 'boolean': return true; case 'array': return isArray; case 'string': - return typeof param === 'number' || - typeof param === 'string'; + return typeof param === 'number' || typeof param === 'string'; case 'constant': return type.values.hasOwnProperty(param); case 'function': @@ -278,7 +295,7 @@ if (typeof IS_MINIFIED !== 'undefined') { // testType() for non-object type parameter validation // Returns true if PASS, false if FAIL - var testParamTypes = function (param, types) { + var testParamTypes = function(param, types) { for (var i = 0; i < types.length; i++) { if (testParamType(param, types[i])) { return true; @@ -287,18 +304,18 @@ if (typeof IS_MINIFIED !== 'undefined') { return false; }; - var testParamFormat = function (args, formats) { + var testParamFormat = function(args, formats) { var errorArray = []; for (var p = 0; p < formats.length; p++) { var arg = args[p]; var format = formats[p]; - var argType = typeof (arg); + var argType = typeof arg; if ('undefined' === argType || null === arg) { if (format.optional !== true) { errorArray.push({ type: 'EMPTY_VAR', position: p, - format: format, + format: format }); } } else if (!testParamTypes(arg, format.types)) { @@ -314,20 +331,26 @@ if (typeof IS_MINIFIED !== 'undefined') { }; // function for generating console.log() msg - p5._friendlyParamError = function (errorObj, func) { + p5._friendlyParamError = function(errorObj, func) { var message; function formatType() { var format = errorObj.format; - return format.types.map(function (type) { - return type.names ? type.names.join('|') : type.name; - }).join('|'); + return format.types + .map(function(type) { + return type.names ? type.names.join('|') : type.name; + }) + .join('|'); } switch (errorObj.type) { case 'EMPTY_VAR': - message = func + '() was expecting ' + formatType() + - ' for parameter #' + errorObj.position + + message = + func + + '() was expecting ' + + formatType() + + ' for parameter #' + + errorObj.position + ' (zero-based index), received an empty variable instead.' + ' If not intentional, this is often a problem with scope:' + ' [https://p5js.org/examples/data-variable-scope.html]'; @@ -335,46 +358,56 @@ if (typeof IS_MINIFIED !== 'undefined') { case 'WRONG_TYPE': var arg = errorObj.arg; var argType = arg instanceof Array ? 'array' : arg.name || typeof arg; - message = func + '() was expecting ' + formatType() + - ' for parameter #' + errorObj.position + - ' (zero-based index), received ' + argType + ' instead'; + message = + func + + '() was expecting ' + + formatType() + + ' for parameter #' + + errorObj.position + + ' (zero-based index), received ' + + argType + + ' instead'; break; case 'WRONG_ARGUMENT_COUNT': - message = func + '() was expecting ' + errorObj.maxParams + - ' arguments, but received ' + errorObj.argCount; + message = + func + + '() was expecting ' + + errorObj.maxParams + + ' arguments, but received ' + + errorObj.argCount; break; } if (message) { try { var re = /Function\.validateParameters.*[\r\n].*[\r\n].*\(([^)]*)/; - var location = re.exec((new Error()).stack)[1]; + var location = re.exec(new Error().stack)[1]; if (location) { message += ' at ' + location; } - } catch (err) { } + } catch (err) {} report(message + '.', func, ERR_PARAMS); } }; /** - * Validates parameters - * param {String} func the name of the function - * param {Array} args user input arguments - * - * example: - * var a; - * ellipse(10,10,a,5); - * console ouput: - * "It looks like ellipse received an empty variable in spot #2." - * - * example: - * ellipse(10,"foo",5,5); - * console output: - * "ellipse was expecting a number for parameter #1, - * received "foo" instead." - */ + * Validates parameters + * param {String} func the name of the function + * param {Array} args user input arguments + * + * example: + * var a; + * ellipse(10,10,a,5); + * console ouput: + * "It looks like ellipse received an empty variable in spot #2." + * + * example: + * ellipse(10,"foo",5,5); + * console output: + * "ellipse was expecting a number for parameter #1, + * received "foo" instead." + */ p5._validateParameters = function validateParameters(func, args) { if (p5.disableFriendlyErrors) { return; // skip FES @@ -400,7 +433,7 @@ if (typeof IS_MINIFIED !== 'undefined') { errorArray.push({ type: 'WRONG_ARGUMENT_COUNT', argCount: args.length, - maxParams: docs.maxParams, + maxParams: docs.maxParams }); } @@ -410,7 +443,6 @@ if (typeof IS_MINIFIED !== 'undefined') { } }; - /** * Prints out all the colors in the color pallete with white text. * For color blindness testing. @@ -438,7 +470,6 @@ if (typeof IS_MINIFIED !== 'undefined') { p5.prototype._validateParameters = p5.validateParameters; } - // This is a lazily-defined list of p5 symbols that may be // misused by beginners at top-level code, outside of setup/draw. We'd like // to detect these errors and help the user by suggesting they move them @@ -446,39 +477,42 @@ if (typeof IS_MINIFIED !== 'undefined') { // // For more details, see https://github.com/processing/p5.js/issues/1121. var misusedAtTopLevelCode = null; -var FAQ_URL = 'https://github.com/processing/p5.js/wiki/' + +var FAQ_URL = + 'https://github.com/processing/p5.js/wiki/' + 'Frequently-Asked-Questions' + '#why-cant-i-assign-variables-using-p5-functions-and-' + 'variables-before-setup'; -var defineMisusedAtTopLevelCode = function () { +var defineMisusedAtTopLevelCode = function() { var uniqueNamesFound = {}; - var getSymbols = function (obj) { - return Object.getOwnPropertyNames(obj).filter(function (name) { - if (name[0] === '_') { - return false; - } - if (name in uniqueNamesFound) { - return false; - } + var getSymbols = function(obj) { + return Object.getOwnPropertyNames(obj) + .filter(function(name) { + if (name[0] === '_') { + return false; + } + if (name in uniqueNamesFound) { + return false; + } - uniqueNamesFound[name] = true; + uniqueNamesFound[name] = true; - return true; - }).map(function (name) { - var type; - - if (typeof (obj[name]) === 'function') { - type = 'function'; - } else if (name === name.toUpperCase()) { - type = 'constant'; - } else { - type = 'variable'; - } + return true; + }) + .map(function(name) { + var type; + + if (typeof obj[name] === 'function') { + type = 'function'; + } else if (name === name.toUpperCase()) { + type = 'constant'; + } else { + type = 'variable'; + } - return { name: name, type: type }; - }); + return { name: name, type: type }; + }); }; misusedAtTopLevelCode = [].concat( @@ -492,12 +526,12 @@ var defineMisusedAtTopLevelCode = function () { // This will ultimately ensure that we report the most specific error // possible to the user, e.g. advising them about HALF_PI instead of PI // when their code misuses the former. - misusedAtTopLevelCode.sort(function (a, b) { + misusedAtTopLevelCode.sort(function(a, b) { return b.name.length - a.name.length; }); }; -var helpForMisusedAtTopLevelCode = function (e, log) { +var helpForMisusedAtTopLevelCode = function(e, log) { if (!log) { log = console.log.bind(console); } @@ -515,7 +549,7 @@ var helpForMisusedAtTopLevelCode = function (e, log) { // return; //} - misusedAtTopLevelCode.some(function (symbol) { + misusedAtTopLevelCode.some(function(symbol) { // Note that while just checking for the occurrence of the // symbol name in the error message could result in false positives, // a more rigorous test is difficult because different browsers @@ -530,11 +564,16 @@ var helpForMisusedAtTopLevelCode = function (e, log) { // * Uncaught ReferenceError: PI is not defined (Chrome) if (e.message && e.message.match('\\W?' + symbol.name + '\\W') !== null) { - log('Did you just try to use p5.js\'s ' + symbol.name + - (symbol.type === 'function' ? '() ' : ' ') + symbol.type + - '? If so, you may want to ' + - 'move it into your sketch\'s setup() function.\n\n' + - 'For more details, see: ' + FAQ_URL); + log( + "Did you just try to use p5.js's " + + symbol.name + + (symbol.type === 'function' ? '() ' : ' ') + + symbol.type + + '? If so, you may want to ' + + "move it into your sketch's setup() function.\n\n" + + 'For more details, see: ' + + FAQ_URL + ); return true; } }); @@ -550,7 +589,7 @@ if (document.readyState !== 'complete') { // global (non-instance mode) p5 APIs are used at the top-level // scope of a file, so we'll unbind our error listener now to make // sure we don't log false positives later. - window.addEventListener('load', function () { + window.addEventListener('load', function() { window.removeEventListener('error', helpForMisusedAtTopLevelCode, false); }); } diff --git a/src/image/loading_displaying.js b/src/image/loading_displaying.js index 3c8bfee96c..44610f17ff 100644 --- a/src/image/loading_displaying.js +++ b/src/image/loading_displaying.js @@ -243,7 +243,7 @@ p5.prototype.image = function( // set defaults per spec: https://goo.gl/3ykfOq p5._validateParameters('image', arguments); - + var defW = img.width; var defH = img.height; diff --git a/tasks/build/browserify.js b/tasks/build/browserify.js index 366e7931b3..9eb192d8ac 100644 --- a/tasks/build/browserify.js +++ b/tasks/build/browserify.js @@ -10,53 +10,57 @@ var bannerTemplate = module.exports = function(grunt) { var srcFilePath = require.resolve('../../src/app.js'); - grunt.registerTask('browserify', 'Compile the p5.js source with Browserify', function(param) { - - var isMin = param === 'min'; - var filename = isMin ? 'p5.pre-min.js' : 'p5.js'; - - // This file will not exist until it has been built - var libFilePath = path.resolve('lib/' + filename); - - // Reading and writing files is asynchronous - var done = this.async(); - - // Render the banner for the top of the file - var banner = grunt.template.process(bannerTemplate); - - // Invoke Browserify programatically to bundle the code - var browseified = browserify(srcFilePath, { - standalone: 'p5' - }); - - if (isMin) { - browseified = browseified.exclude('../../docs/reference/data.json'); + grunt.registerTask( + 'browserify', + 'Compile the p5.js source with Browserify', + function(param) { + var isMin = param === 'min'; + var filename = isMin ? 'p5.pre-min.js' : 'p5.js'; + + // This file will not exist until it has been built + var libFilePath = path.resolve('lib/' + filename); + + // Reading and writing files is asynchronous + var done = this.async(); + + // Render the banner for the top of the file + var banner = grunt.template.process(bannerTemplate); + + // Invoke Browserify programatically to bundle the code + var browseified = browserify(srcFilePath, { + standalone: 'p5' + }); + + if (isMin) { + browseified = browseified.exclude('../../docs/reference/data.json'); + } + + var bundle = browseified.transform('brfs').bundle(); + + // Start the generated output with the banner comment, + var code = banner + '\n'; + + // Then read the bundle into memory so we can run it through derequire + bundle + .on('data', function(data) { + code += data; + }) + .on('end', function() { + // "code" is complete: create the distributable UMD build by running + // the bundle through derequire, then write the bundle to disk. + // (Derequire changes the bundle's internal "require" function to + // something that will not interfere with this module being used + // within a separate browserify bundle.) + grunt.file.write(libFilePath, derequire(code)); + + // Print a success message + grunt.log.writeln( + '>>'.green + ' Bundle ' + ('lib/' + filename).cyan + ' created.' + ); + + // Complete the task + done(); + }); } - - var bundle = browseified - .transform('brfs') - .bundle(); - - // Start the generated output with the banner comment, - var code = banner + '\n'; - - // Then read the bundle into memory so we can run it through derequire - bundle.on('data', function(data) { - code += data; - }).on('end', function() { - - // "code" is complete: create the distributable UMD build by running - // the bundle through derequire, then write the bundle to disk. - // (Derequire changes the bundle's internal "require" function to - // something that will not interfere with this module being used - // within a separate browserify bundle.) - grunt.file.write(libFilePath, derequire(code)); - - // Print a success message - grunt.log.writeln('>>'.green + ' Bundle ' + ('lib/' + filename).cyan + ' created.'); - - // Complete the task - done(); - }); - }); + ); }; From d3f90034b9afeb18eab9137b70174f1763f6549f Mon Sep 17 00:00:00 2001 From: Spongman Date: Fri, 15 Dec 2017 14:37:07 -0800 Subject: [PATCH 14/31] prettify --- lib/addons/p5.dom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index 3507f70bdd..cd7d190556 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -219,9 +219,9 @@ *
* */ - p5.prototype.removeElements =function (e) { + p5.prototype.removeElements = function(e) { p5._validateParameters('removeElements', arguments); - for (var i=0; i Date: Mon, 18 Dec 2017 18:13:19 -0800 Subject: [PATCH 15/31] avoid use of 'arguments' object where possible --- src/color/creating_reading.js | 22 +-- src/color/p5.Color.js | 33 ++-- src/color/setting.js | 34 ++-- src/core/2d_primitives.js | 161 ++++----------- src/core/canvas.js | 2 + src/core/constants.js | 2 + src/core/core.js | 11 +- src/core/curves.js | 120 ++++-------- src/core/environment.js | 2 +- src/core/init.js | 2 + src/core/p5.Element.js | 46 ++--- src/core/p5.Graphics.js | 2 + src/core/p5.Renderer.js | 12 +- src/core/p5.Renderer2D.js | 4 +- src/core/rendering.js | 11 +- src/core/shim.js | 2 + src/core/structure.js | 15 +- src/core/transform.js | 60 ++---- src/data/p5.TypedDict.js | 57 +++--- src/math/polargeometry.js | 2 + src/typography/p5.Font.js | 10 +- src/utilities/string_functions.js | 92 ++++----- src/webgl/camera.js | 45 +++-- src/webgl/light.js | 48 ++--- src/webgl/loading.js | 3 +- src/webgl/material.js | 8 +- src/webgl/p5.RendererGL.Immediate.js | 6 +- src/webgl/p5.RendererGL.js | 22 ++- src/webgl/p5.Shader.js | 2 + src/webgl/p5.Texture.js | 2 + src/webgl/primitives.js | 280 +++++++++++++++------------ 31 files changed, 494 insertions(+), 624 deletions(-) diff --git a/src/color/creating_reading.js b/src/color/creating_reading.js index ec51dcd659..03500fcbc3 100644 --- a/src/color/creating_reading.js +++ b/src/color/creating_reading.js @@ -440,28 +440,28 @@ p5.prototype.lerpColor = function(c1, c2, amt) { var fromArray, toArray; if (mode === constants.RGB) { - fromArray = arguments[0].levels.map(function(level) { + fromArray = c1.levels.map(function(level) { return level / 255; }); - toArray = arguments[1].levels.map(function(level) { + toArray = c2.levels.map(function(level) { return level / 255; }); } else if (mode === constants.HSB) { - arguments[0]._getBrightness(); // Cache hsba so it definitely exists. - arguments[1]._getBrightness(); - fromArray = arguments[0].hsba; - toArray = arguments[1].hsba; + c1._getBrightness(); // Cache hsba so it definitely exists. + c2._getBrightness(); + fromArray = c1.hsba; + toArray = c2.hsba; } else if (mode === constants.HSL) { - arguments[0]._getLightness(); // Cache hsla so it definitely exists. - arguments[1]._getLightness(); - fromArray = arguments[0].hsla; - toArray = arguments[1].hsla; + c1._getLightness(); // Cache hsla so it definitely exists. + c2._getLightness(); + fromArray = c1.hsla; + toArray = c2.hsla; } else { throw new Error(mode + 'cannot be used for interpolation.'); } // Prevent extrapolation. - amt = Math.max(Math.min(arguments[2], 1), 0); + amt = Math.max(Math.min(amt, 1), 0); // Define lerp here itself if user isn't using math module. // Maintains the definition as found in math/calculation.js diff --git a/src/color/p5.Color.js b/src/color/p5.Color.js index 7000ad8d31..e20c34f68b 100644 --- a/src/color/p5.Color.js +++ b/src/color/p5.Color.js @@ -7,6 +7,8 @@ * @requires color_conversion */ +'use strict'; + var p5 = require('../core/core'); var constants = require('../core/constants'); var color_conversion = require('./color_conversion'); @@ -600,7 +602,7 @@ var colorPatterns = { * //todo * */ -p5.Color._parseInputs = function() { +p5.Color._parseInputs = function(r, g, b, a) { var numArgs = arguments.length; var mode = this.mode; var maxes = this.maxes; @@ -609,13 +611,13 @@ p5.Color._parseInputs = function() { if (numArgs >= 3) { // Argument is a list of component values. - results[0] = arguments[0] / maxes[mode][0]; - results[1] = arguments[1] / maxes[mode][1]; - results[2] = arguments[2] / maxes[mode][2]; + results[0] = r / maxes[mode][0]; + results[1] = g / maxes[mode][1]; + results[2] = b / maxes[mode][2]; // Alpha may be undefined, so default it to 100%. - if (typeof arguments[3] === 'number') { - results[3] = arguments[3] / maxes[mode][3]; + if (typeof a === 'number') { + results[3] = a / maxes[mode][3]; } else { results[3] = 1; } @@ -633,8 +635,8 @@ p5.Color._parseInputs = function() { } else { return results; } - } else if (numArgs === 1 && typeof arguments[0] === 'string') { - var str = arguments[0].trim().toLowerCase(); + } else if (numArgs === 1 && typeof r === 'string') { + var str = r.trim().toLowerCase(); // Return if string is a named colour. if (namedColors[str]) { @@ -785,10 +787,7 @@ p5.Color._parseInputs = function() { // Input did not match any CSS color pattern: default to white. results = [1, 1, 1, 1]; - } else if ( - (numArgs === 1 || numArgs === 2) && - typeof arguments[0] === 'number' - ) { + } else if ((numArgs === 1 || numArgs === 2) && typeof r === 'number') { // 'Grayscale' mode. /** @@ -796,13 +795,13 @@ p5.Color._parseInputs = function() { * value (they are equivalent when chroma is zero). For RGB, normalize the * gray level according to the blue maximum. */ - results[0] = arguments[0] / maxes[mode][2]; - results[1] = arguments[0] / maxes[mode][2]; - results[2] = arguments[0] / maxes[mode][2]; + results[0] = r / maxes[mode][2]; + results[1] = r / maxes[mode][2]; + results[2] = r / maxes[mode][2]; // Alpha may be undefined, so default it to 100%. - if (typeof arguments[1] === 'number') { - results[3] = arguments[1] / maxes[mode][3]; + if (typeof g === 'number') { + results[3] = g / maxes[mode][3]; } else { results[3] = 1; } diff --git a/src/color/setting.js b/src/color/setting.js index 52ec8bf194..58d85c97c0 100644 --- a/src/color/setting.js +++ b/src/color/setting.js @@ -300,31 +300,31 @@ p5.prototype.clear = function() { * @param {Number} [maxA] range for the alpha * @chainable */ -p5.prototype.colorMode = function() { +p5.prototype.colorMode = function(mode, max1, max2, max3, maxA) { if ( - arguments[0] === constants.RGB || - arguments[0] === constants.HSB || - arguments[0] === constants.HSL + mode === constants.RGB || + mode === constants.HSB || + mode === constants.HSL ) { // Set color mode. - this._renderer._colorMode = arguments[0]; + this._renderer._colorMode = mode; // Set color maxes. - var maxes = this._renderer._colorMaxes[this._renderer._colorMode]; + var maxes = this._renderer._colorMaxes[mode]; if (arguments.length === 2) { - maxes[0] = arguments[1]; // Red - maxes[1] = arguments[1]; // Green - maxes[2] = arguments[1]; // Blue - maxes[3] = arguments[1]; // Alpha + maxes[0] = max1; // Red + maxes[1] = max1; // Green + maxes[2] = max1; // Blue + maxes[3] = max1; // Alpha } else if (arguments.length === 4) { - maxes[0] = arguments[1]; // Red - maxes[1] = arguments[2]; // Green - maxes[2] = arguments[3]; // Blue + maxes[0] = max1; // Red + maxes[1] = max2; // Green + maxes[2] = max3; // Blue } else if (arguments.length === 5) { - maxes[0] = arguments[1]; // Red - maxes[1] = arguments[2]; // Green - maxes[2] = arguments[3]; // Blue - maxes[3] = arguments[4]; // Alpha + maxes[0] = max1; // Red + maxes[1] = max2; // Green + maxes[2] = max3; // Blue + maxes[3] = maxA; // Alpha } } diff --git a/src/core/2d_primitives.js b/src/core/2d_primitives.js index 98334e6fa0..1b4d37b0de 100644 --- a/src/core/2d_primitives.js +++ b/src/core/2d_primitives.js @@ -78,12 +78,7 @@ require('./error_helpers'); * */ p5.prototype.arc = function(x, y, w, h, start, stop, mode) { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - - p5._validateParameters('arc', args); + p5._validateParameters('arc', arguments); if (!this._renderer._doStroke && !this._renderer._doFill) { return this; } @@ -161,39 +156,26 @@ p5.prototype.arc = function(x, y, w, h, start, stop, mode) { *white ellipse with black outline in middle-right of canvas that is 55x55. * */ -p5.prototype.ellipse = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - // Duplicate 3rd argument if only 3 given. - if (args.length === 3) { - args.push(args[2]); - } +p5.prototype.ellipse = function(x, y, w, h) { + p5._validateParameters('ellipse', arguments); - p5._validateParameters('ellipse', args); // p5 supports negative width and heights for rects - if (args[2] < 0) { - args[2] = Math.abs(args[2]); + if (w < 0) { + w = Math.abs(w); } - if (args[3] < 0) { - args[3] = Math.abs(args[3]); + + if (typeof h === 'undefined') { + // Duplicate 3rd argument if only 3 given. + h = w; + } else if (h < 0) { + h = Math.abs(h); } - if (!this._renderer._doStroke && !this._renderer._doFill) { - return this; + + if (this._renderer._doStroke || this._renderer._doFill) { + var vals = canvas.modeAdjust(x, y, w, h, this._renderer._ellipseMode); + this._renderer.ellipse([vals.x, vals.y, vals.w, vals.h]); } - var vals = canvas.modeAdjust( - args[0], - args[1], - args[2], - args[3], - this._renderer._ellipseMode - ); - args[0] = vals.x; - args[1] = vals.y; - args[2] = vals.w; - args[3] = vals.h; - this._renderer.ellipse(args); + return this; }; /** @@ -233,21 +215,12 @@ p5.prototype.ellipse = function() { * */ p5.prototype.line = function() { - if (!this._renderer._doStroke) { - return this; - } - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('line', arguments); - p5._validateParameters('line', args); - //check whether we should draw a 3d line or 2d - if (this._renderer.isP3D) { - this._renderer.line.apply(this, args); - } else { - this._renderer.line(args[0], args[1], args[2], args[3]); + if (this._renderer._doStroke) { + this._renderer.line.apply(this._renderer, arguments); } + return this; }; @@ -260,6 +233,7 @@ p5.prototype.line = function() { * @method point * @param {Number} x the x-coordinate * @param {Number} y the y-coordinate + * @param {Number} [z] the z-coordinate (for WEBGL mode) * @chainable * @example *
@@ -276,21 +250,12 @@ p5.prototype.line = function() { * */ p5.prototype.point = function() { - if (!this._renderer._doStroke) { - return this; - } - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('point', arguments); - p5._validateParameters('point', args); - //check whether we should draw a 3d line or 2d - if (this._renderer.isP3D) { - this._renderer.point(args[0], args[1], args[2]); - } else { - this._renderer.point(args[0], args[1]); + if (this._renderer._doStroke) { + this._renderer.point.apply(this._renderer, arguments); } + return this; }; @@ -335,42 +300,12 @@ p5.prototype.point = function() { * @chainable */ p5.prototype.quad = function() { - if (!this._renderer._doStroke && !this._renderer._doFill) { - return this; - } - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('quad', arguments); - p5._validateParameters('quad', args); - if (this._renderer.isP3D) { - this._renderer.quad( - args[0], - args[1], - args[2], - args[3], - args[4], - args[5], - args[6], - args[7], - args[8], - args[9], - args[10], - args[11] - ); - } else { - this._renderer.quad( - args[0], - args[1], - args[2], - args[3], - args[4], - args[5], - args[6], - args[7] - ); + if (this._renderer._doStroke || this._renderer._doFill) { + this._renderer.quad.apply(this._renderer, arguments); } + return this; }; @@ -434,28 +369,14 @@ p5.prototype.quad = function() { * @param {Number} [detailY] * @chainable */ -p5.prototype.rect = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - if (!this._renderer._doStroke && !this._renderer._doFill) { - return this; +p5.prototype.rect = function(x, y, w, h, detailX, detailY) { + p5._validateParameters('rect', arguments); + + if (this._renderer._doStroke || this._renderer._doFill) { + var vals = canvas.modeAdjust(x, y, w, h, this._renderer._rectMode); + this._renderer.rect([vals.x, vals.y, vals.w, vals.h]); } - p5._validateParameters('rect', args); - var vals = canvas.modeAdjust( - args[0], - args[1], - args[2], - args[3], - this._renderer._rectMode - ); - args[0] = vals.x; - args[1] = vals.y; - args[2] = vals.w; - args[3] = vals.h; - this._renderer.rect(args); return this; }; @@ -484,16 +405,12 @@ p5.prototype.rect = function() { * */ p5.prototype.triangle = function() { - if (!this._renderer._doStroke && !this._renderer._doFill) { - return this; - } - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; + p5._validateParameters('triangle', arguments); + + if (this._renderer._doStroke || this._renderer._doFill) { + this._renderer.triangle(arguments); } - p5._validateParameters('triangle', args); - this._renderer.triangle(args); return this; }; diff --git a/src/core/canvas.js b/src/core/canvas.js index d796c12f8b..f1d219f30d 100644 --- a/src/core/canvas.js +++ b/src/core/canvas.js @@ -2,6 +2,8 @@ * @requires constants */ +'use strict'; + var constants = require('./constants'); module.exports = { diff --git a/src/core/constants.js b/src/core/constants.js index 370bec6f62..0f1804004d 100644 --- a/src/core/constants.js +++ b/src/core/constants.js @@ -4,6 +4,8 @@ * @for p5 */ +'use strict'; + var PI = Math.PI; module.exports = { diff --git a/src/core/core.js b/src/core/core.js index 5fb30421a2..d176a0348f 100644 --- a/src/core/core.js +++ b/src/core/core.js @@ -36,7 +36,7 @@ var constants = require('./constants'); * @return {p5} a p5 instance */ var p5 = function(sketch, node, sync) { - if (arguments.length === 2 && typeof node === 'boolean') { + if (typeof node === 'boolean' && typeof sync === 'undefined') { sync = node; node = undefined; } @@ -179,6 +179,8 @@ var p5 = function(sketch, node, sync) { this._preloadCount = 0; this._isGlobal = false; this._loop = true; + this._bezierDetail = 20; + this._curveDetail = 20; this._styles = []; this._defaultCanvasSize = { width: 100, @@ -296,12 +298,7 @@ var p5 = function(sketch, node, sync) { //increment counter this._incrementPreload(); //call original function - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - // args.push(this._decrementPreload.bind(this)); - return this._registeredPreloadMethods[fnName].apply(obj, args); + return this._registeredPreloadMethods[fnName].apply(obj, arguments); }.bind(this); }; diff --git a/src/core/curves.js b/src/core/curves.js index 21c6fbe5cd..59ee397a90 100644 --- a/src/core/curves.js +++ b/src/core/curves.js @@ -10,9 +10,6 @@ var p5 = require('./core'); require('./error_helpers'); -var bezierDetail = 20; -var curveDetail = 20; - /** * Draws a cubic Bezier curve on the screen. These curves are defined by a * series of anchor and control points. The first two parameters specify @@ -74,25 +71,10 @@ var curveDetail = 20; *
*/ p5.prototype.bezier = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('bezier', arguments); - p5._validateParameters('bezier', args); - if (!this._renderer._doStroke && !this._renderer._doFill) { - return this; - } - if (this._renderer.isP3D) { - args.push(bezierDetail); //adding value of bezier detail to the args array - this._renderer.bezier(args); - } else { - // prettier-ignore - this._renderer.bezier( - args[0], args[1], - args[2], args[3], - args[4], args[5], - args[6], args[7]); + if (this._renderer._doStroke || this._renderer._doFill) { + this._renderer.bezier.apply(this._renderer, arguments); } return this; @@ -120,7 +102,7 @@ p5.prototype.bezier = function() { * */ p5.prototype.bezierDetail = function(d) { - bezierDetail = d; + this._bezierDetail = d; return this; }; @@ -168,18 +150,14 @@ p5.prototype.bezierDetail = function(d) { * */ p5.prototype.bezierPoint = function(a, b, c, d, t) { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('bezierPoint', arguments); - p5._validateParameters('bezierPoint', args); - var adjustedT = 1 - args[4]; + var adjustedT = 1 - t; return ( - Math.pow(adjustedT, 3) * args[0] + - 3 * Math.pow(adjustedT, 2) * args[4] * args[1] + - 3 * adjustedT * Math.pow(args[4], 2) * args[2] + - Math.pow(args[4], 3) * args[3] + Math.pow(adjustedT, 3) * a + + 3 * Math.pow(adjustedT, 2) * t * b + + 3 * adjustedT * Math.pow(t, 2) * c + + Math.pow(t, 3) * d ); }; @@ -249,20 +227,16 @@ p5.prototype.bezierPoint = function(a, b, c, d, t) { * */ p5.prototype.bezierTangent = function(a, b, c, d, t) { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('bezierTangent', arguments); - p5._validateParameters('bezierTangent', args); - var adjustedT = 1 - args[4]; + var adjustedT = 1 - t; return ( - 3 * args[3] * Math.pow(args[4], 2) - - 3 * args[2] * Math.pow(args[4], 2) + - 6 * args[2] * adjustedT * args[4] - - 6 * args[1] * adjustedT * args[4] + - 3 * args[1] * Math.pow(adjustedT, 2) - - 3 * args[0] * Math.pow(adjustedT, 2) + 3 * d * Math.pow(t, 2) - + 3 * c * Math.pow(t, 2) + + 6 * c * adjustedT * t - + 6 * b * adjustedT * t + + 3 * b * Math.pow(adjustedT, 2) - + 3 * a * Math.pow(adjustedT, 2) ); }; @@ -344,26 +318,12 @@ p5.prototype.bezierTangent = function(a, b, c, d, t) { * curving black and orange lines. */ p5.prototype.curve = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('curve', arguments); - p5._validateParameters('curve', args); - if (!this._renderer._doStroke) { - return this; - } - if (this._renderer.isP3D) { - args.push(curveDetail); - this._renderer.curve(args); - } else { - // prettier-ignore - this._renderer.curve( - args[0], args[1], - args[2], args[3], - args[4], args[5], - args[6], args[7]); + if (this._renderer._doStroke) { + this._renderer.curve.apply(this._renderer, arguments); } + return this; }; @@ -389,7 +349,7 @@ p5.prototype.curve = function() { * */ p5.prototype.curveDetail = function(d) { - curveDetail = d; + this._curveDetail = d; return this; }; @@ -476,19 +436,15 @@ p5.prototype.curveTightness = function(t) { *line hooking down to right-bottom with 13 5x5 white ellipse points */ p5.prototype.curvePoint = function(a, b, c, d, t) { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('curvePoint', arguments); - p5._validateParameters('curvePoint', args); - var t3 = args[4] * args[4] * args[4], - t2 = args[4] * args[4], - f1 = -0.5 * t3 + t2 - 0.5 * args[4], + var t3 = t * t * t, + t2 = t * t, + f1 = -0.5 * t3 + t2 - 0.5 * t, f2 = 1.5 * t3 - 2.5 * t2 + 1.0, - f3 = -1.5 * t3 + 2.0 * t2 + 0.5 * args[4], + f3 = -1.5 * t3 + 2.0 * t2 + 0.5 * t, f4 = 0.5 * t3 - 0.5 * t2; - return args[0] * f1 + args[1] * f2 + args[2] * f3 + args[3] * f4; + return a * f1 + b * f2 + c * f3 + d * f4; }; /** @@ -527,18 +483,14 @@ p5.prototype.curvePoint = function(a, b, c, d, t) { *right curving line mid-right of canvas with 7 short lines radiating from it. */ p5.prototype.curveTangent = function(a, b, c, d, t) { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } + p5._validateParameters('curveTangent', arguments); - p5._validateParameters('curveTangent', args); - var t2 = args[4] * args[4], - f1 = -3 * t2 / 2 + 2 * args[4] - 0.5, - f2 = 9 * t2 / 2 - 5 * args[4], - f3 = -9 * t2 / 2 + 4 * args[4] + 0.5, - f4 = 3 * t2 / 2 - args[4]; - return args[0] * f1 + args[1] * f2 + args[2] * f3 + args[3] * f4; + var t2 = t * t, + f1 = -3 * t2 / 2 + 2 * t - 0.5, + f2 = 9 * t2 / 2 - 5 * t, + f3 = -9 * t2 / 2 + 4 * t + 0.5, + f4 = 3 * t2 / 2 - t; + return a * f1 + b * f2 + c * f3 + d * f4; }; module.exports = p5; diff --git a/src/core/environment.js b/src/core/environment.js index 83898db807..fac930afad 100644 --- a/src/core/environment.js +++ b/src/core/environment.js @@ -39,7 +39,7 @@ var _windowPrint = window.print; * default grey canvas */ p5.prototype.print = function(args) { - if (arguments.length === 0) { + if (typeof args === 'undefined') { _windowPrint(); } else { console.log.apply(console, arguments); diff --git a/src/core/init.js b/src/core/init.js index e36232d8ae..4b2402c704 100644 --- a/src/core/init.js +++ b/src/core/init.js @@ -1,3 +1,5 @@ +'use strict'; + var p5 = require('../core/core'); /** diff --git a/src/core/p5.Element.js b/src/core/p5.Element.js index a4d4f22c99..cfdfe91800 100644 --- a/src/core/p5.Element.js +++ b/src/core/p5.Element.js @@ -4,6 +4,8 @@ * @for p5.Element */ +'use strict'; + var p5 = require('./core'); /** @@ -85,20 +87,20 @@ p5.Element = function(elt, pInst) { * */ p5.Element.prototype.parent = function(p) { - if (arguments.length === 0) { + if (typeof p === 'undefined') { return this.elt.parentNode; - } else { - if (typeof p === 'string') { - if (p[0] === '#') { - p = p.substring(1); - } - p = document.getElementById(p); - } else if (p instanceof p5.Element) { - p = p.elt; + } + + if (typeof p === 'string') { + if (p[0] === '#') { + p = p.substring(1); } - p.appendChild(this.elt); - return this; + p = document.getElementById(p); + } else if (p instanceof p5.Element) { + p = p.elt; } + p.appendChild(this.elt); + return this; }; /** @@ -128,14 +130,14 @@ p5.Element.prototype.parent = function(p) { * @return {String} the id of the element */ p5.Element.prototype.id = function(id) { - if (arguments.length === 0) { + if (typeof id === 'undefined') { return this.elt.id; - } else { - this.elt.id = id; - this.width = this.elt.offsetWidth; - this.height = this.elt.offsetHeight; - return this; } + + this.elt.id = id; + this.width = this.elt.offsetWidth; + this.height = this.elt.offsetHeight; + return this; }; /** @@ -152,12 +154,12 @@ p5.Element.prototype.id = function(id) { * @return {String} the class of the element */ p5.Element.prototype.class = function(c) { - if (arguments.length === 0) { + if (typeof c === 'undefined') { return this.elt.className; - } else { - this.elt.className = c; - return this; } + + this.elt.className = c; + return this; }; /** @@ -961,7 +963,7 @@ p5.Element.prototype.drop = function(callback, fxn) { ); // If just one argument it's the callback for the files - if (arguments.length > 1) { + if (typeof fxn !== 'undefined') { attachListener('drop', fxn, this); } diff --git a/src/core/p5.Graphics.js b/src/core/p5.Graphics.js index fcb28d22a6..e10a2ced4c 100644 --- a/src/core/p5.Graphics.js +++ b/src/core/p5.Graphics.js @@ -4,6 +4,8 @@ * @for p5 */ +'use strict'; + var p5 = require('./core'); var constants = require('./constants'); diff --git a/src/core/p5.Renderer.js b/src/core/p5.Renderer.js index f4c48e9904..bcf99539eb 100644 --- a/src/core/p5.Renderer.js +++ b/src/core/p5.Renderer.js @@ -4,6 +4,8 @@ * @for p5 */ +'use strict'; + var p5 = require('./core'); var constants = require('../core/constants'); @@ -81,9 +83,7 @@ p5.Renderer.prototype.resize = function(w, h) { }; p5.Renderer.prototype.textLeading = function(l) { - if (arguments.length && typeof arguments[0] === 'number') { - // #2378 - + if (typeof l === 'number') { this._setProperty('_textLeading', l); return this; } @@ -92,9 +92,7 @@ p5.Renderer.prototype.textLeading = function(l) { }; p5.Renderer.prototype.textSize = function(s) { - if (arguments.length && typeof arguments[0] === 'number') { - // #2378 - + if (typeof s === 'number') { this._setProperty('_textSize', s); this._setProperty('_textLeading', s * constants._DEFAULT_LEADMULT); return this._applyTextProperties(); @@ -104,7 +102,7 @@ p5.Renderer.prototype.textSize = function(s) { }; p5.Renderer.prototype.textStyle = function(s) { - if (arguments.length && arguments[0]) { + if (s) { if ( s === constants.NORMAL || s === constants.ITALIC || diff --git a/src/core/p5.Renderer2D.js b/src/core/p5.Renderer2D.js index 10d0f05506..65f0466b15 100644 --- a/src/core/p5.Renderer2D.js +++ b/src/core/p5.Renderer2D.js @@ -1,3 +1,5 @@ +'use strict'; + var p5 = require('./core'); var canvas = require('./canvas'); var constants = require('./constants'); @@ -1305,7 +1307,7 @@ p5.Renderer2D.prototype.textWidth = function(s) { }; p5.Renderer2D.prototype.textAlign = function(h, v) { - if (arguments.length) { + if (typeof h !== 'undefined' && typeof v !== 'undefined') { if ( h === constants.LEFT || h === constants.RIGHT || diff --git a/src/core/rendering.js b/src/core/rendering.js index a5299beed7..6735dfa9c5 100644 --- a/src/core/rendering.js +++ b/src/core/rendering.js @@ -4,6 +4,8 @@ * @for p5 */ +'use strict'; + var p5 = require('./core'); var constants = require('./constants'); require('./p5.Graphics'); @@ -57,8 +59,9 @@ p5.prototype.createCanvas = function(w, h, renderer) { if (c) { //if defaultCanvas already exists c.parentNode.removeChild(c); //replace the existing defaultCanvas + var thisRenderer = this._renderer; this._elements = this._elements.filter(function(e) { - return e !== this._renderer; + return e !== thisRenderer; }); } c = document.createElement('canvas'); @@ -149,7 +152,11 @@ p5.prototype.resizeCanvas = function(w, h, noRedraw) { this._renderer.resize(w, h); // reset canvas properties for (var savedKey in props) { - this.drawingContext[savedKey] = props[savedKey]; + try { + this.drawingContext[savedKey] = props[savedKey]; + } catch (err) { + // ignore read-only property errors + } } if (!noRedraw) { this.redraw(); diff --git a/src/core/shim.js b/src/core/shim.js index 224146d4ea..e7eabfd114 100644 --- a/src/core/shim.js +++ b/src/core/shim.js @@ -1,3 +1,5 @@ +'use strict'; + // requestAnim shim layer by Paul Irish window.requestAnimationFrame = (function() { return ( diff --git a/src/core/structure.js b/src/core/structure.js index 7fcec6c69e..c81efbf084 100644 --- a/src/core/structure.js +++ b/src/core/structure.js @@ -326,22 +326,17 @@ p5.prototype.popStyle = function() { * black line on far left of canvas * */ -p5.prototype.redraw = function() { +p5.prototype.redraw = function(n) { this.resetMatrix(); if (this._renderer.isP3D) { this._renderer._update(); } - var numberOfRedraws = 1; - if (arguments.length === 1) { - try { - if (parseInt(arguments[0]) > 1) { - numberOfRedraws = parseInt(arguments[0]); - } - } catch (error) { - // Do nothing, because the default value didn't be changed. - } + var numberOfRedraws = parseInt(n); + if (isNaN(numberOfRedraws) || numberOfRedraws < 1) { + numberOfRedraws = 1; } + var userSetup = this.setup || window.setup; var userDraw = this.draw || window.draw; if (typeof userDraw === 'function') { diff --git a/src/core/transform.js b/src/core/transform.js index 888255d7e8..fb279a8a14 100644 --- a/src/core/transform.js +++ b/src/core/transform.js @@ -194,22 +194,13 @@ p5.prototype.resetMatrix = function() { * */ p5.prototype.rotate = function(angle, axis) { - var args = new Array(arguments.length); var r; - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } if (this._angleMode === constants.DEGREES) { - r = this.radians(args[0]); + r = this.radians(angle); } else if (this._angleMode === constants.RADIANS) { - r = args[0]; - } - //in webgl mode - if (args.length > 1) { - this._renderer.rotate(r, args[1]); - } else { - this._renderer.rotate(r); + r = angle; } + this._renderer.rotate(r, axis); return this; }; @@ -353,36 +344,27 @@ p5.prototype.rotateZ = function(rad) { * @param {p5.Vector|Array} scales per-axis percents to scale the object * @chainable */ -p5.prototype.scale = function() { - var x, y, z; - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } +p5.prototype.scale = function(x, y, z) { // Only check for Vector argument type if Vector is available - if (typeof p5.Vector !== 'undefined' && args[0] instanceof p5.Vector) { - x = args[0].x; - y = args[0].y; - z = args[0].z; - } else if (args[0] instanceof Array) { - x = args[0][0]; - y = args[0][1]; - z = args[0][2] || 1; - } else { - if (args.length === 1) { - x = y = z = args[0]; - } else { - x = args[0]; - y = args[1]; - z = args[2] || 1; - } + if (x instanceof p5.Vector) { + var v = x; + x = v.x; + y = v.y; + z = v.z; + } else if (x instanceof Array) { + var rg = x; + x = rg[0]; + y = rg[1]; + z = rg[2] || 1; } - - if (this._renderer.isP3D) { - this._renderer.scale.call(this._renderer, x, y, z); - } else { - this._renderer.scale.call(this._renderer, x, y); + if (isNaN(y)) { + y = z = x; + } else if (isNaN(z)) { + z = 1; } + + this._renderer.scale.call(this._renderer, x, y, z); + return this; }; diff --git a/src/data/p5.TypedDict.js b/src/data/p5.TypedDict.js index ebeb36d8ed..34350d6e45 100644 --- a/src/data/p5.TypedDict.js +++ b/src/data/p5.TypedDict.js @@ -34,8 +34,8 @@ var p5 = require('../core/core'); *
*/ -p5.prototype.createStringDict = function() { - return new p5.StringDict(arguments[0], arguments[1]); +p5.prototype.createStringDict = function(key, value) { + return new p5.StringDict(key, value); }; /** @@ -59,8 +59,8 @@ p5.prototype.createStringDict = function() { *
*/ -p5.prototype.createNumberDict = function() { - return new p5.NumberDict(arguments[0], arguments[1]); +p5.prototype.createNumberDict = function(key, value) { + return new p5.NumberDict(key, value); }; /** @@ -73,12 +73,12 @@ p5.prototype.createNumberDict = function() { * */ -p5.TypedDict = function() { - this.data = {}; - if (arguments[0][0] instanceof Object) { - this.data = arguments[0][0]; +p5.TypedDict = function(key, value) { + if (key instanceof Object) { + this.data = key; } else { - this.data[arguments[0][0]] = arguments[0][1]; + this.data = {}; + this.data[key] = value; } return this; }; @@ -177,12 +177,10 @@ p5.TypedDict.prototype.get = function(key) { */ p5.TypedDict.prototype.set = function(key, value) { - if (arguments.length === 2) { - if (!this.data.hasOwnProperty(key)) { - this.create(key, value); - } else { - this.data[key] = value; - } + if (this._validate(value)) { + this.data[key] = value; + } else { + console.log('Those values dont work for this dictionary type.'); } }; @@ -193,11 +191,7 @@ p5.TypedDict.prototype.set = function(key, value) { p5.TypedDict.prototype._addObj = function(obj) { for (var key in obj) { - if (this._validate(obj[key])) { - this.data[key] = obj[key]; - } else { - console.log('Those values dont work for this dictionary type.'); - } + this.set(key, obj[key]); } }; @@ -224,13 +218,11 @@ p5.TypedDict.prototype._addObj = function(obj) { * @param {Object} obj key/value pair */ -p5.TypedDict.prototype.create = function() { - if (arguments.length === 1 && arguments[0] instanceof Object) { - this._addObj(arguments[0]); - } else if (arguments.length === 2) { - var obj = {}; - obj[arguments[0]] = arguments[1]; - this._addObj(obj); +p5.TypedDict.prototype.create = function(key, value) { + if (key instanceof Object && typeof value === 'undefined') { + this._addObj(key); + } else if (typeof key !== 'undefined') { + this.set(key, value); } else { console.log( 'In order to create a new Dictionary entry you must pass ' + @@ -335,16 +327,15 @@ p5.TypedDict.prototype.print = function() { *
*/ -p5.TypedDict.prototype.saveTable = function() { +p5.TypedDict.prototype.saveTable = function(filename) { var output = ''; for (var key in this.data) { output += key + ',' + this.data[key] + '\n'; } - var filename = arguments[0] || 'mycsv'; var blob = new Blob([output], { type: 'text/csv' }); - p5.prototype.downloadFile(blob, filename, 'csv'); + p5.prototype.downloadFile(blob, filename || 'mycsv', 'csv'); }; /** @@ -378,7 +369,7 @@ p5.TypedDict.prototype.saveJSON = function(filename, opt) { * values for the Dictionary type */ -p5.TypedDict.prototype._validate = function(key, value) { +p5.TypedDict.prototype._validate = function(value) { return true; }; @@ -394,7 +385,7 @@ p5.TypedDict.prototype._validate = function(key, value) { */ p5.StringDict = function() { - p5.TypedDict.call(this, arguments); + p5.TypedDict.apply(this, arguments); }; p5.StringDict.prototype = Object.create(p5.TypedDict.prototype); @@ -415,7 +406,7 @@ p5.StringDict.prototype._validate = function(value) { */ p5.NumberDict = function() { - p5.TypedDict.call(this, arguments); + p5.TypedDict.apply(this, arguments); }; p5.NumberDict.prototype = Object.create(p5.TypedDict.prototype); diff --git a/src/math/polargeometry.js b/src/math/polargeometry.js index 31fc01a310..19f291c0c4 100644 --- a/src/math/polargeometry.js +++ b/src/math/polargeometry.js @@ -1,3 +1,5 @@ +'use strict'; + module.exports = { degreesToRadians: function(x) { return 2 * Math.PI * x / 360; diff --git a/src/typography/p5.Font.js b/src/typography/p5.Font.js index 89469307fb..5e9fd89607 100644 --- a/src/typography/p5.Font.js +++ b/src/typography/p5.Font.js @@ -1230,14 +1230,10 @@ function base3(t, p1, p2, p3, p4) { } function cacheKey() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - i = args.length; var hash = ''; - while (i--) { - hash += args[i] === Object(args[i]) ? JSON.stringify(args[i]) : args[i]; + for (var i = arguments.length - 1; i >= 0; --i) { + var v = arguments[i]; + hash += v === Object(v) ? JSON.stringify(v) : v; } return hash; } diff --git a/src/utilities/string_functions.js b/src/utilities/string_functions.js index 5845a2c7eb..528dac4d15 100644 --- a/src/utilities/string_functions.js +++ b/src/utilities/string_functions.js @@ -178,58 +178,55 @@ p5.prototype.matchAll = function(str, reg) { * @param {Number|String} [right] * @return {Array} formatted Strings\ */ -p5.prototype.nf = function() { +p5.prototype.nf = function(nums, left, right) { p5._validateParameters('nf', arguments); - if (arguments[0] instanceof Array) { - var a = arguments[1]; - var b = arguments[2]; - return arguments[0].map(function(x) { - return doNf(x, a, b); + if (nums instanceof Array) { + return nums.map(function(x) { + return doNf(x, left, right); }); } else { - var typeOfFirst = Object.prototype.toString.call(arguments[0]); + var typeOfFirst = Object.prototype.toString.call(nums); if (typeOfFirst === '[object Arguments]') { - if (arguments[0].length === 3) { - return this.nf(arguments[0][0], arguments[0][1], arguments[0][2]); - } else if (arguments[0].length === 2) { - return this.nf(arguments[0][0], arguments[0][1]); + if (nums.length === 3) { + return this.nf(nums[0], nums[1], nums[2]); + } else if (nums.length === 2) { + return this.nf(nums[0], nums[1]); } else { - return this.nf(arguments[0][0]); + return this.nf(nums[0]); } } else { - return doNf.apply(this, arguments); + return doNf(nums, left, right); } } }; -function doNf() { - var num = arguments[0]; +function doNf(num, left, right) { var neg = num < 0; var n = neg ? num.toString().substring(1) : num.toString(); var decimalInd = n.indexOf('.'); var intPart = decimalInd !== -1 ? n.substring(0, decimalInd) : n; var decPart = decimalInd !== -1 ? n.substring(decimalInd + 1) : ''; var str = neg ? '-' : ''; - if (arguments.length === 3) { + if (typeof right !== 'undefined') { var decimal = ''; - if (decimalInd !== -1 || arguments[2] - decPart.length > 0) { + if (decimalInd !== -1 || right - decPart.length > 0) { decimal = '.'; } - if (decPart.length > arguments[2]) { - decPart = decPart.substring(0, arguments[2]); + if (decPart.length > right) { + decPart = decPart.substring(0, right); } - for (var i = 0; i < arguments[1] - intPart.length; i++) { + for (var i = 0; i < left - intPart.length; i++) { str += '0'; } str += intPart; str += decimal; str += decPart; - for (var j = 0; j < arguments[2] - decPart.length; j++) { + for (var j = 0; j < right - decPart.length; j++) { str += '0'; } return str; } else { - for (var k = 0; k < Math.max(arguments[1] - intPart.length, 0); k++) { + for (var k = 0; k < Math.max(left - intPart.length, 0); k++) { str += '0'; } str += n; @@ -281,34 +278,33 @@ function doNf() { * @param {Number|String} [right] * @return {Array} formatted Strings */ -p5.prototype.nfc = function() { +p5.prototype.nfc = function(num, right) { p5._validateParameters('nfc', arguments); - if (arguments[0] instanceof Array) { - var a = arguments[1]; - return arguments[0].map(function(x) { - return doNfc(x, a); + if (num instanceof Array) { + return num.map(function(x) { + return doNfc(x, right); }); } else { - return doNfc.apply(this, arguments); + return doNfc(num, right); } }; -function doNfc() { - var num = arguments[0].toString(); +function doNfc(num, right) { + num = num.toString(); var dec = num.indexOf('.'); var rem = dec !== -1 ? num.substring(dec) : ''; var n = dec !== -1 ? num.substring(0, dec) : num; n = n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); - if (arguments[1] === 0) { + if (right === 0) { rem = ''; - } else if (arguments[1] !== undefined) { - if (arguments[1] > rem.length) { + } else if (typeof right !== 'undefined') { + if (right > rem.length) { rem += dec === -1 ? '.' : ''; - var len = arguments[1] - rem.length + 1; + var len = right - rem.length + 1; for (var i = 0; i < len; i++) { rem += '0'; } } else { - rem = rem.substring(0, arguments[1] + 1); + rem = rem.substring(0, right + 1); } } return n + rem; @@ -372,10 +368,8 @@ p5.prototype.nfp = function() { } }; -function addNfp() { - return parseFloat(arguments[0]) > 0 - ? '+' + arguments[0].toString() - : arguments[0].toString(); +function addNfp(num) { + return parseFloat(num) > 0 ? '+' + num.toString() : num.toString(); } /** @@ -436,10 +430,8 @@ p5.prototype.nfs = function() { } }; -function addNfs() { - return parseFloat(arguments[0]) > 0 - ? ' ' + arguments[0].toString() - : arguments[0].toString(); +function addNfs(num) { + return parseFloat(num) > 0 ? ' ' + num.toString() : num.toString(); } /** @@ -502,13 +494,13 @@ p5.prototype.split = function(str, delim) { * *
*/ -p5.prototype.splitTokens = function() { +p5.prototype.splitTokens = function(value, delims) { p5._validateParameters('splitTokens', arguments); - var d, sqo, sqc, str; - str = arguments[1]; - if (arguments.length > 1) { - sqc = /\]/g.exec(str); - sqo = /\[/g.exec(str); + var d; + if (typeof delims !== 'undefined') { + var str = delims; + var sqc = /\]/g.exec(str); + var sqo = /\[/g.exec(str); if (sqo && sqc) { str = str.slice(0, sqc.index) + str.slice(sqc.index + 1); sqo = /\[/g.exec(str); @@ -526,7 +518,7 @@ p5.prototype.splitTokens = function() { } else { d = /\s/g; } - return arguments[0].split(d).filter(function(n) { + return value.split(d).filter(function(n) { return n; }); }; diff --git a/src/webgl/camera.js b/src/webgl/camera.js index 40fbfd2f1c..1eb91d3ce9 100644 --- a/src/webgl/camera.js +++ b/src/webgl/camera.js @@ -51,11 +51,18 @@ p5.prototype.camera = function() { return this; }; -p5.RendererGL.prototype.camera = function() { - var eyeX, eyeY, eyeZ; - var centerX, centerY, centerZ; - var upX, upY, upZ; - if (arguments.length === 0) { +p5.RendererGL.prototype.camera = function( + eyeX, + eyeY, + eyeZ, + centerX, + centerY, + centerZ, + upX, + upY, + upZ +) { + if (typeof eyeX === 'undefined') { eyeX = this.defaultCameraX; eyeY = this.defaultCameraY; eyeZ = this.defaultCameraZ; @@ -65,16 +72,6 @@ p5.RendererGL.prototype.camera = function() { upX = 0; upY = 1; upZ = 0; - } else { - eyeX = arguments[0]; - eyeY = arguments[1]; - eyeZ = arguments[2]; - centerX = arguments[3]; - centerY = arguments[4]; - centerZ = arguments[5]; - upX = arguments[6]; - upY = arguments[7]; - upZ = arguments[8]; } this.cameraX = eyeX; @@ -206,11 +203,19 @@ p5.prototype.perspective = function() { return this; }; -p5.RendererGL.prototype.perspective = function() { - var fovy = arguments[0] || this.defaultCameraFOV; - var aspect = arguments[1] || this.defaultCameraAspect; - var near = arguments[2] || this.defaultCameraNear; - var far = arguments[3] || this.defaultCameraFar; +p5.RendererGL.prototype.perspective = function(fovy, aspect, near, far) { + if (typeof fovy === 'undefined') { + fovy = this.defaultCameraFOV; + } + if (typeof aspect === 'undefined') { + aspect = this.defaultCameraAspect; + } + if (typeof near === 'undefined') { + near = this.defaultCameraNear; + } + if (typeof far === 'undefined') { + far = this.defaultCameraFar; + } this.cameraFOV = fovy; this.cameraAspect = aspect; diff --git a/src/webgl/light.js b/src/webgl/light.js index a9fc720f18..e9173589d4 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -167,23 +167,15 @@ p5.prototype.directionalLight = function(v1, v2, v3, x, y, z) { this._renderer.curFillShader.setUniform('uDirectionalColor', colors); var _x, _y, _z; - - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - if (typeof args[args.length - 1] === 'number') { - _x = args[args.length - 3]; - _y = args[args.length - 2]; - _z = args[args.length - 1]; + var v = arguments[arguments.length - 1]; + if (typeof v === 'number') { + _x = arguments[arguments.length - 3]; + _y = arguments[arguments.length - 2]; + _z = arguments[arguments.length - 1]; } else { - try { - _x = args[args.length - 1].x; - _y = args[args.length - 1].y; - _z = args[args.length - 1].z; - } catch (error) { - throw error; - } + _x = v.x; + _y = v.y; + _z = v.z; } this._renderer.curFillShader.setUniform('uUseLighting', true); //in case there's no material color for the geometry @@ -281,23 +273,15 @@ p5.prototype.pointLight = function(v1, v2, v3, x, y, z) { this._renderer.curFillShader.setUniform('uPointLightColor', colors); var _x, _y, _z; - - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - if (typeof args[args.length - 1] === 'number') { - _x = args[args.length - 3]; - _y = args[args.length - 2]; - _z = args[args.length - 1]; + var v = arguments[arguments.length - 1]; + if (typeof v === 'number') { + _x = arguments[arguments.length - 3]; + _y = arguments[arguments.length - 2]; + _z = arguments[arguments.length - 1]; } else { - try { - _x = args[args.length - 1].x; - _y = args[args.length - 1].y; - _z = args[args.length - 1].z; - } catch (error) { - throw error; - } + _x = v.x; + _y = v.y; + _z = v.z; } this._renderer.curFillShader.setUniform('uUseLighting', true); //in case there's no material color for the geometry diff --git a/src/webgl/loading.js b/src/webgl/loading.js index 56100b253f..097fc9dbb2 100755 --- a/src/webgl/loading.js +++ b/src/webgl/loading.js @@ -63,8 +63,7 @@ require('./p5.Geometry'); * @param {function(Event)} [failureCallback] * @return {p5.Geometry} the p5.Geometry object */ -p5.prototype.loadModel = function() { - var path = arguments[0]; +p5.prototype.loadModel = function(path) { var normalize; var successCallback; var failureCallback; diff --git a/src/webgl/material.js b/src/webgl/material.js index d255b60bfb..d44ad79002 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -183,11 +183,7 @@ p5.prototype.normalMaterial = function() { * black canvas * */ -p5.prototype.texture = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } +p5.prototype.texture = function(tex) { this._renderer.GL.depthMask(true); this._renderer.GL.enable(this._renderer.GL.BLEND); this._renderer.GL.blendFunc( @@ -201,7 +197,7 @@ p5.prototype.texture = function() { } this._renderer.curFillShader.setUniform('uSpecular', false); this._renderer.curFillShader.setUniform('isTexture', true); - this._renderer.curFillShader.setUniform('uSampler', args[0]); + this._renderer.curFillShader.setUniform('uSampler', tex); this._renderer.noStroke(); return this; }; diff --git a/src/webgl/p5.RendererGL.Immediate.js b/src/webgl/p5.RendererGL.Immediate.js index 8baf7082ee..c1cdc3d8a2 100644 --- a/src/webgl/p5.RendererGL.Immediate.js +++ b/src/webgl/p5.RendererGL.Immediate.js @@ -67,12 +67,10 @@ p5.RendererGL.prototype.beginShape = function(mode) { * @chainable * @TODO implement handling of p5.Vector args */ -p5.RendererGL.prototype.vertex = function() { - var x, y, z, u, v; +p5.RendererGL.prototype.vertex = function(x, y) { + var z, u, v; // default to (x, y) mode: all other arugments assumed to be 0. - x = arguments[0]; - y = arguments[1]; z = u = v = 0; if (arguments.length === 3) { diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 9ddc4ea398..994579257c 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -215,8 +215,8 @@ p5.RendererGL.prototype._resetContext = function(attr, options, callback) { *

* @method setAttributes * @for p5 - * @param {String|Object} String name of attribute or object with key-value pairs - * @param {Boolean} New value of named attribute + * @param {String} key Name of attribute + * @param {Boolean} value New value of named attribute * @example *
* @@ -261,14 +261,20 @@ p5.RendererGL.prototype._resetContext = function(attr, options, callback) { * * @alt a rotating cube with smoother edges */ +/** + * @method setAttributes + * @for p5 + * @param {Object} obj object with key-value pairs + */ -p5.prototype.setAttributes = function() { +p5.prototype.setAttributes = function(key, value) { //@todo_FES - var attr = {}; - if (arguments.length === 2) { - attr[arguments[0]] = arguments[1]; - } else if (arguments.length === 1) { - attr = arguments[0]; + var attr; + if (typeof value !== 'undefined') { + attr = {}; + attr.key = value; + } else if (key instanceof Object) { + attr = key; } this._renderer._resetContext(attr); }; diff --git a/src/webgl/p5.Shader.js b/src/webgl/p5.Shader.js index 61d1acee28..bd60414beb 100644 --- a/src/webgl/p5.Shader.js +++ b/src/webgl/p5.Shader.js @@ -6,6 +6,8 @@ * @requires core */ +'use strict'; + var p5 = require('../core/core'); /** diff --git a/src/webgl/p5.Texture.js b/src/webgl/p5.Texture.js index afe6bf87cc..e6ec024e05 100644 --- a/src/webgl/p5.Texture.js +++ b/src/webgl/p5.Texture.js @@ -6,6 +6,8 @@ * @requires core */ +'use strict'; + var p5 = require('../core/core'); /** diff --git a/src/webgl/primitives.js b/src/webgl/primitives.js index b0ea76e9db..04b40acbd0 100644 --- a/src/webgl/primitives.js +++ b/src/webgl/primitives.js @@ -44,15 +44,20 @@ require('./p5.Geometry'); * 3d red and green gradient. * rotating view of a multi-colored cylinder with concave sides. */ -p5.prototype.plane = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; +p5.prototype.plane = function(width, height, detailX, detailY) { + if (typeof width === 'undefined') { + width = 50; + } + if (typeof height === 'undefined') { + height = width; + } + + if (typeof detailX === 'undefined') { + detailX = 1; + } + if (typeof detailY === 'undefined') { + detailY = 1; } - var width = args[0] || 50; - var height = args[1] || width; - var detailX = typeof args[2] === 'number' ? args[2] : 1; - var detailY = typeof args[3] === 'number' ? args[3] : 1; var gId = 'plane|' + width + '|' + height + '|' + detailX + '|' + detailY; @@ -114,17 +119,24 @@ p5.prototype.plane = function() { * *
*/ -p5.prototype.box = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; +p5.prototype.box = function(width, height, depth, detailX, detailY) { + if (typeof width === 'undefined') { + width = 50; + } + if (typeof height === 'undefined') { + height = width; + } + if (typeof depth === 'undefined') { + depth = height; + } + + if (typeof detailX === 'undefined') { + detailX = 4; + } + if (typeof detailY === 'undefined') { + detailY = 4; } - var width = args[0] || 50; - var height = args[1] || width; - var depth = args[2] || width; - var detailX = typeof args[3] === 'number' ? args[3] : 4; - var detailY = typeof args[4] === 'number' ? args[4] : 4; var gId = 'box|' + width + '|' + height + '|' + depth + '|' + detailX + '|' + detailY; if (!this._renderer.geometryInHash(gId)) { @@ -220,14 +232,16 @@ p5.prototype.box = function() { * *
*/ -p5.prototype.sphere = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; +p5.prototype.sphere = function(radius, detailX, detailY) { + if (typeof radius === 'undefined') { + radius = 50; + } + if (typeof detailX === 'undefined') { + detailX = 24; + } + if (typeof detailY === 'undefined') { + detailY = 16; } - var radius = args[0] || 50; - var detailX = typeof args[1] === 'number' ? args[1] : 24; - var detailY = typeof args[2] === 'number' ? args[2] : 16; var gId = 'sphere|' + radius + '|' + detailX + '|' + detailY; if (!this._renderer.geometryInHash(gId)) { @@ -387,15 +401,20 @@ var _truncatedCone = function( * *
*/ -p5.prototype.cylinder = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - var radius = args[0] || 50; - var height = args[1] || radius; - var detailX = typeof args[2] === 'number' ? args[2] : 24; - var detailY = typeof args[3] === 'number' ? args[3] : 16; +p5.prototype.cylinder = function(radius, height, detailX, detailY) { + if (typeof radius === 'undefined') { + radius = 50; + } + if (typeof height === 'undefined') { + height = radius; + } + if (typeof detailX === 'undefined') { + detailX = 24; + } + if (typeof detailY === 'undefined') { + detailY = 16; + } + var gId = 'cylinder|' + radius + '|' + height + '|' + detailX + '|' + detailY; if (!this._renderer.geometryInHash(gId)) { var cylinderGeom = new p5.Geometry(detailX, detailY); @@ -456,21 +475,26 @@ p5.prototype.cylinder = function() { * *
*/ -p5.prototype.cone = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - var baseRadius = args[0] || 50; - var height = args[1] || baseRadius; - var detailX = typeof args[2] === 'number' ? args[2] : 24; - var detailY = typeof args[3] === 'number' ? args[3] : 16; - var gId = 'cone|' + baseRadius + '|' + height + '|' + detailX + '|' + detailY; +p5.prototype.cone = function(radius, height, detailX, detailY) { + if (typeof radius === 'undefined') { + radius = 50; + } + if (typeof height === 'undefined') { + height = radius; + } + if (typeof detailX === 'undefined') { + detailX = 24; + } + if (typeof detailY === 'undefined') { + detailY = 16; + } + + var gId = 'cone|' + radius + '|' + height + '|' + detailX + '|' + detailY; if (!this._renderer.geometryInHash(gId)) { var coneGeom = new p5.Geometry(detailX, detailY); _truncatedCone.call( coneGeom, - baseRadius, + radius, 0, //top radius 0 height, detailX, @@ -527,16 +551,23 @@ p5.prototype.cone = function() { * *
*/ -p5.prototype.ellipsoid = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; +p5.prototype.ellipsoid = function(radiusX, radiusY, radiusZ, detailX, detailY) { + if (typeof radiusX === 'undefined') { + radiusX = 50; + } + if (typeof radiusY === 'undefined') { + radiusY = radiusX; + } + if (typeof radiusZ === 'undefined') { + radiusZ = radiusX; + } + + if (typeof detailX === 'undefined') { + detailX = 24; + } + if (typeof detailY === 'undefined') { + detailY = 16; } - var detailX = typeof args[3] === 'number' ? args[3] : 24; - var detailY = typeof args[4] === 'number' ? args[4] : 24; - var radiusX = args[0] || 50; - var radiusY = args[1] || radiusX; - var radiusZ = args[2] || radiusX; var gId = 'ellipsoid|' + @@ -617,16 +648,20 @@ p5.prototype.ellipsoid = function() { * *
*/ -p5.prototype.torus = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; +p5.prototype.torus = function(radius, tubeRadius, detailX, detailY) { + if (typeof radius === 'undefined') { + radius = 50; + } + if (typeof tubeRadius === 'undefined') { + tubeRadius = 10; } - var detailX = typeof args[2] === 'number' ? args[2] : 24; - var detailY = typeof args[3] === 'number' ? args[3] : 16; - var radius = args[0] || 50; - var tubeRadius = args[1] || 10; + if (typeof detailX === 'undefined') { + detailX = 24; + } + if (typeof detailY === 'undefined') { + detailY = 16; + } var gId = 'torus|' + radius + '|' + tubeRadius + '|' + detailX + '|' + detailY; @@ -796,19 +831,7 @@ p5.RendererGL.prototype.rect = function(args) { return this; }; -p5.RendererGL.prototype.quad = function() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) { - args[i] = arguments[i]; - } - var x1 = args[0], - y1 = args[1], - x2 = args[2], - y2 = args[3], - x3 = args[4], - y3 = args[5], - x4 = args[6], - y4 = args[7]; +p5.RendererGL.prototype.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) { var gId = 'quad|' + x1 + @@ -847,63 +870,76 @@ p5.RendererGL.prototype.quad = function() { //this implementation of bezier curve //is based on Bernstein polynomial -p5.RendererGL.prototype.bezier = function(args) { - var bezierDetail = args[12] || 20; //value of Bezier detail +// pretier-ignore +p5.RendererGL.prototype.bezier = function( + x1, + y1, + z1, + x2, + y2, + z2, + x3, + y3, + z3, + x4, + y4, + z4 +) { + var bezierDetail = this._pInst._bezierDetail || 20; //value of Bezier detail this.beginShape(); - var coeff = [0, 0, 0, 0]; // Bernstein polynomial coeffecients - var vertex = [0, 0, 0]; //(x,y,z) coordinates of points in bezier curve for (var i = 0; i <= bezierDetail; i++) { - coeff[0] = Math.pow(1 - i / bezierDetail, 3); - coeff[1] = 3 * (i / bezierDetail) * Math.pow(1 - i / bezierDetail, 2); - coeff[2] = 3 * Math.pow(i / bezierDetail, 2) * (1 - i / bezierDetail); - coeff[3] = Math.pow(i / bezierDetail, 3); - vertex[0] = - args[0] * coeff[0] + - args[3] * coeff[1] + - args[6] * coeff[2] + - args[9] * coeff[3]; - vertex[1] = - args[1] * coeff[0] + - args[4] * coeff[1] + - args[7] * coeff[2] + - args[10] * coeff[3]; - vertex[2] = - args[2] * coeff[0] + - args[5] * coeff[1] + - args[8] * coeff[2] + - args[11] * coeff[3]; - this.vertex(vertex[0], vertex[1], vertex[2]); + var c1 = Math.pow(1 - i / bezierDetail, 3); + var c2 = 3 * (i / bezierDetail) * Math.pow(1 - i / bezierDetail, 2); + var c3 = 3 * Math.pow(i / bezierDetail, 2) * (1 - i / bezierDetail); + var c4 = Math.pow(i / bezierDetail, 3); + this.vertex( + x1 * c1 + x2 * c2 + x3 * c3 + x4 * c4, + y1 * c1 + y2 * c2 + y3 * c3 + y4 * c4, + z1 * c1 + z2 * c2 + z3 * c3 + z4 * c4 + ); } this.endShape(); return this; }; -p5.RendererGL.prototype.curve = function(args) { - var curveDetail = args[12]; +// pretier-ignore +p5.RendererGL.prototype.curve = function( + x1, + y1, + z1, + x2, + y2, + z2, + x3, + y3, + z3, + x4, + y4, + z4 +) { + var curveDetail = this._pInst._curveDetail; this.beginShape(); - var coeff = [0, 0, 0, 0]; //coeffecients of the equation - var vertex = [0, 0, 0]; //(x,y,z) coordinates of points in bezier curve for (var i = 0; i <= curveDetail; i++) { - coeff[0] = Math.pow(i / curveDetail, 3) * 0.5; - coeff[1] = Math.pow(i / curveDetail, 2) * 0.5; - coeff[2] = i / curveDetail * 0.5; - coeff[3] = 0.5; - vertex[0] = - coeff[0] * (-args[0] + 3 * args[3] - 3 * args[6] + args[9]) + - coeff[1] * (2 * args[0] - 5 * args[3] + 4 * args[6] - args[9]) + - coeff[2] * (-args[0] + args[6]) + - coeff[3] * (2 * args[3]); - vertex[1] = - coeff[0] * (-args[1] + 3 * args[4] - 3 * args[7] + args[10]) + - coeff[1] * (2 * args[1] - 5 * args[4] + 4 * args[7] - args[10]) + - coeff[2] * (-args[1] + args[7]) + - coeff[3] * (2 * args[4]); - vertex[2] = - coeff[0] * (-args[2] + 3 * args[5] - 3 * args[8] + args[11]) + - coeff[1] * (2 * args[2] - 5 * args[5] + 4 * args[8] - args[11]) + - coeff[2] * (-args[2] + args[8]) + - coeff[3] * (2 * args[5]); - this.vertex(vertex[0], vertex[1], vertex[2]); + var c1 = Math.pow(i / curveDetail, 3) * 0.5; + var c2 = Math.pow(i / curveDetail, 2) * 0.5; + var c3 = i / curveDetail * 0.5; + var c4 = 0.5; + var vx = + c1 * (-x1 + 3 * x2 - 3 * x3 + x4) + + c2 * (2 * x1 - 5 * x2 + 4 * x3 - x4) + + c3 * (-x1 + x3) + + c4 * (2 * x2); + var vy = + c1 * (-y1 + 3 * y2 - 3 * y3 + y4) + + c2 * (2 * y1 - 5 * y2 + 4 * y3 - y4) + + c3 * (-y1 + y3) + + c4 * (2 * y2); + var vz = + c1 * (-z1 + 3 * z2 - 3 * z3 + z4) + + c2 * (2 * z1 - 5 * z2 + 4 * z3 - z4) + + c3 * (-z1 + z3) + + c4 * (2 * z2); + this.vertex(vx, vy, vz); } this.endShape(); return this; From a72307d503d77988818fa67e7ecd21bae37df65b Mon Sep 17 00:00:00 2001 From: piersh Date: Fri, 22 Dec 2017 11:11:17 -0800 Subject: [PATCH 16/31] implicit normal calculation --- src/webgl/primitives.js | 89 +++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/src/webgl/primitives.js b/src/webgl/primitives.js index b0ea76e9db..0764d64493 100644 --- a/src/webgl/primitives.js +++ b/src/webgl/primitives.js @@ -232,29 +232,28 @@ p5.prototype.sphere = function() { var gId = 'sphere|' + radius + '|' + detailX + '|' + detailY; if (!this._renderer.geometryInHash(gId)) { var _sphere = function() { - var u, v, p; for (var i = 0; i <= this.detailY; i++) { - v = i / this.detailY; + var v = i / this.detailY; + var phi = Math.PI * v - Math.PI / 2; + var cosPhi = Math.cos(phi); + var sinPhi = Math.sin(phi); + for (var j = 0; j <= this.detailX; j++) { - u = j / this.detailX; + var u = j / this.detailX; var theta = 2 * Math.PI * u; - var phi = Math.PI * v - Math.PI / 2; - p = new p5.Vector( - radius * Math.cos(phi) * Math.sin(theta), - radius * Math.sin(phi), - radius * Math.cos(phi) * Math.cos(theta) + var n = new p5.Vector( + cosPhi * Math.sin(theta), + sinPhi, + cosPhi * Math.cos(theta) ); - this.vertices.push(p); + this.vertexNormals.push(n); + this.vertices.push(p5.Vector.mult(n, radius)); this.uvs.push([u, v]); } } }; var sphereGeom = new p5.Geometry(detailX, detailY, _sphere); - sphereGeom - .computeFaces() - .computeNormals() - .averageNormals() - .averagePoleNormals(); + sphereGeom.computeFaces(); if (detailX <= 24 && detailY <= 16) { sphereGeom._makeTriangleEdges(); this._renderer._edgesToVertices(sphereGeom); @@ -552,25 +551,36 @@ p5.prototype.ellipsoid = function() { if (!this._renderer.geometryInHash(gId)) { var _ellipsoid = function() { - var u, v, p; for (var i = 0; i <= this.detailY; i++) { - v = i / this.detailY; + var v = i / this.detailY; + var phi = Math.PI * v - Math.PI / 2; + var cosPhi = Math.cos(phi); + var sinPhi = Math.sin(phi); + for (var j = 0; j <= this.detailX; j++) { - u = j / this.detailX; + var u = j / this.detailX; var theta = 2 * Math.PI * u; - var phi = Math.PI * v - Math.PI / 2; - p = new p5.Vector( - radiusX * Math.cos(phi) * Math.sin(theta), - radiusY * Math.sin(phi), - radiusZ * Math.cos(phi) * Math.cos(theta) + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); + var p = new p5.Vector( + radiusX * cosPhi * sinTheta, + radiusY * sinPhi, + radiusZ * cosPhi * cosTheta ); + var n = new p5.Vector( + cosPhi * sinTheta / radiusX, + sinPhi / radiusY, + cosPhi * cosTheta / radiusZ + ).normalize(); + this.vertices.push(p); + this.vertexNormals.push(n); this.uvs.push([u, v]); } } }; var ellipsoidGeom = new p5.Geometry(detailX, detailY, _ellipsoid); - ellipsoidGeom.computeFaces().computeNormals(); + ellipsoidGeom.computeFaces(); if (detailX <= 24 && detailY <= 24) { ellipsoidGeom._makeTriangleEdges(); this._renderer._edgesToVertices(ellipsoidGeom); @@ -633,28 +643,37 @@ p5.prototype.torus = function() { if (!this._renderer.geometryInHash(gId)) { var _torus = function() { - var u, v, p; for (var i = 0; i <= this.detailY; i++) { - v = i / this.detailY; + var v = i / this.detailY; + var phi = 2 * Math.PI * v; + var cosPhi = Math.cos(phi); + var sinPhi = Math.sin(phi); + for (var j = 0; j <= this.detailX; j++) { - u = j / this.detailX; + var u = j / this.detailX; var theta = 2 * Math.PI * u; - var phi = 2 * Math.PI * v; - p = new p5.Vector( - (radius + tubeRadius * Math.cos(phi)) * Math.cos(theta), - (radius + tubeRadius * Math.cos(phi)) * Math.sin(theta), - tubeRadius * Math.sin(phi) + var cosTheta = Math.cos(theta); + var sinTheta = Math.sin(theta); + + var p = new p5.Vector( + (radius + tubeRadius * cosPhi) * cosTheta, + (radius + tubeRadius * cosPhi) * sinTheta, + tubeRadius * sinPhi + ); + var n = new p5.Vector( + tubeRadius * cosPhi * cosTheta, + tubeRadius * cosPhi * sinTheta, + tubeRadius * sinPhi ); + this.vertices.push(p); + this.vertexNormals.push(n); this.uvs.push([u, v]); } } }; var torusGeom = new p5.Geometry(detailX, detailY, _torus); - torusGeom - .computeFaces() - .computeNormals() - .averageNormals(); + torusGeom.computeFaces(); if (detailX <= 24 && detailY <= 16) { torusGeom._makeTriangleEdges(); this._renderer._edgesToVertices(torusGeom); From e2d1181d40728e0f65f7f25defffe43af5391ae8 Mon Sep 17 00:00:00 2001 From: Spongman Date: Fri, 22 Dec 2017 19:13:35 -0800 Subject: [PATCH 17/31] normalize torus normal --- src/webgl/primitives.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/webgl/primitives.js b/src/webgl/primitives.js index 0764d64493..e78f0361d1 100644 --- a/src/webgl/primitives.js +++ b/src/webgl/primitives.js @@ -661,9 +661,9 @@ p5.prototype.torus = function() { tubeRadius * sinPhi ); var n = new p5.Vector( - tubeRadius * cosPhi * cosTheta, - tubeRadius * cosPhi * sinTheta, - tubeRadius * sinPhi + cosPhi * cosTheta, + cosPhi * sinTheta, + sinPhi ); this.vertices.push(p); From f5a89b025d1460c5a037c65b02b26ae4536e06dc Mon Sep 17 00:00:00 2001 From: Nitish Bansal Date: Sat, 23 Dec 2017 22:43:27 +0530 Subject: [PATCH 18/31] Added example for clearCues --- lib/addons/p5.dom.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index 5ee75eaee0..89a0a2bf8a 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -2595,8 +2595,34 @@ /** * Remove all of the callbacks that had originally been scheduled * via the addCue method. - * * @method clearCues + * @param {Number} id ID of the cue, as returned by addCue + * @example + *
+ * var audioEl; + * function setup() { + * background(255, 255, 255); + * audioEl = createAudio('assets/beat.mp3'); + * //this call allows the mediaelement to + * //play as soon as its loaded + * //and sets it to loop indefinitely + * audioEl.autoplay(true).loop(); + * // schedule calls to changeBackground + * audioEl.addCue(0.5, changeBackground, color(255, 0, 0)); + * audioEl.addCue(1.0, changeBackground, color(0, 255, 0)); + * audioEl.addCue(2.5, changeBackground, color(0, 0, 255)); + * audioEl.addCue(3.0, changeBackground, color(0, 255, 255)); + * audioEl.addCue(4.2, changeBackground, color(255, 255, 0)); + * // here we clear the scheduled callbacks + * audioEl.clearCues(); + * // then we add some more callbacks + * audioEl.addCue(0.5, changeBackground, color(2, 2, 2)); + * audioEl.addCue(1.5, changeBackground, color(255, 255, 0)); + * } + * function changeBackground(val) { + * background(val); + *} + *
*/ p5.MediaElement.prototype.clearCues = function() { this._cues = []; From 4083775850442075dd620e6e400d75186784ae07 Mon Sep 17 00:00:00 2001 From: Nitish Bansal Date: Sat, 23 Dec 2017 23:17:25 +0530 Subject: [PATCH 19/31] Fixed Build failure --- lib/addons/p5.dom.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index 89a0a2bf8a..2778d07d49 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -2606,7 +2606,7 @@ * //this call allows the mediaelement to * //play as soon as its loaded * //and sets it to loop indefinitely - * audioEl.autoplay(true).loop(); + * audioEl.showControls(); * // schedule calls to changeBackground * audioEl.addCue(0.5, changeBackground, color(255, 0, 0)); * audioEl.addCue(1.0, changeBackground, color(0, 255, 0)); From f700f0c87b0924e03000b2b609665e9aa892a4e9 Mon Sep 17 00:00:00 2001 From: Nitish Bansal Date: Sat, 23 Dec 2017 23:36:23 +0530 Subject: [PATCH 20/31] Added description for showControls --- lib/addons/p5.dom.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index 2778d07d49..d4ab46e39c 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -2603,9 +2603,7 @@ * function setup() { * background(255, 255, 255); * audioEl = createAudio('assets/beat.mp3'); - * //this call allows the mediaelement to - * //play as soon as its loaded - * //and sets it to loop indefinitely + * //Show the default MediaElement controls, as determined by the web browser * audioEl.showControls(); * // schedule calls to changeBackground * audioEl.addCue(0.5, changeBackground, color(255, 0, 0)); From 20f4343f3630f5cd881405b3e44006ab6d435bd2 Mon Sep 17 00:00:00 2001 From: Spongman Date: Sat, 23 Dec 2017 11:18:47 -0800 Subject: [PATCH 21/31] prettify --- src/webgl/primitives.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/webgl/primitives.js b/src/webgl/primitives.js index e78f0361d1..1e35d3ad03 100644 --- a/src/webgl/primitives.js +++ b/src/webgl/primitives.js @@ -660,11 +660,7 @@ p5.prototype.torus = function() { (radius + tubeRadius * cosPhi) * sinTheta, tubeRadius * sinPhi ); - var n = new p5.Vector( - cosPhi * cosTheta, - cosPhi * sinTheta, - sinPhi - ); + var n = new p5.Vector(cosPhi * cosTheta, cosPhi * sinTheta, sinPhi); this.vertices.push(p); this.vertexNormals.push(n); From ee483b920b756e9135912a474bc0aa9d3092bb98 Mon Sep 17 00:00:00 2001 From: piersh Date: Sat, 23 Dec 2017 20:11:39 -0800 Subject: [PATCH 22/31] fix RendererGL._resetContext() prettify --- src/webgl/p5.RendererGL.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index c655767bd4..d9bcafb4cf 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -171,13 +171,11 @@ p5.RendererGL.prototype._resetContext = function(attr, options, callback) { document.body.appendChild(c); } this._pInst.canvas = c; - this._pInst._setProperty( - '_renderer', - new p5.RendererGL(this._pInst.canvas, this._pInst, true, attr) - ); - this._pInst._renderer.resize(w, h); - this._pInst._renderer._applyDefaults(); - this._pInst._elements.push(this._renderer); + var renderer = new p5.RendererGL(this._pInst.canvas, this._pInst, true, attr); + this._pInst._setProperty('_renderer', renderer); + renderer.resize(w, h); + renderer._applyDefaults(); + this._pInst._elements.push(renderer); if (typeof callback === 'function') { //setTimeout with 0 forces the task to the back of the queue, this ensures that //we finish switching out the renderer From 004361b8b90b166e7211e1c0526869129df4f9c3 Mon Sep 17 00:00:00 2001 From: Spongman Date: Sat, 23 Dec 2017 20:52:56 -0800 Subject: [PATCH 23/31] Update item.html fix ','/and in 'Used by' list --- docs/yuidoc-p5-theme-src/scripts/tpl/item.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/yuidoc-p5-theme-src/scripts/tpl/item.html b/docs/yuidoc-p5-theme-src/scripts/tpl/item.html index 7549ea4883..77473e7a14 100644 --- a/docs/yuidoc-p5-theme-src/scripts/tpl/item.html +++ b/docs/yuidoc-p5-theme-src/scripts/tpl/item.html @@ -42,10 +42,12 @@

Description

if (name.substr(0, 3) === 'p5.') { name = name.substr(3); } - if (i == refs.length - 1) { - %> and <% - } else if (i !== 0) { - %>, <% + if (i !== 0) { + if (i == refs.length - 1) { + %> and <% + } else { + %>, <% + } } %><%= name %>()<% } @@ -168,4 +170,4 @@

Returns

<%=item.return.type%>: <%= item.return.description %>

<% } %>
-<% } %> \ No newline at end of file +<% } %> From eb84ce0636bb882b1bd7b257caa17adf513ac7f8 Mon Sep 17 00:00:00 2001 From: Nitish Bansal Date: Sun, 24 Dec 2017 13:18:09 +0530 Subject: [PATCH 24/31] Added mousePressed function --- lib/addons/p5.dom.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index d4ab46e39c..acae2c97b1 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -2606,20 +2606,24 @@ * //Show the default MediaElement controls, as determined by the web browser * audioEl.showControls(); * // schedule calls to changeBackground + * background(200); + * text('Click to change Cue!', 10, 25, 70, 80); * audioEl.addCue(0.5, changeBackground, color(255, 0, 0)); * audioEl.addCue(1.0, changeBackground, color(0, 255, 0)); * audioEl.addCue(2.5, changeBackground, color(0, 0, 255)); * audioEl.addCue(3.0, changeBackground, color(0, 255, 255)); * audioEl.addCue(4.2, changeBackground, color(255, 255, 0)); + * } + * function mousePressed() { * // here we clear the scheduled callbacks * audioEl.clearCues(); * // then we add some more callbacks - * audioEl.addCue(0.5, changeBackground, color(2, 2, 2)); - * audioEl.addCue(1.5, changeBackground, color(255, 255, 0)); + * audioEl.addCue(1, changeBackground, color(2, 2, 2)); + * audioEl.addCue(3, changeBackground, color(255, 255, 0)); * } * function changeBackground(val) { * background(val); - *} + * } *
*/ p5.MediaElement.prototype.clearCues = function() { From 7955564624c691ae0bbb8ffbe2b7f1b01d47797c Mon Sep 17 00:00:00 2001 From: Nitish Bansal Date: Sun, 24 Dec 2017 17:39:34 +0530 Subject: [PATCH 25/31] Added example for hideControls() --- lib/addons/p5.dom.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index 8aeb8b7e30..11d0424d83 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -2550,8 +2550,28 @@ /** * Hide the default mediaElement controls. - * * @method hideControls + * @example + *
+ * var ele; + * function setup() { + * //p5.MediaElement objects are usually created + * //by calling the createAudio(), createVideo(), + * //and createCapture() functions. + * //In this example we create + * //a new p5.MediaElement via createAudio() + * ele = createAudio('assets/lucky_dragons_-_power_melody.mp3'); + * ele.showControls(); + * background(200); + * textAlign(CENTER); + * text('Click to hide Controls!', 10, 25, 70, 80); + * } + * function mousePressed() { + * ele.hideControls(); + * background(200); + * text('Controls hidden', width / 2, height / 2); + * } + *
*/ p5.MediaElement.prototype.hideControls = function() { this.elt.controls = false; From 79177306b81051a5f90c695eb017fb86969a2e2c Mon Sep 17 00:00:00 2001 From: Nitish Bansal Date: Sun, 24 Dec 2017 23:08:02 +0530 Subject: [PATCH 26/31] Corrected if condition and added example --- lib/addons/p5.dom.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index 8aeb8b7e30..33b4950acc 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -2633,13 +2633,35 @@ /** * Remove a callback based on its ID. The ID is returned by the * addCue method. - * * @method removeCue * @param {Number} id ID of the cue, as returned by addCue + * @example + *
+ * var audioEl, id1, id2; + * function setup() { + * background(255, 255, 255); + * audioEl = createAudio('assets/beat.mp3'); + * audioEl.showControls(); + * // schedule five calls to changeBackground + * id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0)); + * audioEl.addCue(1.0, changeBackground, color(0, 255, 0)); + * audioEl.addCue(2.5, changeBackground, color(0, 0, 255)); + * audioEl.addCue(3.0, changeBackground, color(0, 255, 255)); + * id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0)); + * text('Click to remove first and last Cue!', 10, 25, 70, 80); + * } + * function mousePressed() { + * audioEl.removeCue(id1); + * audioEl.removeCue(id2); + * } + * function changeBackground(val) { + * background(val); + * } + *
*/ p5.MediaElement.prototype.removeCue = function(id) { for (var i = 0; i < this._cues.length; i++) { - if (this._cues[i] === id) { + if (this._cues[i].id === id) { console.log(id); this._cues.splice(i, 1); } From 423c0e2762fafb27206d64621b7818f7f0e05e36 Mon Sep 17 00:00:00 2001 From: Stalgia Grigg Date: Sun, 24 Dec 2017 14:11:10 -0800 Subject: [PATCH 27/31] Add non-recursive array flattening for larger models --- src/webgl/p5.RendererGL.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index c655767bd4..8bf0ea1bbb 100755 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -940,7 +940,30 @@ p5.RendererGL.prototype._bindBuffer = function( */ p5.RendererGL.prototype._flatten = function(arr) { if (arr.length > 0) { - return [].concat.apply([], arr); + //big models , load slower to avoid stack overflow + //non-recursive flatten via axelduch + //stackoverflow.com/questions/27266550/how-to-flatten-nested-array-in-javascript + if (arr.length > 20000) { + var toString = Object.prototype.toString; + var arrayTypeStr = '[object Array]'; + var result = []; + var nodes = arr.slice(); + var node; + node = nodes.pop(); + do { + if (toString.call(node) === arrayTypeStr) { + nodes.push.apply(nodes, node); + } else { + result.push(node); + } + } while (nodes.length && (node = nodes.pop()) !== undefined); + result.reverse(); // we reverse result to restore the original order + return result; + } else { + //otherwise if model within limits for browser + //use faster loading + return [].concat.apply([], arr); + } } else { return []; } From 5fcd44385d93b58b974370c1ce332216d5bd666f Mon Sep 17 00:00:00 2001 From: Spongman Date: Wed, 27 Dec 2017 11:55:45 -0800 Subject: [PATCH 28/31] Update setting.js add missing `
` tag --- src/color/setting.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/color/setting.js b/src/color/setting.js index 52ec8bf194..31a1597fcb 100644 --- a/src/color/setting.js +++ b/src/color/setting.js @@ -280,6 +280,7 @@ p5.prototype.clear = function() { * ellipse(40, 40, 50, 50); * ellipse(50, 50, 40, 40); * + *
* * @alt *Green to red gradient from bottom L to top R. shading originates from top left. From 2b023e7b4c3aa22faa1d0c2a257a03b0b6947dc5 Mon Sep 17 00:00:00 2001 From: Spongman Date: Wed, 27 Dec 2017 12:10:28 -0800 Subject: [PATCH 29/31] also server non-minified libs useful when testing doc samples --- Gruntfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index e004b2ef8f..aa079046d5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -314,8 +314,8 @@ module.exports = function(grunt) { middleware: function(connect, options, middlewares) { middlewares.unshift( require('connect-modrewrite')([ - '^/assets/js/p5\\.min\\.js(.*) /lib/p5.min.js$1 [L]', - '^/assets/js/p5\\.(dom|sound)\\.min\\.js(.*) /lib/addons/p5.$1.min.js$2 [L]' + '^/assets/js/p5(\\.min)?\\.js(.*) /lib/p5$1.js$2 [L]', + '^/assets/js/p5\\.(dom|sound)(\\.min)?\\.js(.*) /lib/addons/p5.$1$2.js$3 [L]' ]), function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); From a46ee3c400e0a454b033581dc2c24412734e207a Mon Sep 17 00:00:00 2001 From: Blaize Kaye Date: Thu, 28 Dec 2017 11:11:30 +1300 Subject: [PATCH 30/31] removed comment from vertex documentation --- src/core/vertex.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/vertex.js b/src/core/vertex.js index 6bcdf68fa3..9983a60f2f 100644 --- a/src/core/vertex.js +++ b/src/core/vertex.js @@ -102,7 +102,6 @@ p5.prototype.beginContour = function() { * *
* - * // currently not working * beginShape(POINTS); * vertex(30, 20); * vertex(85, 20); From beb263abba805dc305384685472fa46b20bc22ac Mon Sep 17 00:00:00 2001 From: Nitish Bansal Date: Thu, 28 Dec 2017 23:56:05 +0530 Subject: [PATCH 31/31] Added volume example --- lib/addons/p5.dom.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/addons/p5.dom.js b/lib/addons/p5.dom.js index 8fb752023c..0d6aad1349 100644 --- a/lib/addons/p5.dom.js +++ b/lib/addons/p5.dom.js @@ -2176,6 +2176,30 @@ * @param {Number} [val] volume between 0.0 and 1.0 * @return {Number|p5.MediaElement} current volume or p5.MediaElement * @method volume + * + * @example + *
+ * var ele; + * function setup(){ + * //p5.MediaElement objects are usually created + * //by calling the createAudio(), createVideo(), + * //and createCapture() functions. + * //In this example we create + * //a new p5.MediaElement via createAudio(). + * ele = createAudio('assets/lucky_dragons_-_power_melody.mp3'); + * background(250); + * textAlign(CENTER); + * text("Click to Play!", width/2, height/2); + * } + * function mouseClicked() { + * //Here we call the volume() function + * //on the sound element to set its volume + * //Volume must be between 0.0 and 1.0 + * ele.volume(0.2) + * ele.play(); + * background(200); + * text("You clicked Play!", width/2, height/2); + * } */ p5.MediaElement.prototype.volume = function(val) { if (typeof val === 'undefined') {