diff --git a/javascript/applet_js/processing.js b/javascript/applet_js/processing.js
index b3c9bf8e6..45c550fdd 100644
--- a/javascript/applet_js/processing.js
+++ b/javascript/applet_js/processing.js
@@ -1,6 +1,6 @@
/***
- P R O C E S S I N G . J S - 1.2.3
+ P R O C E S S I N G . J S - 1.3.6
a port of the Processing visualization language
Processing.js is licensed under the MIT License, see LICENSE.
@@ -11,692 +11,385 @@
***/
(function(window, document, Math, undef) {
-
- var nop = function(){};
-
- var debug = (function() {
- if ("console" in window) {
- return function(msg) {
- window.console.log('Processing.js: ' + msg);
- };
- } else {
- return nop();
- }
- }());
-
+ var nop = function() {};
+ var debug = function() {
+ if ("console" in window) return function(msg) {
+ window.console.log("Processing.js: " + msg)
+ };
+ return nop()
+ }();
var ajax = function(url) {
- var xhr = new XMLHttpRequest();
+ var xhr = new XMLHttpRequest;
xhr.open("GET", url, false);
- if (xhr.overrideMimeType) {
- xhr.overrideMimeType("text/plain");
- }
+ if (xhr.overrideMimeType) xhr.overrideMimeType("text/plain");
xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT");
xhr.send(null);
- // failed request?
- if (xhr.status !== 200 && xhr.status !== 0) { throw ("XMLHttpRequest failed, status code " + xhr.status); }
- return xhr.responseText;
+ if (xhr.status !== 200 && xhr.status !== 0) throw "XMLHttpRequest failed, status code " + xhr.status;
+ return xhr.responseText
};
+ var isDOMPresent = "document" in this && !("fake" in this.document);
+ document.head = document.head || document.getElementsByTagName("head")[0];
- var isDOMPresent = ("document" in this) && !("fake" in this.document);
-
- // Typed Arrays: fallback to WebGL arrays or Native JS arrays if unavailable
function setupTypedArray(name, fallback) {
- // Check if TypedArray exists, and use if so.
- if (name in window) {
- return window[name];
- }
-
- // Check if WebGLArray exists
- if (typeof window[fallback] === "function") {
- return window[fallback];
- } else {
- // Use Native JS array
- return function(obj) {
- if (obj instanceof Array) {
- return obj;
- } else if (typeof obj === "number") {
- var arr = [];
- arr.length = obj;
- return arr;
- }
- };
+ if (name in window) return window[name];
+ if (typeof window[fallback] === "function") return window[fallback];
+ return function(obj) {
+ if (obj instanceof Array) return obj;
+ if (typeof obj === "number") {
+ var arr = [];
+ arr.length = obj;
+ return arr
+ }
}
}
-
var Float32Array = setupTypedArray("Float32Array", "WebGLFloatArray"),
- Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"),
- Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"),
- Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray");
-
- /* Browsers fixes end */
-
+ Int32Array = setupTypedArray("Int32Array", "WebGLIntArray"),
+ Uint16Array = setupTypedArray("Uint16Array", "WebGLUnsignedShortArray"),
+ Uint8Array = setupTypedArray("Uint8Array", "WebGLUnsignedByteArray");
var PConstants = {
X: 0,
Y: 1,
Z: 2,
-
R: 3,
G: 4,
B: 5,
A: 6,
-
U: 7,
V: 8,
-
NX: 9,
NY: 10,
NZ: 11,
-
EDGE: 12,
-
- // Stroke
SR: 13,
SG: 14,
SB: 15,
SA: 16,
-
SW: 17,
-
- // Transformations (2D and 3D)
TX: 18,
TY: 19,
TZ: 20,
-
VX: 21,
VY: 22,
VZ: 23,
VW: 24,
-
- // Material properties
AR: 25,
AG: 26,
AB: 27,
-
DR: 3,
DG: 4,
DB: 5,
DA: 6,
-
SPR: 28,
SPG: 29,
SPB: 30,
-
SHINE: 31,
-
ER: 32,
EG: 33,
EB: 34,
-
BEEN_LIT: 35,
-
VERTEX_FIELD_COUNT: 36,
-
- // Renderers
- P2D: 1,
+ P2D: 1,
JAVA2D: 1,
- WEBGL: 2,
- P3D: 2,
+ WEBGL: 2,
+ P3D: 2,
OPENGL: 2,
- PDF: 0,
- DXF: 0,
-
- // Platform IDs
- OTHER: 0,
+ PDF: 0,
+ DXF: 0,
+ OTHER: 0,
WINDOWS: 1,
- MAXOSX: 2,
- LINUX: 3,
-
- EPSILON: 0.0001,
-
- MAX_FLOAT: 3.4028235e+38,
- MIN_FLOAT: -3.4028235e+38,
- MAX_INT: 2147483647,
- MIN_INT: -2147483648,
-
- PI: Math.PI,
- TWO_PI: 2 * Math.PI,
- HALF_PI: Math.PI / 2,
- THIRD_PI: Math.PI / 3,
+ MAXOSX: 2,
+ LINUX: 3,
+ EPSILON: 1.0E-4,
+ MAX_FLOAT: 3.4028235E38,
+ MIN_FLOAT: -3.4028235E38,
+ MAX_INT: 2147483647,
+ MIN_INT: -2147483648,
+ PI: Math.PI,
+ TWO_PI: 2 * Math.PI,
+ HALF_PI: Math.PI / 2,
+ THIRD_PI: Math.PI / 3,
QUARTER_PI: Math.PI / 4,
-
DEG_TO_RAD: Math.PI / 180,
RAD_TO_DEG: 180 / Math.PI,
-
- WHITESPACE: " \t\n\r\f\u00A0",
-
- // Color modes
- RGB: 1,
- ARGB: 2,
- HSB: 3,
+ WHITESPACE: " \t\n\r\u000c\u00a0",
+ RGB: 1,
+ ARGB: 2,
+ HSB: 3,
ALPHA: 4,
- CMYK: 5,
-
- // Image file types
- TIFF: 0,
+ CMYK: 5,
+ TIFF: 0,
TARGA: 1,
- JPEG: 2,
- GIF: 3,
-
- // Filter/convert types
- BLUR: 11,
- GRAY: 12,
- INVERT: 13,
- OPAQUE: 14,
+ JPEG: 2,
+ GIF: 3,
+ BLUR: 11,
+ GRAY: 12,
+ INVERT: 13,
+ OPAQUE: 14,
POSTERIZE: 15,
THRESHOLD: 16,
- ERODE: 17,
- DILATE: 18,
-
- // Blend modes
- REPLACE: 0,
- BLEND: 1 << 0,
- ADD: 1 << 1,
- SUBTRACT: 1 << 2,
- LIGHTEST: 1 << 3,
- DARKEST: 1 << 4,
+ ERODE: 17,
+ DILATE: 18,
+ REPLACE: 0,
+ BLEND: 1 << 0,
+ ADD: 1 << 1,
+ SUBTRACT: 1 << 2,
+ LIGHTEST: 1 << 3,
+ DARKEST: 1 << 4,
DIFFERENCE: 1 << 5,
- EXCLUSION: 1 << 6,
- MULTIPLY: 1 << 7,
- SCREEN: 1 << 8,
- OVERLAY: 1 << 9,
+ EXCLUSION: 1 << 6,
+ MULTIPLY: 1 << 7,
+ SCREEN: 1 << 8,
+ OVERLAY: 1 << 9,
HARD_LIGHT: 1 << 10,
SOFT_LIGHT: 1 << 11,
- DODGE: 1 << 12,
- BURN: 1 << 13,
-
- // Color component bit masks
- ALPHA_MASK: 0xff000000,
- RED_MASK: 0x00ff0000,
- GREEN_MASK: 0x0000ff00,
- BLUE_MASK: 0x000000ff,
-
- // Projection matrices
- CUSTOM: 0,
+ DODGE: 1 << 12,
+ BURN: 1 << 13,
+ ALPHA_MASK: 4278190080,
+ RED_MASK: 16711680,
+ GREEN_MASK: 65280,
+ BLUE_MASK: 255,
+ CUSTOM: 0,
ORTHOGRAPHIC: 2,
- PERSPECTIVE: 3,
-
- // Shapes
- POINT: 2,
- POINTS: 2,
- LINE: 4,
- LINES: 4,
- TRIANGLE: 8,
- TRIANGLES: 9,
+ PERSPECTIVE: 3,
+ POINT: 2,
+ POINTS: 2,
+ LINE: 4,
+ LINES: 4,
+ TRIANGLE: 8,
+ TRIANGLES: 9,
TRIANGLE_STRIP: 10,
- TRIANGLE_FAN: 11,
- QUAD: 16,
- QUADS: 16,
- QUAD_STRIP: 17,
- POLYGON: 20,
- PATH: 21,
- RECT: 30,
- ELLIPSE: 31,
- ARC: 32,
- SPHERE: 40,
- BOX: 41,
-
- GROUP: 0,
- PRIMITIVE: 1,
- //PATH: 21, // shared with Shape PATH
- GEOMETRY: 3,
-
- // Shape Vertex
- VERTEX: 0,
+ TRIANGLE_FAN: 11,
+ QUAD: 16,
+ QUADS: 16,
+ QUAD_STRIP: 17,
+ POLYGON: 20,
+ PATH: 21,
+ RECT: 30,
+ ELLIPSE: 31,
+ ARC: 32,
+ SPHERE: 40,
+ BOX: 41,
+ GROUP: 0,
+ PRIMITIVE: 1,
+ GEOMETRY: 3,
+ VERTEX: 0,
BEZIER_VERTEX: 1,
- CURVE_VERTEX: 2,
- BREAK: 3,
- CLOSESHAPE: 4,
-
- // Shape closing modes
- OPEN: 1,
+ CURVE_VERTEX: 2,
+ BREAK: 3,
+ CLOSESHAPE: 4,
+ OPEN: 1,
CLOSE: 2,
-
- // Shape drawing modes
- CORNER: 0, // Draw mode convention to use (x, y) to (width, height)
- CORNERS: 1, // Draw mode convention to use (x1, y1) to (x2, y2) coordinates
- RADIUS: 2, // Draw mode from the center, and using the radius
- CENTER_RADIUS: 2, // Deprecated! Use RADIUS instead
- CENTER: 3, // Draw from the center, using second pair of values as the diameter
- DIAMETER: 3, // Synonym for the CENTER constant. Draw from the center
- CENTER_DIAMETER: 3, // Deprecated! Use DIAMETER instead
-
- // Text vertical alignment modes
- BASELINE: 0, // Default vertical alignment for text placement
- TOP: 101, // Align text to the top
- BOTTOM: 102, // Align text from the bottom, using the baseline
-
- // UV Texture coordinate modes
- NORMAL: 1,
+ CORNER: 0,
+ CORNERS: 1,
+ RADIUS: 2,
+ CENTER_RADIUS: 2,
+ CENTER: 3,
+ DIAMETER: 3,
+ CENTER_DIAMETER: 3,
+ BASELINE: 0,
+ TOP: 101,
+ BOTTOM: 102,
+ NORMAL: 1,
NORMALIZED: 1,
- IMAGE: 2,
-
- // Text placement modes
+ IMAGE: 2,
MODEL: 4,
SHAPE: 5,
-
- // Stroke modes
- SQUARE: 'butt',
- ROUND: 'round',
- PROJECT: 'square',
- MITER: 'miter',
- BEVEL: 'bevel',
-
- // Lighting modes
- AMBIENT: 0,
+ SQUARE: "butt",
+ ROUND: "round",
+ PROJECT: "square",
+ MITER: "miter",
+ BEVEL: "bevel",
+ AMBIENT: 0,
DIRECTIONAL: 1,
- //POINT: 2, Shared with Shape constant
- SPOT: 3,
-
- // Key constants
-
- // Both key and keyCode will be equal to these values
+ SPOT: 3,
BACKSPACE: 8,
- TAB: 9,
- ENTER: 10,
- RETURN: 13,
- ESC: 27,
- DELETE: 127,
- CODED: 0xffff,
-
- // p.key will be CODED and p.keyCode will be this value
- SHIFT: 16,
- CONTROL: 17,
- ALT: 18,
- CAPSLK: 20,
- PGUP: 33,
- PGDN: 34,
- END: 35,
- HOME: 36,
- LEFT: 37,
- UP: 38,
- RIGHT: 39,
- DOWN: 40,
- F1: 112,
- F2: 113,
- F3: 114,
- F4: 115,
- F5: 116,
- F6: 117,
- F7: 118,
- F8: 119,
- F9: 120,
- F10: 121,
- F11: 122,
- F12: 123,
- NUMLK: 144,
- META: 157,
- INSERT: 155,
-
- // Cursor types
- ARROW: 'default',
- CROSS: 'crosshair',
- HAND: 'pointer',
- MOVE: 'move',
- TEXT: 'text',
- WAIT: 'wait',
+ TAB: 9,
+ ENTER: 10,
+ RETURN: 13,
+ ESC: 27,
+ DELETE: 127,
+ CODED: 65535,
+ SHIFT: 16,
+ CONTROL: 17,
+ ALT: 18,
+ CAPSLK: 20,
+ PGUP: 33,
+ PGDN: 34,
+ END: 35,
+ HOME: 36,
+ LEFT: 37,
+ UP: 38,
+ RIGHT: 39,
+ DOWN: 40,
+ F1: 112,
+ F2: 113,
+ F3: 114,
+ F4: 115,
+ F5: 116,
+ F6: 117,
+ F7: 118,
+ F8: 119,
+ F9: 120,
+ F10: 121,
+ F11: 122,
+ F12: 123,
+ NUMLK: 144,
+ META: 157,
+ INSERT: 155,
+ ARROW: "default",
+ CROSS: "crosshair",
+ HAND: "pointer",
+ MOVE: "move",
+ TEXT: "text",
+ WAIT: "wait",
NOCURSOR: "url('data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='), auto",
-
- // Hints
- DISABLE_OPENGL_2X_SMOOTH: 1,
- ENABLE_OPENGL_2X_SMOOTH: -1,
- ENABLE_OPENGL_4X_SMOOTH: 2,
- ENABLE_NATIVE_FONTS: 3,
- DISABLE_DEPTH_TEST: 4,
- ENABLE_DEPTH_TEST: -4,
- ENABLE_DEPTH_SORT: 5,
- DISABLE_DEPTH_SORT: -5,
- DISABLE_OPENGL_ERROR_REPORT: 6,
- ENABLE_OPENGL_ERROR_REPORT: -6,
- ENABLE_ACCURATE_TEXTURES: 7,
- DISABLE_ACCURATE_TEXTURES: -7,
- HINT_COUNT: 10,
-
- // PJS defined constants
- SINCOS_LENGTH: parseInt(360 / 0.5, 10),
- PRECISIONB: 15, // fixed point precision is limited to 15 bits!!
- PRECISIONF: 1 << 15,
- PREC_MAXVAL: (1 << 15) - 1,
- PREC_ALPHA_SHIFT: 24 - 15,
- PREC_RED_SHIFT: 16 - 15,
- NORMAL_MODE_AUTO: 0,
- NORMAL_MODE_SHAPE: 1,
+ DISABLE_OPENGL_2X_SMOOTH: 1,
+ ENABLE_OPENGL_2X_SMOOTH: -1,
+ ENABLE_OPENGL_4X_SMOOTH: 2,
+ ENABLE_NATIVE_FONTS: 3,
+ DISABLE_DEPTH_TEST: 4,
+ ENABLE_DEPTH_TEST: -4,
+ ENABLE_DEPTH_SORT: 5,
+ DISABLE_DEPTH_SORT: -5,
+ DISABLE_OPENGL_ERROR_REPORT: 6,
+ ENABLE_OPENGL_ERROR_REPORT: -6,
+ ENABLE_ACCURATE_TEXTURES: 7,
+ DISABLE_ACCURATE_TEXTURES: -7,
+ HINT_COUNT: 10,
+ SINCOS_LENGTH: 720,
+ PRECISIONB: 15,
+ PRECISIONF: 1 << 15,
+ PREC_MAXVAL: (1 << 15) - 1,
+ PREC_ALPHA_SHIFT: 24 - 15,
+ PREC_RED_SHIFT: 16 - 15,
+ NORMAL_MODE_AUTO: 0,
+ NORMAL_MODE_SHAPE: 1,
NORMAL_MODE_VERTEX: 2,
- MAX_LIGHTS: 8
+ MAX_LIGHTS: 8
};
- /**
- * Returns Java hashCode() result for the object. If the object has the "hashCode" function,
- * it preforms the call of this function. Otherwise it uses/creates the "$id" property,
- * which is used as the hashCode.
- *
- * @param {Object} obj The object.
- * @returns {int} The object's hash code.
- */
function virtHashCode(obj) {
- if (obj.constructor === String) {
+ if (typeof obj === "string") {
var hash = 0;
- for (var i = 0; i < obj.length; ++i) {
- hash = (hash * 31 + obj.charCodeAt(i)) & 0xFFFFFFFF;
- }
- return hash;
- } else if (typeof(obj) !== "object") {
- return obj & 0xFFFFFFFF;
- } else if (obj.hashCode instanceof Function) {
- return obj.hashCode();
- } else {
- if (obj.$id === undef) {
- obj.$id = ((Math.floor(Math.random() * 0x10000) - 0x8000) << 16) | Math.floor(Math.random() * 0x10000);
- }
- return obj.$id;
+ for (var i = 0; i < obj.length; ++i) hash = hash * 31 + obj.charCodeAt(i) & 4294967295;
+ return hash
}
+ if (typeof obj !== "object") return obj & 4294967295;
+ if (obj.hashCode instanceof Function) return obj.hashCode();
+ if (obj.$id === undef) obj.$id = Math.floor(Math.random() * 65536) - 32768 << 16 | Math.floor(Math.random() * 65536);
+ return obj.$id
}
-
- /**
- * Returns Java equals() result for two objects. If the first object
- * has the "equals" function, it preforms the call of this function.
- * Otherwise the method uses the JavaScript === operator.
- *
- * @param {Object} obj The first object.
- * @param {Object} other The second object.
- *
- * @returns {boolean} true if the objects are equal.
- */
function virtEquals(obj, other) {
- if (obj === null || other === null) {
- return (obj === null) && (other === null);
- } else if (obj.constructor === String) {
- return obj === other;
- } else if (typeof(obj) !== "object") {
- return obj === other;
- } else if (obj.equals instanceof Function) {
- return obj.equals(other);
- } else {
- return obj === other;
- }
+ if (obj === null || other === null) return obj === null && other === null;
+ if (typeof obj === "string") return obj === other;
+ if (typeof obj !== "object") return obj === other;
+ if (obj.equals instanceof Function) return obj.equals(other);
+ return obj === other
}
-
- /**
- * A ObjectIterator is an iterator wrapper for objects. If passed object contains
- * the iterator method, the object instance will be replaced by the result returned by
- * this method call. If passed object is an array, the ObjectIterator instance iterates
- * through its items.
- *
- * @param {Object} obj The object to be iterated.
- */
var ObjectIterator = function(obj) {
- if (obj.iterator instanceof Function) {
- return obj.iterator();
- } else if (obj instanceof Array) {
- // iterate through array items
+ if (obj.iterator instanceof Function) return obj.iterator();
+ if (obj instanceof Array) {
var index = -1;
this.hasNext = function() {
- return ++index < obj.length;
+ return ++index < obj.length
};
this.next = function() {
- return obj[index];
- };
- } else {
- throw "Unable to iterate: " + obj;
- }
+ return obj[index]
+ }
+ } else throw "Unable to iterate: " + obj;
};
-
- /**
- * An ArrayList stores a variable number of objects.
- *
- * @param {int} initialCapacity optional defines the initial capacity of the list, it's empty by default
- *
- * @returns {ArrayList} new ArrayList object
- */
- var ArrayList = (function() {
+ var ArrayList = function() {
function Iterator(array) {
var index = 0;
this.hasNext = function() {
- return index < array.length;
+ return index < array.length
};
-
this.next = function() {
- return array[index++];
+ return array[index++]
};
-
this.remove = function() {
- array.splice(index, 1);
- };
+ array.splice(index, 1)
+ }
}
-
function ArrayList() {
var array;
- if (arguments.length === 0) {
+ if (arguments.length === 0) array = [];
+ else if (arguments.length > 0 && typeof arguments[0] !== "number") array = arguments[0].toArray();
+ else {
array = [];
- } else if (arguments.length > 0 && typeof arguments[0] !== 'number') {
- array = arguments[0].toArray();
- } else {
- array = [];
- array.length = 0 | arguments[0];
+ array.length = 0 | arguments[0]
}
-
- /**
- * @member ArrayList
- * ArrayList.get() Returns the element at the specified position in this list.
- *
- * @param {int} i index of element to return
- *
- * @returns {Object} the element at the specified position in this list.
- */
this.get = function(i) {
- return array[i];
+ return array[i]
};
- /**
- * @member ArrayList
- * ArrayList.contains() Returns true if this list contains the specified element.
- *
- * @param {Object} item element whose presence in this List is to be tested.
- *
- * @returns {boolean} true if the specified element is present; false otherwise.
- */
this.contains = function(item) {
- return this.indexOf(item)>-1;
+ return this.indexOf(item) > -1
};
- /**
- * @member ArrayList
- * ArrayList.indexOf() Returns the position this element takes in the list, or -1 if the element is not found.
- *
- * @param {Object} item element whose position in this List is to be tested.
- *
- * @returns {int} the list position that the first match for this element holds in the list, or -1 if it is not in the list.
- */
this.indexOf = function(item) {
- for (var i = 0, len = array.length; i < len; ++i) {
- if (virtEquals(item, array[i])) {
- return i;
- }
- }
- return -1;
+ for (var i = 0, len = array.length; i < len; ++i) if (virtEquals(item, array[i])) return i;
+ return -1
};
- /**
- * @member ArrayList
- * ArrayList.add() Adds the specified element to this list.
- *
- * @param {int} index optional index at which the specified element is to be inserted
- * @param {Object} object element to be added to the list
- */
this.add = function() {
- if (arguments.length === 1) {
- array.push(arguments[0]); // for add(Object)
- } else if (arguments.length === 2) {
+ if (arguments.length === 1) array.push(arguments[0]);
+ else if (arguments.length === 2) {
var arg0 = arguments[0];
- if (typeof arg0 === 'number') {
- if (arg0 >= 0 && arg0 <= array.length) {
- array.splice(arg0, 0, arguments[1]); // for add(i, Object)
- } else {
- throw(arg0 + " is not a valid index");
- }
- } else {
- throw(typeof arg0 + " is not a number");
- }
- } else {
- throw("Please use the proper number of parameters.");
- }
+ if (typeof arg0 === "number") if (arg0 >= 0 && arg0 <= array.length) array.splice(arg0, 0, arguments[1]);
+ else throw arg0 + " is not a valid index";
+ else throw typeof arg0 + " is not a number";
+ } else throw "Please use the proper number of parameters.";
};
- /**
- * @member ArrayList
- * ArrayList.addAll(collection) appends all of the elements in the specified
- * Collection to the end of this list, in the order that they are returned by
- * the specified Collection's Iterator.
- *
- * When called as addAll(index, collection) the elements are inserted into
- * this list at the position indicated by index.
- *
- * @param {index} Optional; specifies the position the colletion should be inserted at
- * @param {collection} Any iterable object (ArrayList, HashMap.keySet(), etc.)
- * @throws out of bounds error for negative index, or index greater than list size.
- */
this.addAll = function(arg1, arg2) {
- // addAll(int, Collection)
var it;
if (typeof arg1 === "number") {
- if (arg1 < 0 || arg1 > array.length) {
- throw("Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length);
- }
+ if (arg1 < 0 || arg1 > array.length) throw "Index out of bounds for addAll: " + arg1 + " greater or equal than " + array.length;
it = new ObjectIterator(arg2);
- while (it.hasNext()) {
- array.splice(arg1++, 0, it.next());
- }
- }
- // addAll(Collection)
- else {
+ while (it.hasNext()) array.splice(arg1++, 0, it.next())
+ } else {
it = new ObjectIterator(arg1);
- while (it.hasNext()) {
- array.push(it.next());
- }
+ while (it.hasNext()) array.push(it.next())
}
};
- /**
- * @member ArrayList
- * ArrayList.set() Replaces the element at the specified position in this list with the specified element.
- *
- * @param {int} index index of element to replace
- * @param {Object} object element to be stored at the specified position
- */
this.set = function() {
if (arguments.length === 2) {
var arg0 = arguments[0];
- if (typeof arg0 === 'number') {
- if (arg0 >= 0 && arg0 < array.length) {
- array.splice(arg0, 1, arguments[1]);
- } else {
- throw(arg0 + " is not a valid index.");
- }
- } else {
- throw(typeof arg0 + " is not a number");
- }
- } else {
- throw("Please use the proper number of parameters.");
- }
+ if (typeof arg0 === "number") if (arg0 >= 0 && arg0 < array.length) array.splice(arg0, 1, arguments[1]);
+ else throw arg0 + " is not a valid index.";
+ else throw typeof arg0 + " is not a number";
+ } else throw "Please use the proper number of parameters.";
};
-
- /**
- * @member ArrayList
- * ArrayList.size() Returns the number of elements in this list.
- *
- * @returns {int} the number of elements in this list
- */
this.size = function() {
- return array.length;
+ return array.length
};
-
- /**
- * @member ArrayList
- * ArrayList.clear() Removes all of the elements from this list. The list will be empty after this call returns.
- */
this.clear = function() {
- array.length = 0;
+ array.length = 0
};
-
- /**
- * @member ArrayList
- * ArrayList.remove() Removes an element either based on index, if the argument is a number, or
- * by equality check, if the argument is an object.
- *
- * @param {int|Object} item either the index of the element to be removed, or the element itself.
- *
- * @returns {Object|boolean} If removal is by index, the element that was removed, or null if nothing was removed. If removal is by object, true if removal occurred, otherwise false.
- */
this.remove = function(item) {
- if (typeof item === 'number') {
- return array.splice(item, 1)[0];
- } else {
- item = this.indexOf(item);
- if (item > -1) {
- array.splice(item, 1);
- return true;
- }
- return false;
+ if (typeof item === "number") return array.splice(item, 1)[0];
+ item = this.indexOf(item);
+ if (item > -1) {
+ array.splice(item, 1);
+ return true
}
+ return false
};
-
- /**
- * @member ArrayList
- * ArrayList.isEmpty() Tests if this list has no elements.
- *
- * @returns {boolean} true if this list has no elements; false otherwise
- */
this.isEmpty = function() {
- return !array.length;
+ return !array.length
};
-
- /**
- * @member ArrayList
- * ArrayList.clone() Returns a shallow copy of this ArrayList instance. (The elements themselves are not copied.)
- *
- * @returns {ArrayList} a clone of this ArrayList instance
- */
this.clone = function() {
- return new ArrayList(this);
+ return new ArrayList(this)
};
-
- /**
- * @member ArrayList
- * ArrayList.toArray() Returns an array containing all of the elements in this list in the correct order.
- *
- * @returns {Object[]} Returns an array containing all of the elements in this list in the correct order
- */
this.toArray = function() {
- return array.slice(0);
+ return array.slice(0)
};
-
this.iterator = function() {
- return new Iterator(array);
- };
- }
-
- return ArrayList;
- }());
-
- /**
- * A HashMap stores a collection of objects, each referenced by a key. This is similar to an Array, only
- * instead of accessing elements with a numeric index, a String is used. (If you are familiar with
- * associative arrays from other languages, this is the same idea.)
- *
- * @param {int} initialCapacity defines the initial capacity of the map, it's 16 by default
- * @param {float} loadFactor the load factor for the map, the default is 0.75
- * @param {Map} m gives the new HashMap the same mappings as this Map
- */
- var HashMap = (function() {
- /**
- * @member HashMap
- * A HashMap stores a collection of objects, each referenced by a key. This is similar to an Array, only
- * instead of accessing elements with a numeric index, a String is used. (If you are familiar with
- * associative arrays from other languages, this is the same idea.)
- *
- * @param {int} initialCapacity defines the initial capacity of the map, it's 16 by default
- * @param {float} loadFactor the load factor for the map, the default is 0.75
- * @param {Map} m gives the new HashMap the same mappings as this Map
- */
- function HashMap() {
- if (arguments.length === 1 && arguments[0].constructor === HashMap) {
- return arguments[0].clone();
+ return new Iterator(array)
}
-
+ }
+ return ArrayList
+ }();
+ var HashMap = function() {
+ function HashMap() {
+ if (arguments.length === 1 && arguments[0] instanceof HashMap) return arguments[0].clone();
var initialCapacity = arguments.length > 0 ? arguments[0] : 16;
var loadFactor = arguments.length > 1 ? arguments[1] : 0.75;
var buckets = [];
@@ -706,31 +399,22 @@
function getBucketIndex(key) {
var index = virtHashCode(key) % buckets.length;
- return index < 0 ? buckets.length + index : index;
+ return index < 0 ? buckets.length + index : index
}
function ensureLoad() {
- if (count <= loadFactor * buckets.length) {
- return;
- }
+ if (count <= loadFactor * buckets.length) return;
var allEntries = [];
- for (var i = 0; i < buckets.length; ++i) {
- if (buckets[i] !== undef) {
- allEntries = allEntries.concat(buckets[i]);
- }
- }
+ for (var i = 0; i < buckets.length; ++i) if (buckets[i] !== undef) allEntries = allEntries.concat(buckets[i]);
var newBucketsLength = buckets.length * 2;
buckets = [];
buckets.length = newBucketsLength;
for (var j = 0; j < allEntries.length; ++j) {
var index = getBucketIndex(allEntries[j].key);
var bucket = buckets[index];
- if (bucket === undef) {
- buckets[index] = bucket = [];
- }
- bucket.push(allEntries[j]);
+ if (bucket === undef) buckets[index] = bucket = [];
+ bucket.push(allEntries[j])
}
}
-
function Iterator(conversion, removeItem) {
var bucketIndex = 0;
var itemIndex = -1;
@@ -739,82 +423,52 @@
function findNext() {
while (!endOfBuckets) {
++itemIndex;
- if (bucketIndex >= buckets.length) {
- endOfBuckets = true;
- } else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) {
+ if (bucketIndex >= buckets.length) endOfBuckets = true;
+ else if (buckets[bucketIndex] === undef || itemIndex >= buckets[bucketIndex].length) {
itemIndex = -1;
- ++bucketIndex;
- } else {
- return;
- }
+ ++bucketIndex
+ } else return
}
}
-
- /*
- * @member Iterator
- * Checks if the Iterator has more items
- */
this.hasNext = function() {
- return !endOfBuckets;
+ return !endOfBuckets
};
-
- /*
- * @member Iterator
- * Return the next Item
- */
this.next = function() {
var result = conversion(buckets[bucketIndex][itemIndex]);
findNext();
- return result;
+ return result
};
-
- /*
- * @member Iterator
- * Remove the current item
- */
this.remove = function() {
removeItem(this.next());
- --itemIndex;
+ --itemIndex
};
-
- findNext();
+ findNext()
}
-
function Set(conversion, isIn, removeItem) {
this.clear = function() {
- hashMap.clear();
+ hashMap.clear()
};
-
this.contains = function(o) {
- return isIn(o);
+ return isIn(o)
};
-
this.containsAll = function(o) {
var it = o.iterator();
- while (it.hasNext()) {
- if (!this.contains(it.next())) {
- return false;
- }
- }
- return true;
+ while (it.hasNext()) if (!this.contains(it.next())) return false;
+ return true
};
-
this.isEmpty = function() {
- return hashMap.isEmpty();
+ return hashMap.isEmpty()
};
-
this.iterator = function() {
- return new Iterator(conversion, removeItem);
+ return new Iterator(conversion, removeItem)
};
-
this.remove = function(o) {
if (this.contains(o)) {
removeItem(o);
- return true;
+ return true
}
- return false;
+ return false
};
-
this.removeAll = function(c) {
var it = c.iterator();
var changed = false;
@@ -822,160 +476,132 @@
var item = it.next();
if (this.contains(item)) {
removeItem(item);
- changed = true;
+ changed = true
}
}
- return true;
+ return true
};
-
this.retainAll = function(c) {
var it = this.iterator();
var toRemove = [];
while (it.hasNext()) {
var entry = it.next();
- if (!c.contains(entry)) {
- toRemove.push(entry);
- }
+ if (!c.contains(entry)) toRemove.push(entry)
}
- for (var i = 0; i < toRemove.length; ++i) {
- removeItem(toRemove[i]);
- }
- return toRemove.length > 0;
+ for (var i = 0; i < toRemove.length; ++i) removeItem(toRemove[i]);
+ return toRemove.length > 0
};
-
this.size = function() {
- return hashMap.size();
+ return hashMap.size()
};
-
this.toArray = function() {
var result = [];
var it = this.iterator();
- while (it.hasNext()) {
- result.push(it.next());
- }
- return result;
- };
+ while (it.hasNext()) result.push(it.next());
+ return result
+ }
}
-
function Entry(pair) {
this._isIn = function(map) {
- return map === hashMap && (pair.removed === undef);
+ return map === hashMap && pair.removed === undef
};
-
this.equals = function(o) {
- return virtEquals(pair.key, o.getKey());
+ return virtEquals(pair.key, o.getKey())
};
-
this.getKey = function() {
- return pair.key;
+ return pair.key
};
-
this.getValue = function() {
- return pair.value;
+ return pair.value
};
-
this.hashCode = function(o) {
- return virtHashCode(pair.key);
+ return virtHashCode(pair.key)
};
-
this.setValue = function(value) {
var old = pair.value;
pair.value = value;
- return old;
- };
+ return old
+ }
}
-
this.clear = function() {
count = 0;
buckets = [];
- buckets.length = initialCapacity;
+ buckets.length = initialCapacity
};
-
this.clone = function() {
- var map = new HashMap();
+ var map = new HashMap;
map.putAll(this);
- return map;
+ return map
};
-
this.containsKey = function(key) {
var index = getBucketIndex(key);
var bucket = buckets[index];
- if (bucket === undef) {
- return false;
- }
- for (var i = 0; i < bucket.length; ++i) {
- if (virtEquals(bucket[i].key, key)) {
- return true;
- }
- }
- return false;
+ if (bucket === undef) return false;
+ for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return true;
+ return false
};
-
this.containsValue = function(value) {
for (var i = 0; i < buckets.length; ++i) {
var bucket = buckets[i];
- if (bucket === undef) {
- continue;
- }
- for (var j = 0; j < bucket.length; ++j) {
- if (virtEquals(bucket[j].value, value)) {
- return true;
- }
- }
+ if (bucket === undef) continue;
+ for (var j = 0; j < bucket.length; ++j) if (virtEquals(bucket[j].value, value)) return true
}
- return false;
+ return false
};
-
this.entrySet = function() {
- return new Set(
-
- function(pair) {
- return new Entry(pair);
+ return new Set(function(pair) {
+ return new Entry(pair)
},
- function(pair) {
- return pair.constructor === Entry && pair._isIn(hashMap);
- },
function(pair) {
- return hashMap.remove(pair.getKey());
- });
+ return pair instanceof Entry && pair._isIn(hashMap)
+ },
+
+
+ function(pair) {
+ return hashMap.remove(pair.getKey())
+ })
};
-
this.get = function(key) {
var index = getBucketIndex(key);
var bucket = buckets[index];
- if (bucket === undef) {
- return null;
- }
- for (var i = 0; i < bucket.length; ++i) {
- if (virtEquals(bucket[i].key, key)) {
- return bucket[i].value;
- }
- }
- return null;
+ if (bucket === undef) return null;
+ for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) return bucket[i].value;
+ return null
};
-
this.isEmpty = function() {
- return count === 0;
+ return count === 0
};
-
this.keySet = function() {
- return new Set(
-
- function(pair) {
- return pair.key;
+ return new Set(function(pair) {
+ return pair.key
},
- function(key) {
- return hashMap.containsKey(key);
- },
function(key) {
- return hashMap.remove(key);
- });
+ return hashMap.containsKey(key)
+ },
+
+
+ function(key) {
+ return hashMap.remove(key)
+ })
};
+ this.values = function() {
+ return new Set(function(pair) {
+ return pair.value
+ },
+
+ function(value) {
+ return hashMap.containsValue(value)
+ },
+
+ function(value) {
+ return hashMap.removeByValue(value)
+ })
+ };
this.put = function(key, value) {
var index = getBucketIndex(key);
var bucket = buckets[index];
@@ -986,243 +612,199 @@
value: value
}];
ensureLoad();
- return null;
+ return null
}
- for (var i = 0; i < bucket.length; ++i) {
- if (virtEquals(bucket[i].key, key)) {
- var previous = bucket[i].value;
- bucket[i].value = value;
- return previous;
- }
- }
- ++count;
+ for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) {
+ var previous = bucket[i].value;
+ bucket[i].value = value;
+ return previous
+ }++count;
bucket.push({
key: key,
value: value
});
ensureLoad();
- return null;
+ return null
};
-
this.putAll = function(m) {
var it = m.entrySet().iterator();
while (it.hasNext()) {
var entry = it.next();
- this.put(entry.getKey(), entry.getValue());
+ this.put(entry.getKey(), entry.getValue())
}
};
-
this.remove = function(key) {
var index = getBucketIndex(key);
var bucket = buckets[index];
- if (bucket === undef) {
- return null;
+ if (bucket === undef) return null;
+ for (var i = 0; i < bucket.length; ++i) if (virtEquals(bucket[i].key, key)) {
+ --count;
+ var previous = bucket[i].value;
+ bucket[i].removed = true;
+ if (bucket.length > 1) bucket.splice(i, 1);
+ else buckets[index] = undef;
+ return previous
}
- for (var i = 0; i < bucket.length; ++i) {
- if (virtEquals(bucket[i].key, key)) {
- --count;
- var previous = bucket[i].value;
- bucket[i].removed = true;
- if (bucket.length > 1) {
- bucket.splice(i, 1);
- } else {
- buckets[index] = undef;
- }
- return previous;
+ return null
+ };
+ this.removeByValue = function(value) {
+ var bucket, i, ilen, pair;
+ for (bucket in buckets) if (buckets.hasOwnProperty(bucket)) for (i = 0, ilen = buckets[bucket].length; i < ilen; i++) {
+ pair = buckets[bucket][i];
+ if (pair.value === value) {
+ buckets[bucket].splice(i, 1);
+ return true
}
}
- return null;
+ return false
};
-
this.size = function() {
- return count;
- };
-
- this.values = function() {
- var result = [];
- var it = this.entrySet().iterator();
- while (it.hasNext()) {
- var entry = it.next();
- result.push(entry.getValue());
- }
- return result;
- };
+ return count
+ }
}
-
- return HashMap;
- }());
-
- var PVector = (function() {
+ return HashMap
+ }();
+ var PVector = function() {
function PVector(x, y, z) {
this.x = x || 0;
this.y = y || 0;
- this.z = z || 0;
+ this.z = z || 0
}
+ PVector.dist = function(v1, v2) {
+ return v1.dist(v2)
+ };
+ PVector.dot = function(v1, v2) {
+ return v1.dot(v2)
+ };
+ PVector.cross = function(v1, v2) {
+ return v1.cross(v2)
+ };
+ PVector.angleBetween = function(v1, v2) {
+ return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag()))
+ };
+ PVector.prototype = {
+ set: function(v, y, z) {
+ if (arguments.length === 1) this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0);
+ else {
+ this.x = v;
+ this.y = y;
+ this.z = z
+ }
+ },
+ get: function() {
+ return new PVector(this.x, this.y, this.z)
+ },
+ mag: function() {
+ var x = this.x,
+ y = this.y,
+ z = this.z;
+ return Math.sqrt(x * x + y * y + z * z)
+ },
+ add: function(v, y, z) {
+ if (arguments.length === 1) {
+ this.x += v.x;
+ this.y += v.y;
+ this.z += v.z
+ } else {
+ this.x += v;
+ this.y += y;
+ this.z += z
+ }
+ },
+ sub: function(v, y, z) {
+ if (arguments.length === 1) {
+ this.x -= v.x;
+ this.y -= v.y;
+ this.z -= v.z
+ } else {
+ this.x -= v;
+ this.y -= y;
+ this.z -= z
+ }
+ },
+ mult: function(v) {
+ if (typeof v === "number") {
+ this.x *= v;
+ this.y *= v;
+ this.z *= v
+ } else {
+ this.x *= v.x;
+ this.y *= v.y;
+ this.z *= v.z
+ }
+ },
+ div: function(v) {
+ if (typeof v === "number") {
+ this.x /= v;
+ this.y /= v;
+ this.z /= v
+ } else {
+ this.x /= v.x;
+ this.y /= v.y;
+ this.z /= v.z
+ }
+ },
+ dist: function(v) {
+ var dx = this.x - v.x,
+ dy = this.y - v.y,
+ dz = this.z - v.z;
+ return Math.sqrt(dx * dx + dy * dy + dz * dz)
+ },
+ dot: function(v, y, z) {
+ if (arguments.length === 1) return this.x * v.x + this.y * v.y + this.z * v.z;
+ return this.x * v + this.y * y + this.z * z
+ },
+ cross: function(v) {
+ var x = this.x,
+ y = this.y,
+ z = this.z;
+ return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y)
+ },
+ normalize: function() {
+ var m = this.mag();
+ if (m > 0) this.div(m)
+ },
+ limit: function(high) {
+ if (this.mag() > high) {
+ this.normalize();
+ this.mult(high)
+ }
+ },
+ heading2D: function() {
+ return -Math.atan2(-this.y, this.x)
+ },
+ toString: function() {
+ return "[" + this.x + ", " + this.y + ", " + this.z + "]"
+ },
+ array: function() {
+ return [this.x, this.y, this.z]
+ }
+ };
function createPVectorMethod(method) {
return function(v1, v2) {
var v = v1.get();
v[method](v2);
- return v;
- };
- }
-
- function createSimplePVectorMethod(method) {
- return function(v1, v2) {
- return v1[method](v2);
- };
- }
-
- var simplePVMethods = "dist dot cross".split(" ");
- var method = simplePVMethods.length;
-
- PVector.angleBetween = function(v1, v2) {
- return Math.acos(v1.dot(v2) / (v1.mag() * v2.mag()));
- };
-
- // Common vector operations for PVector
- PVector.prototype = {
- set: function(v, y, z) {
- if (arguments.length === 1) {
- this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0);
- } else {
- this.x = v;
- this.y = y;
- this.z = z;
- }
- },
- get: function() {
- return new PVector(this.x, this.y, this.z);
- },
- mag: function() {
- return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
- },
- add: function(v, y, z) {
- if (arguments.length === 3) {
- this.x += v;
- this.y += y;
- this.z += z;
- } else if (arguments.length === 1) {
- this.x += v.x;
- this.y += v.y;
- this.z += v.z;
- }
- },
- sub: function(v, y, z) {
- if (arguments.length === 3) {
- this.x -= v;
- this.y -= y;
- this.z -= z;
- } else if (arguments.length === 1) {
- this.x -= v.x;
- this.y -= v.y;
- this.z -= v.z;
- }
- },
- mult: function(v) {
- if (typeof v === 'number') {
- this.x *= v;
- this.y *= v;
- this.z *= v;
- } else if (typeof v === 'object') {
- this.x *= v.x;
- this.y *= v.y;
- this.z *= v.z;
- }
- },
- div: function(v) {
- if (typeof v === 'number') {
- this.x /= v;
- this.y /= v;
- this.z /= v;
- } else if (typeof v === 'object') {
- this.x /= v.x;
- this.y /= v.y;
- this.z /= v.z;
- }
- },
- dist: function(v) {
- var dx = this.x - v.x,
- dy = this.y - v.y,
- dz = this.z - v.z;
- return Math.sqrt(dx * dx + dy * dy + dz * dz);
- },
- dot: function(v, y, z) {
- if (arguments.length === 3) {
- return (this.x * v + this.y * y + this.z * z);
- } else if (arguments.length === 1) {
- return (this.x * v.x + this.y * v.y + this.z * v.z);
- }
- },
- cross: function(v) {
- return new PVector(this.y * v.z - v.y * this.z,
- this.z * v.x - v.z * this.x,
- this.x * v.y - v.x * this.y);
- },
- normalize: function() {
- var m = this.mag();
- if (m > 0) {
- this.div(m);
- }
- },
- limit: function(high) {
- if (this.mag() > high) {
- this.normalize();
- this.mult(high);
- }
- },
- heading2D: function() {
- return (-Math.atan2(-this.y, this.x));
- },
- toString: function() {
- return "[" + this.x + ", " + this.y + ", " + this.z + "]";
- },
- array: function() {
- return [this.x, this.y, this.z];
- }
- };
-
- while (method--) {
- PVector[simplePVMethods[method]] = createSimplePVectorMethod(simplePVMethods[method]);
- }
-
- for (method in PVector.prototype) {
- if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) {
- PVector[method] = createPVectorMethod(method);
+ return v
}
}
+ for (var method in PVector.prototype) if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) PVector[method] = createPVectorMethod(method);
+ return PVector
+ }();
- return PVector;
- }());
-
- // Building defaultScope. Changing of the prototype protects
- // internal Processing code from the changes in defaultScope
function DefaultScope() {}
DefaultScope.prototype = PConstants;
-
- var defaultScope = new DefaultScope();
- defaultScope.ArrayList = ArrayList;
- defaultScope.HashMap = HashMap;
- defaultScope.PVector = PVector;
+ var defaultScope = new DefaultScope;
+ defaultScope.ArrayList = ArrayList;
+ defaultScope.HashMap = HashMap;
+ defaultScope.PVector = PVector;
defaultScope.ObjectIterator = ObjectIterator;
- //defaultScope.PImage = PImage; // TODO
- //defaultScope.PShape = PShape; // TODO
- //defaultScope.PShapeSVG = PShapeSVG; // TODO
-
- ////////////////////////////////////////////////////////////////////////////
- // Class inheritance helper methods
- ////////////////////////////////////////////////////////////////////////////
-
+ defaultScope.PConstants = PConstants;
defaultScope.defineProperty = function(obj, name, desc) {
- if("defineProperty" in Object) {
- Object.defineProperty(obj, name, desc);
- } else {
- if (desc.hasOwnProperty("get")) {
- obj.__defineGetter__(name, desc.get);
- }
- if (desc.hasOwnProperty("set")) {
- obj.__defineSetter__(name, desc.set);
- }
+ if ("defineProperty" in Object) Object.defineProperty(obj, name, desc);
+ else {
+ if (desc.hasOwnProperty("get")) obj.__defineGetter__(name, desc.get);
+ if (desc.hasOwnProperty("set")) obj.__defineSetter__(name, desc.set)
}
};
@@ -1230,4345 +812,2150 @@
function extendGetterSetter(propertyName) {
defaultScope.defineProperty(subClass, propertyName, {
get: function() {
- return baseClass[propertyName];
+ return baseClass[propertyName]
},
set: function(v) {
- baseClass[propertyName]=v;
+ baseClass[propertyName] = v
},
enumerable: true
- });
+ })
}
-
var properties = [];
- for (var propertyName in baseClass) {
- if (typeof baseClass[propertyName] === 'function') {
- // Overriding all non-overriden functions
- if (!subClass.hasOwnProperty(propertyName)) {
- subClass[propertyName] = baseClass[propertyName];
- }
- } else if(propertyName.charAt(0) !== "$" && !(propertyName in subClass)) {
- // Delaying the properties extension due to the IE9 bug (see #918).
- properties.push(propertyName);
- }
- }
- while (properties.length > 0) {
- extendGetterSetter(properties.shift());
- }
+ for (var propertyName in baseClass) if (typeof baseClass[propertyName] === "function") {
+ if (!subClass.hasOwnProperty(propertyName)) subClass[propertyName] = baseClass[propertyName]
+ } else if (propertyName.charAt(0) !== "$" && !(propertyName in subClass)) properties.push(propertyName);
+ while (properties.length > 0) extendGetterSetter(properties.shift())
}
-
defaultScope.extendClassChain = function(base) {
var path = [base];
for (var self = base.$upcast; self; self = self.$upcast) {
extendClass(self, base);
path.push(self);
- base = self;
- }
- while (path.length > 0) {
- path.pop().$self=base;
+ base = self
}
+ while (path.length > 0) path.pop().$self = base
};
-
defaultScope.extendStaticMembers = function(derived, base) {
- extendClass(derived, base);
+ extendClass(derived, base)
};
-
defaultScope.extendInterfaceMembers = function(derived, base) {
- extendClass(derived, base);
+ extendClass(derived, base)
};
-
defaultScope.addMethod = function(object, name, fn, superAccessor) {
if (object[name]) {
var args = fn.length,
oldfn = object[name];
-
object[name] = function() {
- if (arguments.length === args) {
- return fn.apply(this, arguments);
- } else {
- return oldfn.apply(this, arguments);
- }
- };
- } else {
- object[name] = fn;
- }
+ if (arguments.length === args) return fn.apply(this, arguments);
+ return oldfn.apply(this, arguments)
+ }
+ } else object[name] = fn
};
-
defaultScope.createJavaArray = function(type, bounds) {
var result = null;
- if (typeof bounds[0] === 'number') {
+ if (typeof bounds[0] === "number") {
var itemsCount = 0 | bounds[0];
if (bounds.length <= 1) {
result = [];
result.length = itemsCount;
- for (var i = 0; i < itemsCount; ++i) {
- result[i] = 0;
- }
+ for (var i = 0; i < itemsCount; ++i) result[i] = 0
} else {
result = [];
var newBounds = bounds.slice(1);
- for (var j = 0; j < itemsCount; ++j) {
- result.push(defaultScope.createJavaArray(type, newBounds));
- }
+ for (var j = 0; j < itemsCount; ++j) result.push(defaultScope.createJavaArray(type, newBounds))
}
}
- return result;
+ return result
};
-
var colors = {
- aliceblue: "#f0f8ff",
- antiquewhite: "#faebd7",
- aqua: "#00ffff",
- aquamarine: "#7fffd4",
- azure: "#f0ffff",
- beige: "#f5f5dc",
- bisque: "#ffe4c4",
- black: "#000000",
- blanchedalmond: "#ffebcd",
- blue: "#0000ff",
- blueviolet: "#8a2be2",
- brown: "#a52a2a",
- burlywood: "#deb887",
- cadetblue: "#5f9ea0",
- chartreuse: "#7fff00",
- chocolate: "#d2691e",
- coral: "#ff7f50",
- cornflowerblue: "#6495ed",
- cornsilk: "#fff8dc",
- crimson: "#dc143c",
- cyan: "#00ffff",
- darkblue: "#00008b",
- darkcyan: "#008b8b",
- darkgoldenrod: "#b8860b",
- darkgray: "#a9a9a9",
- darkgreen: "#006400",
- darkkhaki: "#bdb76b",
- darkmagenta: "#8b008b",
- darkolivegreen: "#556b2f",
- darkorange: "#ff8c00",
- darkorchid: "#9932cc",
- darkred: "#8b0000",
- darksalmon: "#e9967a",
- darkseagreen: "#8fbc8f",
- darkslateblue: "#483d8b",
- darkslategray: "#2f4f4f",
- darkturquoise: "#00ced1",
- darkviolet: "#9400d3",
- deeppink: "#ff1493",
- deepskyblue: "#00bfff",
- dimgray: "#696969",
- dodgerblue: "#1e90ff",
- firebrick: "#b22222",
- floralwhite: "#fffaf0",
- forestgreen: "#228b22",
- fuchsia: "#ff00ff",
- gainsboro: "#dcdcdc",
- ghostwhite: "#f8f8ff",
- gold: "#ffd700",
- goldenrod: "#daa520",
- gray: "#808080",
- green: "#008000",
- greenyellow: "#adff2f",
- honeydew: "#f0fff0",
- hotpink: "#ff69b4",
- indianred: "#cd5c5c",
- indigo: "#4b0082",
- ivory: "#fffff0",
- khaki: "#f0e68c",
- lavender: "#e6e6fa",
- lavenderblush: "#fff0f5",
- lawngreen: "#7cfc00",
- lemonchiffon: "#fffacd",
- lightblue: "#add8e6",
- lightcoral: "#f08080",
- lightcyan: "#e0ffff",
+ aliceblue: "#f0f8ff",
+ antiquewhite: "#faebd7",
+ aqua: "#00ffff",
+ aquamarine: "#7fffd4",
+ azure: "#f0ffff",
+ beige: "#f5f5dc",
+ bisque: "#ffe4c4",
+ black: "#000000",
+ blanchedalmond: "#ffebcd",
+ blue: "#0000ff",
+ blueviolet: "#8a2be2",
+ brown: "#a52a2a",
+ burlywood: "#deb887",
+ cadetblue: "#5f9ea0",
+ chartreuse: "#7fff00",
+ chocolate: "#d2691e",
+ coral: "#ff7f50",
+ cornflowerblue: "#6495ed",
+ cornsilk: "#fff8dc",
+ crimson: "#dc143c",
+ cyan: "#00ffff",
+ darkblue: "#00008b",
+ darkcyan: "#008b8b",
+ darkgoldenrod: "#b8860b",
+ darkgray: "#a9a9a9",
+ darkgreen: "#006400",
+ darkkhaki: "#bdb76b",
+ darkmagenta: "#8b008b",
+ darkolivegreen: "#556b2f",
+ darkorange: "#ff8c00",
+ darkorchid: "#9932cc",
+ darkred: "#8b0000",
+ darksalmon: "#e9967a",
+ darkseagreen: "#8fbc8f",
+ darkslateblue: "#483d8b",
+ darkslategray: "#2f4f4f",
+ darkturquoise: "#00ced1",
+ darkviolet: "#9400d3",
+ deeppink: "#ff1493",
+ deepskyblue: "#00bfff",
+ dimgray: "#696969",
+ dodgerblue: "#1e90ff",
+ firebrick: "#b22222",
+ floralwhite: "#fffaf0",
+ forestgreen: "#228b22",
+ fuchsia: "#ff00ff",
+ gainsboro: "#dcdcdc",
+ ghostwhite: "#f8f8ff",
+ gold: "#ffd700",
+ goldenrod: "#daa520",
+ gray: "#808080",
+ green: "#008000",
+ greenyellow: "#adff2f",
+ honeydew: "#f0fff0",
+ hotpink: "#ff69b4",
+ indianred: "#cd5c5c",
+ indigo: "#4b0082",
+ ivory: "#fffff0",
+ khaki: "#f0e68c",
+ lavender: "#e6e6fa",
+ lavenderblush: "#fff0f5",
+ lawngreen: "#7cfc00",
+ lemonchiffon: "#fffacd",
+ lightblue: "#add8e6",
+ lightcoral: "#f08080",
+ lightcyan: "#e0ffff",
lightgoldenrodyellow: "#fafad2",
- lightgrey: "#d3d3d3",
- lightgreen: "#90ee90",
- lightpink: "#ffb6c1",
- lightsalmon: "#ffa07a",
- lightseagreen: "#20b2aa",
- lightskyblue: "#87cefa",
- lightslategray: "#778899",
- lightsteelblue: "#b0c4de",
- lightyellow: "#ffffe0",
- lime: "#00ff00",
- limegreen: "#32cd32",
- linen: "#faf0e6",
- magenta: "#ff00ff",
- maroon: "#800000",
- mediumaquamarine: "#66cdaa",
- mediumblue: "#0000cd",
- mediumorchid: "#ba55d3",
- mediumpurple: "#9370d8",
- mediumseagreen: "#3cb371",
- mediumslateblue: "#7b68ee",
- mediumspringgreen: "#00fa9a",
- mediumturquoise: "#48d1cc",
- mediumvioletred: "#c71585",
- midnightblue: "#191970",
- mintcream: "#f5fffa",
- mistyrose: "#ffe4e1",
- moccasin: "#ffe4b5",
- navajowhite: "#ffdead",
- navy: "#000080",
- oldlace: "#fdf5e6",
- olive: "#808000",
- olivedrab: "#6b8e23",
- orange: "#ffa500",
- orangered: "#ff4500",
- orchid: "#da70d6",
- palegoldenrod: "#eee8aa",
- palegreen: "#98fb98",
- paleturquoise: "#afeeee",
- palevioletred: "#d87093",
- papayawhip: "#ffefd5",
- peachpuff: "#ffdab9",
- peru: "#cd853f",
- pink: "#ffc0cb",
- plum: "#dda0dd",
- powderblue: "#b0e0e6",
- purple: "#800080",
- red: "#ff0000",
- rosybrown: "#bc8f8f",
- royalblue: "#4169e1",
- saddlebrown: "#8b4513",
- salmon: "#fa8072",
- sandybrown: "#f4a460",
- seagreen: "#2e8b57",
- seashell: "#fff5ee",
- sienna: "#a0522d",
- silver: "#c0c0c0",
- skyblue: "#87ceeb",
- slateblue: "#6a5acd",
- slategray: "#708090",
- snow: "#fffafa",
- springgreen: "#00ff7f",
- steelblue: "#4682b4",
- tan: "#d2b48c",
- teal: "#008080",
- thistle: "#d8bfd8",
- tomato: "#ff6347",
- turquoise: "#40e0d0",
- violet: "#ee82ee",
- wheat: "#f5deb3",
- white: "#ffffff",
- whitesmoke: "#f5f5f5",
- yellow: "#ffff00",
- yellowgreen: "#9acd32"
+ lightgrey: "#d3d3d3",
+ lightgreen: "#90ee90",
+ lightpink: "#ffb6c1",
+ lightsalmon: "#ffa07a",
+ lightseagreen: "#20b2aa",
+ lightskyblue: "#87cefa",
+ lightslategray: "#778899",
+ lightsteelblue: "#b0c4de",
+ lightyellow: "#ffffe0",
+ lime: "#00ff00",
+ limegreen: "#32cd32",
+ linen: "#faf0e6",
+ magenta: "#ff00ff",
+ maroon: "#800000",
+ mediumaquamarine: "#66cdaa",
+ mediumblue: "#0000cd",
+ mediumorchid: "#ba55d3",
+ mediumpurple: "#9370d8",
+ mediumseagreen: "#3cb371",
+ mediumslateblue: "#7b68ee",
+ mediumspringgreen: "#00fa9a",
+ mediumturquoise: "#48d1cc",
+ mediumvioletred: "#c71585",
+ midnightblue: "#191970",
+ mintcream: "#f5fffa",
+ mistyrose: "#ffe4e1",
+ moccasin: "#ffe4b5",
+ navajowhite: "#ffdead",
+ navy: "#000080",
+ oldlace: "#fdf5e6",
+ olive: "#808000",
+ olivedrab: "#6b8e23",
+ orange: "#ffa500",
+ orangered: "#ff4500",
+ orchid: "#da70d6",
+ palegoldenrod: "#eee8aa",
+ palegreen: "#98fb98",
+ paleturquoise: "#afeeee",
+ palevioletred: "#d87093",
+ papayawhip: "#ffefd5",
+ peachpuff: "#ffdab9",
+ peru: "#cd853f",
+ pink: "#ffc0cb",
+ plum: "#dda0dd",
+ powderblue: "#b0e0e6",
+ purple: "#800080",
+ red: "#ff0000",
+ rosybrown: "#bc8f8f",
+ royalblue: "#4169e1",
+ saddlebrown: "#8b4513",
+ salmon: "#fa8072",
+ sandybrown: "#f4a460",
+ seagreen: "#2e8b57",
+ seashell: "#fff5ee",
+ sienna: "#a0522d",
+ silver: "#c0c0c0",
+ skyblue: "#87ceeb",
+ slateblue: "#6a5acd",
+ slategray: "#708090",
+ snow: "#fffafa",
+ springgreen: "#00ff7f",
+ steelblue: "#4682b4",
+ tan: "#d2b48c",
+ teal: "#008080",
+ thistle: "#d8bfd8",
+ tomato: "#ff6347",
+ turquoise: "#40e0d0",
+ violet: "#ee82ee",
+ wheat: "#f5deb3",
+ white: "#ffffff",
+ whitesmoke: "#f5f5f5",
+ yellow: "#ffff00",
+ yellowgreen: "#9acd32"
};
+ (function(Processing) {
+ var unsupportedP5 = ("open() createOutput() createInput() BufferedReader selectFolder() " + "dataPath() createWriter() selectOutput() beginRecord() " + "saveStream() endRecord() selectInput() saveBytes() createReader() " + "beginRaw() endRaw() PrintWriter delay()").split(" "),
+ count = unsupportedP5.length,
+ prettyName, p5Name;
- // Manage multiple Processing instances
+ function createUnsupportedFunc(n) {
+ return function() {
+ throw "Processing.js does not support " + n + ".";
+ }
+ }
+ while (count--) {
+ prettyName = unsupportedP5[count];
+ p5Name = prettyName.replace("()", "");
+ Processing[p5Name] = createUnsupportedFunc(prettyName)
+ }
+ })(defaultScope);
+ defaultScope.defineProperty(defaultScope, "screenWidth", {
+ get: function() {
+ return window.innerWidth
+ }
+ });
+ defaultScope.defineProperty(defaultScope, "screenHeight", {
+ get: function() {
+ return window.innerHeight
+ }
+ });
var processingInstances = [];
var processingInstanceIds = {};
-
var removeInstance = function(id) {
processingInstances.splice(processingInstanceIds[id], 1);
- delete processingInstanceIds[id];
+ delete processingInstanceIds[id]
};
-
var addInstance = function(processing) {
- if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) {
- processing.externals.canvas.id = "__processing" + processingInstances.length;
- }
+ if (processing.externals.canvas.id === undef || !processing.externals.canvas.id.length) processing.externals.canvas.id = "__processing" + processingInstances.length;
processingInstanceIds[processing.externals.canvas.id] = processingInstances.length;
- processingInstances.push(processing);
+ processingInstances.push(processing)
};
-
- var Processing = this.Processing = function(curElement, aCode) {
- // Previously we allowed calling Processing as a func instead of ctor, but no longer.
- if (!(this instanceof Processing)) {
- throw("called Processing constructor as if it were a function: missing 'new'.");
+ function computeFontMetrics(pfont) {
+ var emQuad = 250,
+ correctionFactor = pfont.size / emQuad,
+ canvas = document.createElement("canvas");
+ canvas.width = 2 * emQuad;
+ canvas.height = 2 * emQuad;
+ canvas.style.opacity = 0;
+ var cfmFont = pfont.getCSSDefinition(emQuad + "px", "normal"),
+ ctx = canvas.getContext("2d");
+ ctx.font = cfmFont;
+ pfont.context2d = ctx;
+ var protrusions = "dbflkhyjqpg";
+ canvas.width = ctx.measureText(protrusions).width;
+ ctx.font = cfmFont;
+ var leadDiv = document.createElement("div");
+ leadDiv.style.position = "absolute";
+ leadDiv.style.opacity = 0;
+ leadDiv.style.fontFamily = '"' + pfont.name + '"';
+ leadDiv.style.fontSize = emQuad + "px";
+ leadDiv.innerHTML = protrusions + " " + protrusions;
+ document.body.appendChild(leadDiv);
+ var w = canvas.width,
+ h = canvas.height,
+ baseline = h / 2;
+ ctx.fillStyle = "white";
+ ctx.fillRect(0, 0, w, h);
+ ctx.fillStyle = "black";
+ ctx.fillText(protrusions, 0, baseline);
+ var pixelData = ctx.getImageData(0, 0, w, h).data;
+ var i = 0,
+ w4 = w * 4,
+ len = pixelData.length;
+ while (++i < len && pixelData[i] === 255) nop();
+ var ascent = Math.round(i / w4);
+ i = len - 1;
+ while (--i > 0 && pixelData[i] === 255) nop();
+ var descent = Math.round(i / w4);
+ pfont.ascent = correctionFactor * (baseline - ascent);
+ pfont.descent = correctionFactor * (descent - baseline);
+ if (document.defaultView.getComputedStyle) {
+ var leadDivHeight = document.defaultView.getComputedStyle(leadDiv, null).getPropertyValue("height");
+ leadDivHeight = correctionFactor * leadDivHeight.replace("px", "");
+ if (leadDivHeight >= pfont.size * 2) pfont.leading = Math.round(leadDivHeight / 2)
}
+ document.body.removeChild(leadDiv)
+ }
+ function PFont(name, size) {
+ if (name === undef) name = "";
+ this.name = name;
+ if (size === undef) size = 0;
+ this.size = size;
+ this.glyph = false;
+ this.ascent = 0;
+ this.descent = 0;
+ this.leading = 1.2 * size;
+ var illegalIndicator = name.indexOf(" Italic Bold");
+ if (illegalIndicator !== -1) name = name.substring(0, illegalIndicator);
+ this.style = "normal";
+ var italicsIndicator = name.indexOf(" Italic");
+ if (italicsIndicator !== -1) {
+ name = name.substring(0, italicsIndicator);
+ this.style = "italic"
+ }
+ this.weight = "normal";
+ var boldIndicator = name.indexOf(" Bold");
+ if (boldIndicator !== -1) {
+ name = name.substring(0, boldIndicator);
+ this.weight = "bold"
+ }
+ this.family = "sans-serif";
+ if (name !== undef) switch (name) {
+ case "sans-serif":
+ case "serif":
+ case "monospace":
+ case "fantasy":
+ case "cursive":
+ this.family = name;
+ break;
+ default:
+ this.family = '"' + name + '", sans-serif';
+ break
+ }
+ this.context2d = null;
+ computeFontMetrics(this);
+ this.css = this.getCSSDefinition();
+ this.context2d.font = this.css
+ }
+ PFont.prototype.getCSSDefinition = function(fontSize, lineHeight) {
+ if (fontSize === undef) fontSize = this.size + "px";
+ if (lineHeight === undef) lineHeight = this.leading + "px";
+ var components = [this.style, "normal", this.weight, fontSize + "/" + lineHeight, this.family];
+ return components.join(" ")
+ };
+ PFont.prototype.measureTextWidth = function(string) {
+ return this.context2d.measureText(string).width
+ };
+ PFont.PFontCache = {};
+ PFont.get = function(fontName, fontSize) {
+ var cache = PFont.PFontCache;
+ var idx = fontName + "/" + fontSize;
+ if (!cache[idx]) cache[idx] = new PFont(fontName, fontSize);
+ return cache[idx]
+ };
+ PFont.list = function() {
+ return ["sans-serif", "serif", "monospace", "fantasy", "cursive"]
+ };
+ PFont.preloading = {
+ template: {},
+ initialized: false,
+ initialize: function() {
+ var generateTinyFont = function() {
+ var encoded = "#E3KAI2wAgT1MvMg7Eo3VmNtYX7ABi3CxnbHlm" + "7Abw3kaGVhZ7ACs3OGhoZWE7A53CRobXR47AY3" + "AGbG9jYQ7G03Bm1heH7ABC3CBuYW1l7Ae3AgcG" + "9zd7AI3AE#B3AQ2kgTY18PPPUACwAg3ALSRoo3" + "#yld0xg32QAB77#E777773B#E3C#I#Q77773E#" + "Q7777777772CMAIw7AB77732B#M#Q3wAB#g3B#" + "E#E2BB//82BB////w#B7#gAEg3E77x2B32B#E#" + "Q#MTcBAQ32gAe#M#QQJ#E32M#QQJ#I#g32Q77#";
+ var expand = function(input) {
+ return "AAAAAAAA".substr(~~input ? 7 - input : 6)
+ };
+ return encoded.replace(/[#237]/g, expand)
+ };
+ var fontface = document.createElement("style");
+ fontface.setAttribute("type", "text/css");
+ fontface.innerHTML = "@font-face {\n" + ' font-family: "PjsEmptyFont";' + "\n" + " src: url('data:application/x-font-ttf;base64," + generateTinyFont() + "')\n" + " format('truetype');\n" + "}";
+ document.head.appendChild(fontface);
+ var element = document.createElement("span");
+ element.style.cssText = 'position: absolute; top: 0; left: 0; opacity: 0; font-family: "PjsEmptyFont", fantasy;';
+ element.innerHTML = "AAAAAAAA";
+ document.body.appendChild(element);
+ this.template = element;
+ this.initialized = true
+ },
+ getElementWidth: function(element) {
+ return document.defaultView.getComputedStyle(element, "").getPropertyValue("width")
+ },
+ timeAttempted: 0,
+ pending: function(intervallength) {
+ if (!this.initialized) this.initialize();
+ var element, computedWidthFont, computedWidthRef = this.getElementWidth(this.template);
+ for (var i = 0; i < this.fontList.length; i++) {
+ element = this.fontList[i];
+ computedWidthFont = this.getElementWidth(element);
+ if (this.timeAttempted < 4E3 && computedWidthFont === computedWidthRef) {
+ this.timeAttempted += intervallength;
+ return true
+ } else {
+ document.body.removeChild(element);
+ this.fontList.splice(i--, 1);
+ this.timeAttempted = 0
+ }
+ }
+ if (this.fontList.length === 0) return false;
+ return true
+ },
+ fontList: [],
+ addedList: {},
+ add: function(fontSrc) {
+ if (!this.initialized) this.initialize();
+ var fontName = typeof fontSrc === "object" ? fontSrc.fontFace : fontSrc,
+ fontUrl = typeof fontSrc === "object" ? fontSrc.url : fontSrc;
+ if (this.addedList[fontName]) return;
+ var style = document.createElement("style");
+ style.setAttribute("type", "text/css");
+ style.innerHTML = "@font-face{\n font-family: '" + fontName + "';\n src: url('" + fontUrl + "');\n}\n";
+ document.head.appendChild(style);
+ this.addedList[fontName] = true;
+ var element = document.createElement("span");
+ element.style.cssText = "position: absolute; top: 0; left: 0; opacity: 0;";
+ element.style.fontFamily = '"' + fontName + '", "PjsEmptyFont", fantasy';
+ element.innerHTML = "AAAAAAAA";
+ document.body.appendChild(element);
+ this.fontList.push(element)
+ }
+ };
+ defaultScope.PFont = PFont;
+ var Processing = this.Processing = function(aCanvas, aCode) {
+ if (! (this instanceof Processing)) throw "called Processing constructor as if it were a function: missing 'new'.";
+ var curElement, pgraphicsMode = aCanvas === undef && aCode === undef;
+ if (pgraphicsMode) curElement = document.createElement("canvas");
+ else curElement = typeof aCanvas === "string" ? document.getElementById(aCanvas) : aCanvas;
+ if (! (curElement instanceof HTMLCanvasElement)) throw "called Processing constructor without passing canvas element reference or id.";
function unimplemented(s) {
- Processing.debug('Unimplemented - ' + s);
+ Processing.debug("Unimplemented - " + s)
}
-
- // When something new is added to "p." it must also be added to the "names" array.
- // The names array contains the names of everything that is inside "p."
var p = this;
-
- var pgraphicsMode = (arguments.length === 0);
- if (pgraphicsMode) {
- curElement = document.createElement("canvas");
- }
-
- // PJS specific (non-p5) methods and properties to externalize
p.externals = {
- canvas: curElement,
+ canvas: curElement,
context: undef,
- sketch: undef
+ sketch: undef
};
-
- p.name = 'Processing.js Instance'; // Set Processing defaults / environment variables
- p.use3DContext = false; // default '2d' canvas context
-
- /**
- * Confirms if a Processing program is "focused", meaning that it is
- * active and will accept input from mouse or keyboard. This variable
- * is "true" if it is focused and "false" if not. This variable is
- * often used when you want to warn people they need to click on the
- * browser before it will work.
- */
- p.focused = false;
- p.breakShape = false;
-
- // Glyph path storage for textFonts
- p.glyphTable = {};
-
- // Global vars for tracking mouse position
- p.pmouseX = 0;
- p.pmouseY = 0;
- p.mouseX = 0;
- p.mouseY = 0;
- p.mouseButton = 0;
- p.mouseScroll = 0;
-
- // Undefined event handlers to be replaced by user when needed
- p.mouseClicked = undef;
- p.mouseDragged = undef;
- p.mouseMoved = undef;
- p.mousePressed = undef;
- p.mouseReleased = undef;
- p.mouseScrolled = undef;
- p.mouseOver = undef;
- p.mouseOut = undef;
- p.touchStart = undef;
- p.touchEnd = undef;
- p.touchMove = undef;
- p.touchCancel = undef;
- p.key = undef;
- p.keyCode = undef;
- p.keyPressed = function(){}; // needed to remove function checks
- p.keyReleased = function(){};
- p.keyTyped = function(){};
- p.draw = undef;
- p.setup = undef;
-
- // Remapped vars
- p.__mousePressed = false;
- p.__keyPressed = false;
- p.__frameRate = 60;
-
- // The current animation frame
- p.frameCount = 0;
-
- // The height/width of the canvas
- p.width = 100;
- p.height = 100;
-
- // "Private" variables used to maintain state
- var curContext,
- curSketch,
- drawing, // hold a Drawing2D or Drawing3D object
- online = true,
- doFill = true,
- fillStyle = [1.0, 1.0, 1.0, 1.0],
- currentFillColor = 0xFFFFFFFF,
- isFillDirty = true,
- doStroke = true,
- strokeStyle = [0.8, 0.8, 0.8, 1.0],
- currentStrokeColor = 0xFFFDFDFD,
- isStrokeDirty = true,
- lineWidth = 1,
- loopStarted = false,
- doLoop = true,
- looping = 0,
- curRectMode = PConstants.CORNER,
- curEllipseMode = PConstants.CENTER,
- normalX = 0,
- normalY = 0,
- normalZ = 0,
- normalMode = PConstants.NORMAL_MODE_AUTO,
- inDraw = false,
- curFrameRate = 60,
- curMsPerFrame = 1000/curFrameRate,
- curCursor = PConstants.ARROW,
- oldCursor = curElement.style.cursor,
- curShape = PConstants.POLYGON,
- curShapeCount = 0,
- curvePoints = [],
- curTightness = 0,
- curveDet = 20,
- curveInited = false,
- backgroundObj = -3355444, // rgb(204, 204, 204) is the default gray background colour
- bezDetail = 20,
- colorModeA = 255,
- colorModeX = 255,
- colorModeY = 255,
- colorModeZ = 255,
- pathOpen = false,
- mouseDragging = false,
- curColorMode = PConstants.RGB,
- curTint = null,
- curTextSize = 12,
- curTextFont = {name: "\"Arial\", sans-serif", origName: "Arial"},
- curTextLeading = 14,
- getLoaded = false,
- start = new Date().getTime(),
- timeSinceLastFPS = start,
- framesSinceLastFPS = 0,
- textcanvas,
- curveBasisMatrix,
- curveToBezierMatrix,
- curveDrawMatrix,
- bezierDrawMatrix,
- bezierBasisInverse,
- bezierBasisMatrix,
- // Keys and Keystrokes
- firstCodedDown = true, // first coded key stroke
- firstEDGKeyDown = true, // first Enter - Delete Google key stroke
- firstEDMKeyDown = true, // first Enter - Delete Mozilla key stroke
- firstMKeyDown = true, // first Mozilla key stroke
- firstGKeyDown = true, // first Google key stroke
- gRefire = false, // Google refire
- curContextCache = { attributes: {}, locations: {} },
- // Shaders
- programObject3D,
- programObject2D,
- programObjectUnlitShape,
- boxBuffer,
- boxNormBuffer,
- boxOutlineBuffer,
- rectBuffer,
- rectNormBuffer,
- sphereBuffer,
- lineBuffer,
- fillBuffer,
- fillColorBuffer,
- strokeColorBuffer,
- pointBuffer,
- shapeTexVBO,
- canTex, // texture for createGraphics
- textTex, // texture for 3d tex
- curTexture = {width:0,height:0},
- curTextureMode = PConstants.IMAGE,
- usingTexture = false,
- textBuffer,
- textureBuffer,
- indexBuffer,
- // Text alignment
- horizontalTextAlignment = PConstants.LEFT,
- verticalTextAlignment = PConstants.BASELINE,
- baselineOffset = 0.2, // percent
- tMode = PConstants.MODEL,
- // Pixels cache
- originalContext,
- proxyContext = null,
- isContextReplaced = false,
- setPixelsCached,
- maxPixelsCached = 1000,
- pressedKeysMap = [],
- lastPressedKeyCode = null,
- codedKeys = [ PConstants.SHIFT, PConstants.CONTROL, PConstants.ALT, PConstants.CAPSLK, PConstants.PGUP, PConstants.PGDN,
- PConstants.END, PConstants.HOME, PConstants.LEFT, PConstants.UP, PConstants.RIGHT, PConstants.DOWN, PConstants.NUMLK,
- PConstants.INSERT, PConstants.F1, PConstants.F2, PConstants.F3, PConstants.F4, PConstants.F5, PConstants.F6, PConstants.F7,
- PConstants.F8, PConstants.F9, PConstants.F10, PConstants.F11, PConstants.F12, PConstants.META ];
-
- // Get padding and border style widths for mouse offsets
+ p.name = "Processing.js Instance";
+ p.use3DContext = false;
+ p.focused = false;
+ p.breakShape = false;
+ p.glyphTable = {};
+ p.pmouseX = 0;
+ p.pmouseY = 0;
+ p.mouseX = 0;
+ p.mouseY = 0;
+ p.mouseButton = 0;
+ p.mouseScroll = 0;
+ p.mouseClicked = undef;
+ p.mouseDragged = undef;
+ p.mouseMoved = undef;
+ p.mousePressed = undef;
+ p.mouseReleased = undef;
+ p.mouseScrolled = undef;
+ p.mouseOver = undef;
+ p.mouseOut = undef;
+ p.touchStart = undef;
+ p.touchEnd = undef;
+ p.touchMove = undef;
+ p.touchCancel = undef;
+ p.key = undef;
+ p.keyCode = undef;
+ p.keyPressed = nop;
+ p.keyReleased = nop;
+ p.keyTyped = nop;
+ p.draw = undef;
+ p.setup = undef;
+ p.__mousePressed = false;
+ p.__keyPressed = false;
+ p.__frameRate = 60;
+ p.frameCount = 0;
+ p.width = 100;
+ p.height = 100;
+ var curContext, curSketch, drawing, online = true,
+ doFill = true,
+ fillStyle = [1, 1, 1, 1],
+ currentFillColor = 4294967295,
+ isFillDirty = true,
+ doStroke = true,
+ strokeStyle = [0, 0, 0, 1],
+ currentStrokeColor = 4278190080,
+ isStrokeDirty = true,
+ lineWidth = 1,
+ loopStarted = false,
+ renderSmooth = false,
+ doLoop = true,
+ looping = 0,
+ curRectMode = 0,
+ curEllipseMode = 3,
+ normalX = 0,
+ normalY = 0,
+ normalZ = 0,
+ normalMode = 0,
+ curFrameRate = 60,
+ curMsPerFrame = 1E3 / curFrameRate,
+ curCursor = 'default',
+ oldCursor = curElement.style.cursor,
+ curShape = 20,
+ curShapeCount = 0,
+ curvePoints = [],
+ curTightness = 0,
+ curveDet = 20,
+ curveInited = false,
+ backgroundObj = -3355444,
+ bezDetail = 20,
+ colorModeA = 255,
+ colorModeX = 255,
+ colorModeY = 255,
+ colorModeZ = 255,
+ pathOpen = false,
+ mouseDragging = false,
+ pmouseXLastFrame = 0,
+ pmouseYLastFrame = 0,
+ curColorMode = 1,
+ curTint = null,
+ curTint3d = null,
+ getLoaded = false,
+ start = Date.now(),
+ timeSinceLastFPS = start,
+ framesSinceLastFPS = 0,
+ textcanvas, curveBasisMatrix, curveToBezierMatrix, curveDrawMatrix, bezierDrawMatrix, bezierBasisInverse, bezierBasisMatrix, curContextCache = {
+ attributes: {},
+ locations: {}
+ },
+ programObject3D, programObject2D, programObjectUnlitShape, boxBuffer, boxNormBuffer, boxOutlineBuffer, rectBuffer, rectNormBuffer, sphereBuffer, lineBuffer, fillBuffer, fillColorBuffer, strokeColorBuffer, pointBuffer, shapeTexVBO, canTex, textTex, curTexture = {
+ width: 0,
+ height: 0
+ },
+ curTextureMode = 2,
+ usingTexture = false,
+ textBuffer, textureBuffer, indexBuffer, horizontalTextAlignment = 37,
+ verticalTextAlignment = 0,
+ textMode = 4,
+ curFontName = "Arial",
+ curTextSize = 12,
+ curTextAscent = 9,
+ curTextDescent = 2,
+ curTextLeading = 14,
+ curTextFont = PFont.get(curFontName, curTextSize),
+ originalContext, proxyContext = null,
+ isContextReplaced = false,
+ setPixelsCached, maxPixelsCached = 1E3,
+ pressedKeysMap = [],
+ lastPressedKeyCode = null,
+ codedKeys = [16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 144, 155, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 157];
var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop;
-
if (document.defaultView && document.defaultView.getComputedStyle) {
- stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)['paddingLeft'], 10) || 0;
- stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)['paddingTop'], 10) || 0;
- styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)['borderLeftWidth'], 10) || 0;
- styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)['borderTopWidth'], 10) || 0;
+ stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingLeft"], 10) || 0;
+ stylePaddingTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["paddingTop"], 10) || 0;
+ styleBorderLeft = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderLeftWidth"], 10) || 0;
+ styleBorderTop = parseInt(document.defaultView.getComputedStyle(curElement, null)["borderTopWidth"], 10) || 0
}
-
- // User can only have MAX_LIGHTS lights
var lightCount = 0;
-
- //sphere stuff
var sphereDetailV = 0,
- sphereDetailU = 0,
- sphereX = [],
- sphereY = [],
- sphereZ = [],
- sinLUT = new Float32Array(PConstants.SINCOS_LENGTH),
- cosLUT = new Float32Array(PConstants.SINCOS_LENGTH),
- sphereVerts,
- sphereNorms;
-
- // Camera defaults and settings
- var cam,
- cameraInv,
- forwardTransform,
- reverseTransform,
- modelView,
- modelViewInv,
- userMatrixStack,
- userReverseMatrixStack,
- inverseCopy,
- projection,
- manipulatingCamera = false,
- frustumMode = false,
- cameraFOV = 60 * (Math.PI / 180),
- cameraX = p.width / 2,
- cameraY = p.height / 2,
- cameraZ = cameraY / Math.tan(cameraFOV / 2),
- cameraNear = cameraZ / 10,
- cameraFar = cameraZ * 10,
- cameraAspect = p.width / p.height;
-
+ sphereDetailU = 0,
+ sphereX = [],
+ sphereY = [],
+ sphereZ = [],
+ sinLUT = new Float32Array(720),
+ cosLUT = new Float32Array(720),
+ sphereVerts, sphereNorms;
+ var cam, cameraInv, modelView, modelViewInv, userMatrixStack, userReverseMatrixStack, inverseCopy, projection, manipulatingCamera = false,
+ frustumMode = false,
+ cameraFOV = 60 * (Math.PI / 180),
+ cameraX = p.width / 2,
+ cameraY = p.height / 2,
+ cameraZ = cameraY / Math.tan(cameraFOV / 2),
+ cameraNear = cameraZ / 10,
+ cameraFar = cameraZ * 10,
+ cameraAspect = p.width / p.height;
var vertArray = [],
- curveVertArray = [],
- curveVertCount = 0,
- isCurve = false,
- isBezier = false,
- firstVert = true;
-
- //PShape stuff
- var curShapeMode = PConstants.CORNER;
-
- // Stores states for pushStyle() and popStyle().
+ curveVertArray = [],
+ curveVertCount = 0,
+ isCurve = false,
+ isBezier = false,
+ firstVert = true;
+ var curShapeMode = 0;
var styleArray = [];
-
- // Vertices are specified in a counter-clockwise order
- // triangles are in this order: back, front, right, bottom, left, top
- var boxVerts = new Float32Array([
- 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5,
- 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5,
- 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5,
- 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5,
- -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5,
- 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]);
-
- var boxOutlineVerts = new Float32Array([
- 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5,
- -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5,
- 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
- -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5,
- 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5,
- -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]);
-
- var boxNorms = new Float32Array([
- 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1,
- 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
- 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
- 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
- -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
- 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]);
-
- // These verts are used for the fill and stroke using TRIANGLE_FAN and LINE_LOOP
- var rectVerts = new Float32Array([0,0,0, 0,1,0, 1,1,0, 1,0,0]);
-
- var rectNorms = new Float32Array([0,0,1, 0,0,1, 0,0,1, 0,0,1]);
-
-
- // Shader for points and lines in begin/endShape
- var vShaderSrcUnlitShape =
- "varying vec4 frontColor;" +
-
- "attribute vec3 aVertex;" +
- "attribute vec4 aColor;" +
-
- "uniform mat4 uView;" +
- "uniform mat4 uProjection;" +
- "uniform float pointSize;" +
-
- "void main(void) {" +
- " frontColor = aColor;" +
- " gl_PointSize = pointSize;" +
- " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" +
- "}";
-
- var fShaderSrcUnlitShape =
- "#ifdef GL_ES\n" +
- "precision highp float;\n" +
- "#endif\n" +
-
- "varying vec4 frontColor;" +
-
- "void main(void){" +
- " gl_FragColor = frontColor;" +
- "}";
-
- // Shader for rect, text, box outlines, sphere outlines, point() and line()
- var vertexShaderSource2D =
- "varying vec4 frontColor;" +
-
- "attribute vec3 Vertex;" +
- "attribute vec2 aTextureCoord;" +
- "uniform vec4 color;" +
-
- "uniform mat4 model;" +
- "uniform mat4 view;" +
- "uniform mat4 projection;" +
- "uniform float pointSize;" +
- "varying vec2 vTextureCoord;"+
-
- "void main(void) {" +
- " gl_PointSize = pointSize;" +
- " frontColor = color;" +
- " gl_Position = projection * view * model * vec4(Vertex, 1.0);" +
- " vTextureCoord = aTextureCoord;" +
- "}";
-
- var fragmentShaderSource2D =
- "#ifdef GL_ES\n" +
- "precision highp float;\n" +
- "#endif\n" +
-
- "varying vec4 frontColor;" +
- "varying vec2 vTextureCoord;"+
-
- "uniform sampler2D uSampler;"+
- "uniform int picktype;"+
-
- "void main(void){" +
- " if(picktype == 0){"+
- " gl_FragColor = frontColor;" +
- " }" +
- " else if(picktype == 1){"+
- " float alpha = texture2D(uSampler, vTextureCoord).a;"+
- " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n"+
- " }"+
- "}";
-
+ var boxVerts = new Float32Array([0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5,
+ -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5]);
+ var boxOutlineVerts = new Float32Array([0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5,
+ 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5]);
+ var boxNorms = new Float32Array([0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]);
+ var rectVerts = new Float32Array([0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0]);
+ var rectNorms = new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);
+ var vShaderSrcUnlitShape = "varying vec4 frontColor;" + "attribute vec3 aVertex;" + "attribute vec4 aColor;" + "uniform mat4 uView;" + "uniform mat4 uProjection;" + "uniform float pointSize;" + "void main(void) {" + " frontColor = aColor;" + " gl_PointSize = pointSize;" + " gl_Position = uProjection * uView * vec4(aVertex, 1.0);" + "}";
+ var fShaderSrcUnlitShape = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "void main(void){" + " gl_FragColor = frontColor;" + "}";
+ var vertexShaderSource2D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec2 aTextureCoord;" + "uniform vec4 color;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform float pointSize;" + "varying vec2 vTextureCoord;" + "void main(void) {" + " gl_PointSize = pointSize;" + " frontColor = color;" + " gl_Position = projection * view * model * vec4(Vertex, 1.0);" + " vTextureCoord = aTextureCoord;" + "}";
+ var fragmentShaderSource2D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "varying vec2 vTextureCoord;" + "uniform sampler2D uSampler;" + "uniform int picktype;" + "void main(void){" + " if(picktype == 0){" + " gl_FragColor = frontColor;" + " }" + " else if(picktype == 1){" + " float alpha = texture2D(uSampler, vTextureCoord).a;" + " gl_FragColor = vec4(frontColor.rgb*alpha, alpha);\n" + " }" + "}";
var webglMaxTempsWorkaround = /Windows/.test(navigator.userAgent);
+ var vertexShaderSource3D = "varying vec4 frontColor;" + "attribute vec3 Vertex;" + "attribute vec3 Normal;" + "attribute vec4 aColor;" + "attribute vec2 aTexture;" + "varying vec2 vTexture;" + "uniform vec4 color;" + "uniform bool usingMat;" + "uniform vec3 specular;" + "uniform vec3 mat_emissive;" + "uniform vec3 mat_ambient;" + "uniform vec3 mat_specular;" + "uniform float shininess;" + "uniform mat4 model;" + "uniform mat4 view;" + "uniform mat4 projection;" + "uniform mat4 normalTransform;" + "uniform int lightCount;" + "uniform vec3 falloff;" + "struct Light {" + " int type;" + " vec3 color;" + " vec3 position;" + " vec3 direction;" + " float angle;" + " vec3 halfVector;" + " float concentration;" + "};" + "uniform Light lights0;" + "uniform Light lights1;" + "uniform Light lights2;" + "uniform Light lights3;" + "uniform Light lights4;" + "uniform Light lights5;" + "uniform Light lights6;" + "uniform Light lights7;" + "Light getLight(int index){" + " if(index == 0) return lights0;" + " if(index == 1) return lights1;" + " if(index == 2) return lights2;" + " if(index == 3) return lights3;" + " if(index == 4) return lights4;" + " if(index == 5) return lights5;" + " if(index == 6) return lights6;" + " return lights7;" + "}" + "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" + " float d = length( light.position - ecPos );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " totalAmbient += light.color * attenuation;" + "}" + "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor = 0.0;" + " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" + " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" + " if( nDotVP != 0.0 ){" + " powerfactor = pow( nDotVH, shininess );" + " }" + " col += light.color * nDotVP;" + " spec += specular * powerfactor;" + "}" + "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float powerfactor;" + " vec3 VP = light.position - ecPos;" + " float d = length( VP ); " + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0) {" + " powerfactor = 0.0;" + " }" + " else{" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" + " float spotAttenuation;" + " float powerfactor;" + " vec3 VP = light.position - ecPos; " + " vec3 ldir = normalize( -light.direction );" + " float d = length( VP );" + " VP = normalize( VP );" + " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" + " float spotDot = dot( VP, ldir );" + (webglMaxTempsWorkaround ? " spotAttenuation = 1.0; " : " if( spotDot > cos( light.angle ) ) {" + " spotAttenuation = pow( spotDot, light.concentration );" + " }" + " else{" + " spotAttenuation = 0.0;" + " }" + " attenuation *= spotAttenuation;" + "") + " float nDotVP = max( 0.0, dot( vertNormal, VP ));" + " vec3 halfVector = normalize( VP - normalize(ecPos) );" + " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" + " if( nDotVP == 0.0 ) {" + " powerfactor = 0.0;" + " }" + " else {" + " powerfactor = pow( nDotHV, shininess );" + " }" + " spec += specular * powerfactor * attenuation;" + " col += light.color * nDotVP * attenuation;" + "}" + "void main(void) {" + " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" + " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" + " vec4 col = color;" + " if(color[0] == -1.0){" + " col = aColor;" + " }" + " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" + " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" + " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" + " if( lightCount == 0 ) {" + " frontColor = col + vec4(mat_specular,1.0);" + " }" + " else {" + " for( int i = 0; i < 8; i++ ) {" + " Light l = getLight(i);" + " if( i >= lightCount ){" + " break;" + " }" + " if( l.type == 0 ) {" + " AmbientLight( finalAmbient, ecPos, l );" + " }" + " else if( l.type == 1 ) {" + " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else if( l.type == 2 ) {" + " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " else {" + " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" + " }" + " }" + " if( usingMat == false ) {" + " frontColor = vec4(" + " vec3(col) * finalAmbient +" + " vec3(col) * finalDiffuse +" + " vec3(col) * finalSpecular," + " col[3] );" + " }" + " else{" + " frontColor = vec4( " + " mat_emissive + " + " (vec3(col) * mat_ambient * finalAmbient) + " + " (vec3(col) * finalDiffuse) + " + " (mat_specular * finalSpecular), " + " col[3] );" + " }" + " }" + " vTexture.xy = aTexture.xy;" + " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" + "}";
+ var fragmentShaderSource3D = "#ifdef GL_ES\n" + "precision highp float;\n" + "#endif\n" + "varying vec4 frontColor;" + "uniform sampler2D sampler;" + "uniform bool usingTexture;" + "varying vec2 vTexture;" + "void main(void){" + " if(usingTexture){" + " gl_FragColor = vec4(texture2D(sampler, vTexture.xy)) * frontColor;" + " }" + " else{" + " gl_FragColor = frontColor;" + " }" + "}";
- // Vertex shader for boxes and spheres
- var vertexShaderSource3D =
- "varying vec4 frontColor;" +
-
- "attribute vec3 Vertex;" +
- "attribute vec3 Normal;" +
- "attribute vec4 aColor;" +
- "attribute vec2 aTexture;" +
- "varying vec2 vTexture;" +
-
- "uniform vec4 color;" +
-
- "uniform bool usingMat;" +
- "uniform vec3 specular;" +
- "uniform vec3 mat_emissive;" +
- "uniform vec3 mat_ambient;" +
- "uniform vec3 mat_specular;" +
- "uniform float shininess;" +
-
- "uniform mat4 model;" +
- "uniform mat4 view;" +
- "uniform mat4 projection;" +
- "uniform mat4 normalTransform;" +
-
- "uniform int lightCount;" +
- "uniform vec3 falloff;" +
-
- // careful changing the order of these fields. Some cards
- // have issues with memory alignment
- "struct Light {" +
- " int type;" +
- " vec3 color;" +
- " vec3 position;" +
- " vec3 direction;" +
- " float angle;" +
- " vec3 halfVector;" +
- " float concentration;" +
- "};" +
-
- // nVidia cards have issues with arrays of structures
- // so instead we create 8 instances of Light
- "uniform Light lights0;" +
- "uniform Light lights1;" +
- "uniform Light lights2;" +
- "uniform Light lights3;" +
- "uniform Light lights4;" +
- "uniform Light lights5;" +
- "uniform Light lights6;" +
- "uniform Light lights7;" +
-
- // GLSL does not support switch
- "Light getLight(int index){" +
- " if(index == 0) return lights0;" +
- " if(index == 1) return lights1;" +
- " if(index == 2) return lights2;" +
- " if(index == 3) return lights3;" +
- " if(index == 4) return lights4;" +
- " if(index == 5) return lights5;" +
- " if(index == 6) return lights6;" +
- // Do not use a conditional for the last return statement
- // because some video cards will fail and complain that
- // "not all paths return"
- " return lights7;" +
- "}" +
-
- "void AmbientLight( inout vec3 totalAmbient, in vec3 ecPos, in Light light ) {" +
- // Get the vector from the light to the vertex
- // Get the distance from the current vector to the light position
- " float d = length( light.position - ecPos );" +
- " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" +
- " totalAmbient += light.color * attenuation;" +
- "}" +
-
- "void DirectionalLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" +
- " float powerfactor = 0.0;" +
- " float nDotVP = max(0.0, dot( vertNormal, normalize(-light.position) ));" +
- " float nDotVH = max(0.0, dot( vertNormal, normalize(-light.position-normalize(ecPos) )));" +
-
- " if( nDotVP != 0.0 ){" +
- " powerfactor = pow( nDotVH, shininess );" +
- " }" +
-
- " col += light.color * nDotVP;" +
- " spec += specular * powerfactor;" +
- "}" +
-
- "void PointLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" +
- " float powerfactor;" +
-
- // Get the vector from the light to the vertex
- " vec3 VP = light.position - ecPos;" +
-
- // Get the distance from the current vector to the light position
- " float d = length( VP ); " +
-
- // Normalize the light ray so it can be used in the dot product operation.
- " VP = normalize( VP );" +
-
- " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ));" +
-
- " float nDotVP = max( 0.0, dot( vertNormal, VP ));" +
- " vec3 halfVector = normalize( VP - normalize(ecPos) );" +
- " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" +
-
- " if( nDotVP == 0.0) {" +
- " powerfactor = 0.0;" +
- " }" +
- " else{" +
- " powerfactor = pow( nDotHV, shininess );" +
- " }" +
-
- " spec += specular * powerfactor * attenuation;" +
- " col += light.color * nDotVP * attenuation;" +
- "}" +
-
- /*
- */
- "void SpotLight( inout vec3 col, inout vec3 spec, in vec3 vertNormal, in vec3 ecPos, in Light light ) {" +
- " float spotAttenuation;" +
- " float powerfactor;" +
-
- // calculate the vector from the current vertex to the light.
- " vec3 VP = light.position - ecPos; " +
- " vec3 ldir = normalize( -light.direction );" +
-
- // get the distance from the spotlight and the vertex
- " float d = length( VP );" +
- " VP = normalize( VP );" +
-
- " float attenuation = 1.0 / ( falloff[0] + ( falloff[1] * d ) + ( falloff[2] * d * d ) );" +
-
- // dot product of the vector from vertex to light and light direction.
- " float spotDot = dot( VP, ldir );" +
-
- // if the vertex falls inside the cone
- (webglMaxTempsWorkaround ? // Windows reports max temps error if light.angle is used
- " spotAttenuation = 1.0; " :
- " if( spotDot > cos( light.angle ) ) {" +
- " spotAttenuation = pow( spotDot, light.concentration );" +
- " }" +
- " else{" +
- " spotAttenuation = 0.0;" +
- " }" +
- " attenuation *= spotAttenuation;" +
- "") +
-
- " float nDotVP = max( 0.0, dot( vertNormal, VP ));" +
- " vec3 halfVector = normalize( VP - normalize(ecPos) );" +
- " float nDotHV = max( 0.0, dot( vertNormal, halfVector ));" +
-
- " if( nDotVP == 0.0 ) {" +
- " powerfactor = 0.0;" +
- " }" +
- " else {" +
- " powerfactor = pow( nDotHV, shininess );" +
- " }" +
-
- " spec += specular * powerfactor * attenuation;" +
- " col += light.color * nDotVP * attenuation;" +
- "}" +
-
- "void main(void) {" +
- " vec3 finalAmbient = vec3( 0.0, 0.0, 0.0 );" +
- " vec3 finalDiffuse = vec3( 0.0, 0.0, 0.0 );" +
- " vec3 finalSpecular = vec3( 0.0, 0.0, 0.0 );" +
-
- " vec4 col = color;" +
-
- " if(color[0] == -1.0){" +
- " col = aColor;" +
- " }" +
-
- // We use the sphere vertices as the normals when we create the sphere buffer.
- // But this only works if the sphere vertices are unit length, so we
- // have to normalize the normals here. Since this is only required for spheres
- // we could consider placing this in a conditional later on.
- " vec3 norm = normalize(vec3( normalTransform * vec4( Normal, 0.0 ) ));" +
-
- " vec4 ecPos4 = view * model * vec4(Vertex,1.0);" +
- " vec3 ecPos = (vec3(ecPos4))/ecPos4.w;" +
-
- // If there were no lights this draw call, just use the
- // assigned fill color of the shape and the specular value
- " if( lightCount == 0 ) {" +
- " frontColor = col + vec4(mat_specular,1.0);" +
- " }" +
- " else {" +
- // WebGL forces us to iterate over a constant value
- // so we can't iterate using lightCount
- " for( int i = 0; i < 8; i++ ) {" +
- " Light l = getLight(i);" +
-
- // We can stop iterating if we know we have gone past
- // the number of lights which are on
- " if( i >= lightCount ){" +
- " break;" +
- " }" +
-
- " if( l.type == 0 ) {" +
- " AmbientLight( finalAmbient, ecPos, l );" +
- " }" +
- " else if( l.type == 1 ) {" +
- " DirectionalLight( finalDiffuse, finalSpecular, norm, ecPos, l );" +
- " }" +
- " else if( l.type == 2 ) {" +
- " PointLight( finalDiffuse, finalSpecular, norm, ecPos, l );" +
- " }" +
- " else {" +
- " SpotLight( finalDiffuse, finalSpecular, norm, ecPos, l );" +
- " }" +
- " }" +
-
- " if( usingMat == false ) {" +
- " frontColor = vec4(" +
- " vec3(col) * finalAmbient +" +
- " vec3(col) * finalDiffuse +" +
- " vec3(col) * finalSpecular," +
- " col[3] );" +
- " }" +
- " else{" +
- " frontColor = vec4( " +
- " mat_emissive + " +
- " (vec3(col) * mat_ambient * finalAmbient) + " +
- " (vec3(col) * finalDiffuse) + " +
- " (mat_specular * finalSpecular), " +
- " col[3] );" +
- " }" +
- " }" +
-
- " vTexture.xy = aTexture.xy;" +
- " gl_Position = projection * view * model * vec4( Vertex, 1.0 );" +
- "}";
-
- var fragmentShaderSource3D =
- "#ifdef GL_ES\n" +
- "precision highp float;\n" +
- "#endif\n" +
-
- "varying vec4 frontColor;" +
-
- "uniform sampler2D sampler;" +
- "uniform bool usingTexture;" +
- "varying vec2 vTexture;" +
-
- // In Processing, when a texture is used, the fill color is ignored
- "void main(void){" +
- " if(usingTexture){" +
- " gl_FragColor = vec4(texture2D(sampler, vTexture.xy));" +
- " }"+
- " else{" +
- " gl_FragColor = frontColor;" +
- " }" +
- "}";
-
- ////////////////////////////////////////////////////////////////////////////
- // 3D Functions
- ////////////////////////////////////////////////////////////////////////////
-
- /*
- * Sets a uniform variable in a program object to a particular
- * value. Before calling this function, ensure the correct
- * program object has been installed as part of the current
- * rendering state by calling useProgram.
- *
- * On some systems, if the variable exists in the shader but isn't used,
- * the compiler will optimize it out and this function will fail.
- *
- * @param {WebGLProgram} programObj program object returned from
- * createProgramObject
- * @param {String} varName the name of the variable in the shader
- * @param {float | Array} varValue either a scalar value or an Array
- *
- * @returns none
- *
- * @see uniformi
- * @see uniformMatrix
- */
function uniformf(cacheId, programObj, varName, varValue) {
var varLocation = curContextCache.locations[cacheId];
- if(varLocation === undef) {
+ if (varLocation === undef) {
varLocation = curContext.getUniformLocation(programObj, varName);
- curContextCache.locations[cacheId] = varLocation;
- }
- // the variable won't be found if it was optimized out.
- if (varLocation !== -1) {
- if (varValue.length === 4) {
- curContext.uniform4fv(varLocation, varValue);
- } else if (varValue.length === 3) {
- curContext.uniform3fv(varLocation, varValue);
- } else if (varValue.length === 2) {
- curContext.uniform2fv(varLocation, varValue);
- } else {
- curContext.uniform1f(varLocation, varValue);
- }
+ curContextCache.locations[cacheId] = varLocation
}
+ if (varLocation !== null) if (varValue.length === 4) curContext.uniform4fv(varLocation, varValue);
+ else if (varValue.length === 3) curContext.uniform3fv(varLocation, varValue);
+ else if (varValue.length === 2) curContext.uniform2fv(varLocation, varValue);
+ else curContext.uniform1f(varLocation, varValue)
}
-
- /**
- * Sets a uniform int or int array in a program object to a particular
- * value. Before calling this function, ensure the correct
- * program object has been installed as part of the current
- * rendering state.
- *
- * On some systems, if the variable exists in the shader but isn't used,
- * the compiler will optimize it out and this function will fail.
- *
- * @param {WebGLProgram} programObj program object returned from
- * createProgramObject
- * @param {String} varName the name of the variable in the shader
- * @param {int | Array} varValue either a scalar value or an Array
- *
- * @returns none
- *
- * @see uniformf
- * @see uniformMatrix
- */
function uniformi(cacheId, programObj, varName, varValue) {
var varLocation = curContextCache.locations[cacheId];
- if(varLocation === undef) {
+ if (varLocation === undef) {
varLocation = curContext.getUniformLocation(programObj, varName);
- curContextCache.locations[cacheId] = varLocation;
- }
- // the variable won't be found if it was optimized out.
- if (varLocation !== -1) {
- if (varValue.length === 4) {
- curContext.uniform4iv(varLocation, varValue);
- } else if (varValue.length === 3) {
- curContext.uniform3iv(varLocation, varValue);
- } else if (varValue.length === 2) {
- curContext.uniform2iv(varLocation, varValue);
- } else {
- curContext.uniform1i(varLocation, varValue);
- }
+ curContextCache.locations[cacheId] = varLocation
}
+ if (varLocation !== null) if (varValue.length === 4) curContext.uniform4iv(varLocation, varValue);
+ else if (varValue.length === 3) curContext.uniform3iv(varLocation, varValue);
+ else if (varValue.length === 2) curContext.uniform2iv(varLocation, varValue);
+ else curContext.uniform1i(varLocation, varValue)
+ }
+ function uniformMatrix(cacheId, programObj, varName, transpose, matrix) {
+ var varLocation = curContextCache.locations[cacheId];
+ if (varLocation === undef) {
+ varLocation = curContext.getUniformLocation(programObj, varName);
+ curContextCache.locations[cacheId] = varLocation
+ }
+ if (varLocation !== -1) if (matrix.length === 16) curContext.uniformMatrix4fv(varLocation, transpose, matrix);
+ else if (matrix.length === 9) curContext.uniformMatrix3fv(varLocation, transpose, matrix);
+ else curContext.uniformMatrix2fv(varLocation, transpose, matrix)
}
-
- /**
- * Binds the VBO, sets the vertex attribute data for the program
- * object and enables the attribute.
- *
- * On some systems, if the attribute exists in the shader but
- * isn't used, the compiler will optimize it out and this
- * function will fail.
- *
- * @param {WebGLProgram} programObj program object returned from
- * createProgramObject
- * @param {String} varName the name of the variable in the shader
- * @param {int} size the number of components per vertex attribute
- * @param {WebGLBuffer} VBO Vertex Buffer Object
- *
- * @returns none
- *
- * @see disableVertexAttribPointer
- */
function vertexAttribPointer(cacheId, programObj, varName, size, VBO) {
var varLocation = curContextCache.attributes[cacheId];
- if(varLocation === undef) {
+ if (varLocation === undef) {
varLocation = curContext.getAttribLocation(programObj, varName);
- curContextCache.attributes[cacheId] = varLocation;
+ curContextCache.attributes[cacheId] = varLocation
}
if (varLocation !== -1) {
curContext.bindBuffer(curContext.ARRAY_BUFFER, VBO);
curContext.vertexAttribPointer(varLocation, size, curContext.FLOAT, false, 0, 0);
- curContext.enableVertexAttribArray(varLocation);
+ curContext.enableVertexAttribArray(varLocation)
}
}
-
- /**
- * Disables a program object attribute from being sent to WebGL.
- *
- * @param {WebGLProgram} programObj program object returned from
- * createProgramObject
- * @param {String} varName name of the attribute
- *
- * @returns none
- *
- * @see vertexAttribPointer
- */
- function disableVertexAttribPointer(cacheId, programObj, varName){
+ function disableVertexAttribPointer(cacheId, programObj, varName) {
var varLocation = curContextCache.attributes[cacheId];
- if(varLocation === undef) {
+ if (varLocation === undef) {
varLocation = curContext.getAttribLocation(programObj, varName);
- curContextCache.attributes[cacheId] = varLocation;
- }
- if (varLocation !== -1) {
- curContext.disableVertexAttribArray(varLocation);
+ curContextCache.attributes[cacheId] = varLocation
}
+ if (varLocation !== -1) curContext.disableVertexAttribArray(varLocation)
}
-
- /**
- * Sets the value of a uniform matrix variable in a program
- * object. Before calling this function, ensure the correct
- * program object has been installed as part of the current
- * rendering state.
- *
- * On some systems, if the variable exists in the shader but
- * isn't used, the compiler will optimize it out and this
- * function will fail.
- *
- * @param {WebGLProgram} programObj program object returned from
- * createProgramObject
- * @param {String} varName the name of the variable in the shader
- * @param {boolean} transpose must be false
- * @param {Array} matrix an array of 4, 9 or 16 values
- *
- * @returns none
- *
- * @see uniformi
- * @see uniformf
- */
- function uniformMatrix(cacheId, programObj, varName, transpose, matrix) {
- var varLocation = curContextCache.locations[cacheId];
- if(varLocation === undef) {
- varLocation = curContext.getUniformLocation(programObj, varName);
- curContextCache.locations[cacheId] = varLocation;
- }
- // the variable won't be found if it was optimized out.
- if (varLocation !== -1) {
- if (matrix.length === 16) {
- curContext.uniformMatrix4fv(varLocation, transpose, matrix);
- } else if (matrix.length === 9) {
- curContext.uniformMatrix3fv(varLocation, transpose, matrix);
- } else {
- curContext.uniformMatrix2fv(varLocation, transpose, matrix);
- }
- }
- }
-
+ var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) {
+ var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER);
+ curContext.shaderSource(vertexShaderObject, vetexShaderSource);
+ curContext.compileShader(vertexShaderObject);
+ if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(vertexShaderObject);
+ var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER);
+ curContext.shaderSource(fragmentShaderObject, fragmentShaderSource);
+ curContext.compileShader(fragmentShaderObject);
+ if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) throw curContext.getShaderInfoLog(fragmentShaderObject);
+ var programObject = curContext.createProgram();
+ curContext.attachShader(programObject, vertexShaderObject);
+ curContext.attachShader(programObject, fragmentShaderObject);
+ curContext.linkProgram(programObject);
+ if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) throw "Error linking shaders.";
+ return programObject
+ };
var imageModeCorner = function(x, y, w, h, whAreSizes) {
return {
x: x,
y: y,
w: w,
h: h
- };
+ }
};
var imageModeConvert = imageModeCorner;
-
var imageModeCorners = function(x, y, w, h, whAreSizes) {
return {
x: x,
y: y,
w: whAreSizes ? w : w - x,
h: whAreSizes ? h : h - y
- };
+ }
};
-
var imageModeCenter = function(x, y, w, h, whAreSizes) {
return {
x: x - w / 2,
y: y - h / 2,
w: w,
h: h
- };
+ }
};
-
- /**
- * Creates a WebGL program object.
- *
- * @param {String} vetexShaderSource
- * @param {String} fragmentShaderSource
- *
- * @returns {WebGLProgram} A program object
- */
- var createProgramObject = function(curContext, vetexShaderSource, fragmentShaderSource) {
- var vertexShaderObject = curContext.createShader(curContext.VERTEX_SHADER);
- curContext.shaderSource(vertexShaderObject, vetexShaderSource);
- curContext.compileShader(vertexShaderObject);
- if (!curContext.getShaderParameter(vertexShaderObject, curContext.COMPILE_STATUS)) {
- throw curContext.getShaderInfoLog(vertexShaderObject);
- }
-
- var fragmentShaderObject = curContext.createShader(curContext.FRAGMENT_SHADER);
- curContext.shaderSource(fragmentShaderObject, fragmentShaderSource);
- curContext.compileShader(fragmentShaderObject);
- if (!curContext.getShaderParameter(fragmentShaderObject, curContext.COMPILE_STATUS)) {
- throw curContext.getShaderInfoLog(fragmentShaderObject);
- }
-
- var programObject = curContext.createProgram();
- curContext.attachShader(programObject, vertexShaderObject);
- curContext.attachShader(programObject, fragmentShaderObject);
- curContext.linkProgram(programObject);
- if (!curContext.getProgramParameter(programObject, curContext.LINK_STATUS)) {
- throw "Error linking shaders.";
- }
-
- return programObject;
- };
-
- ////////////////////////////////////////////////////////////////////////////
- // 2D/3D drawing handling
- ////////////////////////////////////////////////////////////////////////////
- // Objects for shared, 2D and 3D contexts
var DrawingShared = function() {};
var Drawing2D = function() {};
var Drawing3D = function() {};
var DrawingPre = function() {};
-
- // Setup the prototype chain
- Drawing2D.prototype = new DrawingShared();
+ Drawing2D.prototype = new DrawingShared;
Drawing2D.prototype.constructor = Drawing2D;
- Drawing3D.prototype = new DrawingShared();
+ Drawing3D.prototype = new DrawingShared;
Drawing3D.prototype.constructor = Drawing3D;
- DrawingPre.prototype = new DrawingShared();
+ DrawingPre.prototype = new DrawingShared;
DrawingPre.prototype.constructor = DrawingPre;
-
- // A no-op function for when the user calls 3D functions from a 2D sketch
- // We can change this to a throw or console.error() later if we want
- DrawingShared.prototype.a3DOnlyFunction = function(){};
-
- ////////////////////////////////////////////////////////////////////////////
- // Char handling
- ////////////////////////////////////////////////////////////////////////////
+ DrawingShared.prototype.a3DOnlyFunction = nop;
var charMap = {};
-
var Char = p.Character = function(chr) {
- if (typeof chr === 'string' && chr.length === 1) {
- this.code = chr.charCodeAt(0);
- } else if (typeof chr === 'number') {
- this.code = chr;
- } else if (chr instanceof Char) {
- this.code = chr;
- } else {
- this.code = NaN;
- }
-
- return (charMap[this.code] === undef) ? charMap[this.code] = this : charMap[this.code];
+ if (typeof chr === "string" && chr.length === 1) this.code = chr.charCodeAt(0);
+ else if (typeof chr === "number") this.code = chr;
+ else if (chr instanceof Char) this.code = chr;
+ else this.code = NaN;
+ return charMap[this.code] === undef ? charMap[this.code] = this : charMap[this.code]
};
-
Char.prototype.toString = function() {
- return String.fromCharCode(this.code);
+ return String.fromCharCode(this.code)
};
-
Char.prototype.valueOf = function() {
- return this.code;
+ return this.code
};
-
- /**
- * Datatype for storing shapes. Processing can currently load and display SVG (Scalable Vector Graphics) shapes.
- * Before a shape is used, it must be loaded with the loadShape() function. The shape() function is used to draw the shape to the display window.
- * The PShape object contain a group of methods, linked below, that can operate on the shape data.
- *
The loadShape() method supports SVG files created with Inkscape and Adobe Illustrator.
- * It is not a full SVG implementation, but offers some straightforward support for handling vector data.
- *
- * @param {int} family the shape type, one of GROUP, PRIMITIVE, PATH, or GEOMETRY
- *
- * @see #shape()
- * @see #loadShape()
- * @see #shapeMode()
- */
var PShape = p.PShape = function(family) {
- this.family = family || PConstants.GROUP;
- this.visible = true;
- this.style = true;
- this.children = [];
+ this.family = family || 0;
+ this.visible = true;
+ this.style = true;
+ this.children = [];
this.nameTable = [];
- this.params = [];
- this.name = "";
- this.image = null; //type PImage
- this.matrix = null;
- this.kind = null;
- this.close = null;
- this.width = null;
- this.height = null;
- this.parent = null;
+ this.params = [];
+ this.name = "";
+ this.image = null;
+ this.matrix = null;
+ this.kind = null;
+ this.close = null;
+ this.width = null;
+ this.height = null;
+ this.parent = null
};
- /**
- * PShape methods
- * missing: findChild(), apply(), contains(), findChild(), getPrimitive(), getParams(), getVertex() , getVertexCount(),
- * getVertexCode() , getVertexCodes() , getVertexCodeCount(), getVertexX(), getVertexY(), getVertexZ()
- */
PShape.prototype = {
- /**
- * @member PShape
- * The isVisible() function returns a boolean value "true" if the image is set to be visible, "false" if not. This is modified with the setVisible() parameter.
- *
The visibility of a shape is usually controlled by whatever program created the SVG file.
- * For instance, this parameter is controlled by showing or hiding the shape in the layers palette in Adobe Illustrator.
- *
- * @return {boolean} returns "true" if the image is set to be visible, "false" if not
- */
- isVisible: function(){
- return this.visible;
+ isVisible: function() {
+ return this.visible
},
- /**
- * @member PShape
- * The setVisible() function sets the shape to be visible or invisible. This is determined by the value of the visible parameter.
- *
The visibility of a shape is usually controlled by whatever program created the SVG file.
- * For instance, this parameter is controlled by showing or hiding the shape in the layers palette in Adobe Illustrator.
- *
- * @param {boolean} visible "false" makes the shape invisible and "true" makes it visible
- */
- setVisible: function (visible){
- this.visible = visible;
+ setVisible: function(visible) {
+ this.visible = visible
},
- /**
- * @member PShape
- * The disableStyle() function disables the shape's style data and uses Processing's current styles. Styles include attributes such as colors, stroke weight, and stroke joints.
- * Overrides this shape's style information and uses PGraphics styles and colors. Identical to ignoreStyles(true). Also disables styles for all child shapes.
- */
- disableStyle: function(){
+ disableStyle: function() {
this.style = false;
- for(var i = 0, j=this.children.length; i part of the SVG document.
- */
- drawPath: function(){
+ drawPath: function() {
var i, j;
- if (this.vertices.length === 0) { return; }
+ if (this.vertices.length === 0) return;
p.beginShape();
- if (this.vertexCodes.length === 0) { // each point is a simple vertex
- if (this.vertices[0].length === 2) { // drawing 2D vertices
- for (i = 0, j = this.vertices.length; i < j; i++) {
- p.vertex(this.vertices[i][0], this.vertices[i][1]);
- }
- } else { // drawing 3D vertices
- for (i = 0, j = this.vertices.length; i < j; i++) {
- p.vertex(this.vertices[i][0],
- this.vertices[i][1],
- this.vertices[i][2]);
- }
- }
- } else { // coded set of vertices
+ if (this.vertexCodes.length === 0) if (this.vertices[0].length === 2) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1]);
+ else for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i][0], this.vertices[i][1], this.vertices[i][2]);
+ else {
var index = 0;
- if (this.vertices[0].length === 2) { // drawing a 2D path
- for (i = 0, j = this.vertexCodes.length; i < j; i++) {
- if (this.vertexCodes[i] === PConstants.VERTEX) {
- p.vertex(this.vertices[index][0], this.vertices[index][1]);
- if ( this.vertices[index]["moveTo"] === true) {
- vertArray[vertArray.length-1]["moveTo"] = true;
- } else if ( this.vertices[index]["moveTo"] === false) {
- vertArray[vertArray.length-1]["moveTo"] = false;
- }
- p.breakShape = false;
- index++;
- } else if (this.vertexCodes[i] === PConstants.BEZIER_VERTEX) {
- p.bezierVertex(this.vertices[index+0][0],
- this.vertices[index+0][1],
- this.vertices[index+1][0],
- this.vertices[index+1][1],
- this.vertices[index+2][0],
- this.vertices[index+2][1]);
- index += 3;
- } else if (this.vertexCodes[i] === PConstants.CURVE_VERTEX) {
- p.curveVertex(this.vertices[index][0],
- this.vertices[index][1]);
- index++;
- } else if (this.vertexCodes[i] === PConstants.BREAK) {
- p.breakShape = true;
- }
- }
- } else { // drawing a 3D path
- for (i = 0, j = this.vertexCodes.length; i < j; i++) {
- if (this.vertexCodes[i] === PConstants.VERTEX) {
- p.vertex(this.vertices[index][0],
- this.vertices[index][1],
- this.vertices[index][2]);
- if (this.vertices[index]["moveTo"] === true) {
- vertArray[vertArray.length-1]["moveTo"] = true;
- } else if (this.vertices[index]["moveTo"] === false) {
- vertArray[vertArray.length-1]["moveTo"] = false;
- }
- p.breakShape = false;
- } else if (this.vertexCodes[i] === PConstants.BEZIER_VERTEX) {
- p.bezierVertex(this.vertices[index+0][0],
- this.vertices[index+0][1],
- this.vertices[index+0][2],
- this.vertices[index+1][0],
- this.vertices[index+1][1],
- this.vertices[index+1][2],
- this.vertices[index+2][0],
- this.vertices[index+2][1],
- this.vertices[index+2][2]);
- index += 3;
- } else if (this.vertexCodes[i] === PConstants.CURVE_VERTEX) {
- p.curveVertex(this.vertices[index][0],
- this.vertices[index][1],
- this.vertices[index][2]);
- index++;
- } else if (this.vertexCodes[i] === PConstants.BREAK) {
- p.breakShape = true;
- }
- }
- }
+ if (this.vertices[0].length === 2) for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) {
+ p.vertex(this.vertices[index][0], this.vertices[index][1]);
+ if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true;
+ else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false;
+ p.breakShape = false;
+ index++
+ } else if (this.vertexCodes[i] === 1) {
+ p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 2][0], this.vertices[index + 2][1]);
+ index += 3
+ } else if (this.vertexCodes[i] === 2) {
+ p.curveVertex(this.vertices[index][0], this.vertices[index][1]);
+ index++
+ } else {
+ if (this.vertexCodes[i] === 3) p.breakShape = true
+ } else for (i = 0, j = this.vertexCodes.length; i < j; i++) if (this.vertexCodes[i] === 0) {
+ p.vertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]);
+ if (this.vertices[index]["moveTo"] === true) vertArray[vertArray.length - 1]["moveTo"] = true;
+ else if (this.vertices[index]["moveTo"] === false) vertArray[vertArray.length - 1]["moveTo"] = false;
+ p.breakShape = false
+ } else if (this.vertexCodes[i] === 1) {
+ p.bezierVertex(this.vertices[index + 0][0], this.vertices[index + 0][1], this.vertices[index + 0][2], this.vertices[index + 1][0], this.vertices[index + 1][1], this.vertices[index + 1][2], this.vertices[index + 2][0], this.vertices[index + 2][1], this.vertices[index + 2][2]);
+ index += 3
+ } else if (this.vertexCodes[i] === 2) {
+ p.curveVertex(this.vertices[index][0], this.vertices[index][1], this.vertices[index][2]);
+ index++
+ } else if (this.vertexCodes[i] === 3) p.breakShape = true
}
- p.endShape(this.close ? PConstants.CLOSE : PConstants.OPEN);
+ p.endShape(this.close ? 2 : 1)
},
- /**
- * @member PShape
- * The drawGeometry() function draws the geometry part of the SVG document.
- */
drawGeometry: function() {
var i, j;
p.beginShape(this.kind);
- if (this.style) {
- for (i = 0, j = this.vertices.length; i < j; i++) {
- p.vertex(this.vertices[i]);
- }
- } else {
- for (i = 0, j = this.vertices.length; i < j; i++) {
- var vert = this.vertices[i];
- if (vert[2] === 0) {
- p.vertex(vert[0], vert[1]);
- } else {
- p.vertex(vert[0], vert[1], vert[2]);
- }
- }
+ if (this.style) for (i = 0, j = this.vertices.length; i < j; i++) p.vertex(this.vertices[i]);
+ else for (i = 0, j = this.vertices.length; i < j; i++) {
+ var vert = this.vertices[i];
+ if (vert[2] === 0) p.vertex(vert[0], vert[1]);
+ else p.vertex(vert[0], vert[1], vert[2])
}
- p.endShape();
+ p.endShape()
},
- /**
- * @member PShape
- * The drawGroup() function draws the part of the SVG document.
- */
drawGroup: function() {
- for (var i = 0, j = this.children.length; i < j; i++) {
- this.children[i].draw();
- }
+ for (var i = 0, j = this.children.length; i < j; i++) this.children[i].draw()
},
- /**
- * @member PShape
- * The drawPrimitive() function draws SVG document shape elements. These can be point, line, triangle, quad, rect, ellipse, arc, box, or sphere.
- */
drawPrimitive: function() {
- if (this.kind === PConstants.POINT) {
- p.point(this.params[0], this.params[1]);
- } else if (this.kind === PConstants.LINE) {
- if (this.params.length === 4) { // 2D
- p.line(this.params[0], this.params[1],
- this.params[2], this.params[3]);
- } else { // 3D
- p.line(this.params[0], this.params[1], this.params[2],
- this.params[3], this.params[4], this.params[5]);
- }
- } else if (this.kind === PConstants.TRIANGLE) {
- p.triangle(this.params[0], this.params[1],
- this.params[2], this.params[3],
- this.params[4], this.params[5]);
- } else if (this.kind === PConstants.QUAD) {
- p.quad(this.params[0], this.params[1],
- this.params[2], this.params[3],
- this.params[4], this.params[5],
- this.params[6], this.params[7]);
- } else if (this.kind === PConstants.RECT) {
- if (this.image !== null) {
- p.imageMode(PConstants.CORNER);
- p.image(this.image,
- this.params[0],
- this.params[1],
- this.params[2],
- this.params[3]);
- } else {
- p.rectMode(PConstants.CORNER);
- p.rect(this.params[0],
- this.params[1],
- this.params[2],
- this.params[3]);
- }
- } else if (this.kind === PConstants.ELLIPSE) {
- p.ellipseMode(PConstants.CORNER);
- p.ellipse(this.params[0],
- this.params[1],
- this.params[2],
- this.params[3]);
- } else if (this.kind === PConstants.ARC) {
- p.ellipseMode(PConstants.CORNER);
- p.arc(this.params[0],
- this.params[1],
- this.params[2],
- this.params[3],
- this.params[4],
- this.params[5]);
- } else if (this.kind === PConstants.BOX) {
- if (this.params.length === 1) {
- p.box(this.params[0]);
- } else {
- p.box(this.params[0], this.params[1], this.params[2]);
- }
- } else if (this.kind === PConstants.SPHERE) {
- p.sphere(this.params[0]);
- }
+ if (this.kind === 2) p.point(this.params[0], this.params[1]);
+ else if (this.kind === 4) if (this.params.length === 4) p.line(this.params[0], this.params[1], this.params[2], this.params[3]);
+ else p.line(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]);
+ else if (this.kind === 8) p.triangle(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5]);
+ else if (this.kind === 16) p.quad(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5], this.params[6], this.params[7]);
+ else if (this.kind === 30) if (this.image !== null) {
+ p.imageMode(0);
+ p.image(this.image, this.params[0], this.params[1], this.params[2], this.params[3])
+ } else {
+ p.rectMode(0);
+ p.rect(this.params[0], this.params[1], this.params[2], this.params[3])
+ } else if (this.kind === 31) {
+ p.ellipseMode(0);
+ p.ellipse(this.params[0], this.params[1], this.params[2], this.params[3])
+ } else if (this.kind === 32) {
+ p.ellipseMode(0);
+ p.arc(this.params[0], this.params[1], this.params[2], this.params[3], this.params[4], this.params[5])
+ } else if (this.kind === 41) if (this.params.length === 1) p.box(this.params[0]);
+ else p.box(this.params[0], this.params[1], this.params[2]);
+ else if (this.kind === 40) p.sphere(this.params[0])
},
- /**
- * @member PShape
- * The pre() function performs the preparations before the SVG is drawn. This includes doing transformations and storing previous styles.
- */
pre: function() {
if (this.matrix) {
p.pushMatrix();
- curContext.transform(this.matrix.elements[0],
- this.matrix.elements[3],
- this.matrix.elements[1],
- this.matrix.elements[4],
- this.matrix.elements[2],
- this.matrix.elements[5]);
- //p.applyMatrix(this.matrix.elements[0],this.matrix.elements[0]);
+ curContext.transform(this.matrix.elements[0], this.matrix.elements[3], this.matrix.elements[1], this.matrix.elements[4], this.matrix.elements[2], this.matrix.elements[5])
}
if (this.style) {
p.pushStyle();
- this.styles();
+ this.styles()
}
},
- /**
- * @member PShape
- * The post() function performs the necessary actions after the SVG is drawn. This includes removing transformations and removing added styles.
- */
post: function() {
- if (this.matrix) {
- p.popMatrix();
- }
- if (this.style) {
- p.popStyle();
- }
+ if (this.matrix) p.popMatrix();
+ if (this.style) p.popStyle()
},
- /**
- * @member PShape
- * The styles() function changes the Processing's current styles
- */
styles: function() {
if (this.stroke) {
p.stroke(this.strokeColor);
p.strokeWeight(this.strokeWeight);
p.strokeCap(this.strokeCap);
- p.strokeJoin(this.strokeJoin);
- } else {
- p.noStroke();
- }
-
- if (this.fill) {
- p.fill(this.fillColor);
-
- } else {
- p.noFill();
- }
+ p.strokeJoin(this.strokeJoin)
+ } else p.noStroke();
+ if (this.fill) p.fill(this.fillColor);
+ else p.noFill()
},
- /**
- * @member PShape
- * The getChild() function extracts a child shape from a parent shape. Specify the name of the shape with the target parameter or the
- * layer position of the shape to get with the index parameter.
- * The shape is returned as a PShape object, or null is returned if there is an error.
- *
- * @param {String} target the name of the shape to get
- * @param {int} index the layer position of the shape to get
- *
- * @return {PShape} returns a child element of a shape as a PShape object or null if there is an error
- */
getChild: function(child) {
var i, j;
- if (typeof child === 'number') {
- return this.children[child];
- } else {
- var found;
- if(child === "" || this.name === child){
- return this;
- } else {
- if(this.nameTable.length > 0) {
- for(i = 0, j = this.nameTable.length; i < j || found; i++) {
- if(this.nameTable[i].getName === child) {
- found = this.nameTable[i];
- }
- }
- if (found) { return found; }
- }
- for(i = 0, j = this.children.length; i < j; i++) {
- found = this.children[i].getChild(child);
- if(found) { return found; }
- }
+ if (typeof child === "number") return this.children[child];
+ var found;
+ if (child === "" || this.name === child) return this;
+ if (this.nameTable.length > 0) {
+ for (i = 0, j = this.nameTable.length; i < j || found; i++) if (this.nameTable[i].getName === child) {
+ found = this.nameTable[i];
+ break
}
- return null;
+ if (found) return found
}
+ for (i = 0, j = this.children.length; i < j; i++) {
+ found = this.children[i].getChild(child);
+ if (found) return found
+ }
+ return null
},
- /**
- * @member PShape
- * The getChildCount() returns the number of children
- *
- * @return {int} returns a count of children
- */
- getChildCount: function () {
- return this.children.length;
+ getChildCount: function() {
+ return this.children.length
},
- /**
- * @member PShape
- * The addChild() adds a child to the PShape.
- *
- * @param {PShape} child the child to add
- */
- addChild: function( child ) {
+ addChild: function(child) {
this.children.push(child);
child.parent = this;
- if (child.getName() !== null) {
- this.addName(child.getName(), child);
- }
+ if (child.getName() !== null) this.addName(child.getName(), child)
},
- /**
- * @member PShape
- * The addName() functions adds a shape to the name lookup table.
- *
- * @param {String} name the name to be added
- * @param {PShape} shape the shape
- */
- addName: function(name, shape) {
- if (this.parent !== null) {
- this.parent.addName( name, shape );
- } else {
- this.nameTable.push( [name, shape] );
- }
+ addName: function(name, shape) {
+ if (this.parent !== null) this.parent.addName(name, shape);
+ else this.nameTable.push([name, shape])
},
- /**
- * @member PShape
- * The translate() function specifies an amount to displace the shape. The x parameter specifies left/right translation, the y parameter specifies up/down translation, and the z parameter specifies translations toward/away from the screen.
- * Subsequent calls to the method accumulates the effect. For example, calling translate(50, 0) and then translate(20, 0) is the same as translate(70, 0).
- * This transformation is applied directly to the shape, it's not refreshed each time draw() is run.
- *
Using this method with the z parameter requires using the P3D or OPENGL parameter in combination with size.
- *
- * @param {int|float} x left/right translation
- * @param {int|float} y up/down translation
- * @param {int|float} z forward/back translation
- *
- * @see PMatrix2D#translate
- * @see PMatrix3D#translate
- */
translate: function() {
- if(arguments.length === 2)
- {
+ if (arguments.length === 2) {
this.checkMatrix(2);
- this.matrix.translate(arguments[0], arguments[1]);
+ this.matrix.translate(arguments[0], arguments[1])
} else {
this.checkMatrix(3);
- this.matrix.translate(arguments[0], arguments[1], 0);
+ this.matrix.translate(arguments[0], arguments[1], 0)
}
},
- /**
- * @member PShape
- * The checkMatrix() function makes sure that the shape's matrix is 1) not null, and 2) has a matrix
- * that can handle at least the specified number of dimensions.
- *
- * @param {int} dimensions the specified number of dimensions
- */
checkMatrix: function(dimensions) {
- if(this.matrix === null) {
- if(dimensions === 2) {
- this.matrix = new p.PMatrix2D();
- } else {
- this.matrix = new p.PMatrix3D();
- }
- }else if(dimensions === 3 && this.matrix instanceof p.PMatrix2D) {
- this.matrix = new p.PMatrix3D();
- }
+ if (this.matrix === null) if (dimensions === 2) this.matrix = new p.PMatrix2D;
+ else this.matrix = new p.PMatrix3D;
+ else if (dimensions === 3 && this.matrix instanceof p.PMatrix2D) this.matrix = new p.PMatrix3D
},
- /**
- * @member PShape
- * The rotateX() function rotates a shape around the x-axis the amount specified by the angle parameter. Angles should be specified in radians (values from 0 to TWO_PI) or converted to radians with the radians() method.
- *
Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction.
- * Subsequent calls to the method accumulates the effect. For example, calling rotateX(HALF_PI) and then rotateX(HALF_PI) is the same as rotateX(PI).
- * This transformation is applied directly to the shape, it's not refreshed each time draw() is run.
- *
This method requires a 3D renderer. You need to pass P3D or OPENGL as a third parameter into the size() method as shown in the example above.
- *
- * @param {float}angle angle of rotation specified in radians
- *
- * @see PMatrix3D#rotateX
- */
rotateX: function(angle) {
- this.rotate(angle, 1, 0, 0);
+ this.rotate(angle, 1, 0, 0)
},
- /**
- * @member PShape
- * The rotateY() function rotates a shape around the y-axis the amount specified by the angle parameter. Angles should be specified in radians (values from 0 to TWO_PI) or converted to radians with the radians() method.
- *
Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction.
- * Subsequent calls to the method accumulates the effect. For example, calling rotateY(HALF_PI) and then rotateY(HALF_PI) is the same as rotateY(PI).
- * This transformation is applied directly to the shape, it's not refreshed each time draw() is run.
- *
This method requires a 3D renderer. You need to pass P3D or OPENGL as a third parameter into the size() method as shown in the example above.
- *
- * @param {float}angle angle of rotation specified in radians
- *
- * @see PMatrix3D#rotateY
- */
rotateY: function(angle) {
- this.rotate(angle, 0, 1, 0);
+ this.rotate(angle, 0, 1, 0)
},
- /**
- * @member PShape
- * The rotateZ() function rotates a shape around the z-axis the amount specified by the angle parameter. Angles should be specified in radians (values from 0 to TWO_PI) or converted to radians with the radians() method.
- *
Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction.
- * Subsequent calls to the method accumulates the effect. For example, calling rotateZ(HALF_PI) and then rotateZ(HALF_PI) is the same as rotateZ(PI).
- * This transformation is applied directly to the shape, it's not refreshed each time draw() is run.
- *
This method requires a 3D renderer. You need to pass P3D or OPENGL as a third parameter into the size() method as shown in the example above.
- *
- * @param {float}angle angle of rotation specified in radians
- *
- * @see PMatrix3D#rotateZ
- */
rotateZ: function(angle) {
- this.rotate(angle, 0, 0, 1);
+ this.rotate(angle, 0, 0, 1)
},
- /**
- * @member PShape
- * The rotate() function rotates a shape the amount specified by the angle parameter. Angles should be specified in radians (values from 0 to TWO_PI) or converted to radians with the radians() method.
- *
Shapes are always rotated around the upper-left corner of their bounding box. Positive numbers rotate objects in a clockwise direction.
- * Transformations apply to everything that happens after and subsequent calls to the method accumulates the effect.
- * For example, calling rotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).
- * This transformation is applied directly to the shape, it's not refreshed each time draw() is run.
- * If optional parameters x,y,z are supplied, the rotate is about the point (x, y, z).
- *
- * @param {float}angle angle of rotation specified in radians
- * @param {float}x x-coordinate of the point
- * @param {float}y y-coordinate of the point
- * @param {float}z z-coordinate of the point
- * @see PMatrix2D#rotate
- * @see PMatrix3D#rotate
- */
rotate: function() {
- if(arguments.length === 1){
+ if (arguments.length === 1) {
this.checkMatrix(2);
- this.matrix.rotate(arguments[0]);
+ this.matrix.rotate(arguments[0])
} else {
this.checkMatrix(3);
- this.matrix.rotate(arguments[0],
- arguments[1],
- arguments[2],
- arguments[3]);
+ this.matrix.rotate(arguments[0], arguments[1], arguments[2], arguments[3])
}
},
- /**
- * @member PShape
- * The scale() function increases or decreases the size of a shape by expanding and contracting vertices. Shapes always scale from the relative origin of their bounding box.
- * Scale values are specified as decimal percentages. For example, the method call scale(2.0) increases the dimension of a shape by 200%.
- * Subsequent calls to the method multiply the effect. For example, calling scale(2.0) and then scale(1.5) is the same as scale(3.0).
- * This transformation is applied directly to the shape, it's not refreshed each time draw() is run.
- *
Using this fuction with the z parameter requires passing P3D or OPENGL into the size() parameter.
- *
- * @param {float}s percentage to scale the object
- * @param {float}x percentage to scale the object in the x-axis
- * @param {float}y percentage to scale the object in the y-axis
- * @param {float}z percentage to scale the object in the z-axis
- *
- * @see PMatrix2D#scale
- * @see PMatrix3D#scale
- */
scale: function() {
- if(arguments.length === 2) {
+ if (arguments.length === 2) {
this.checkMatrix(2);
- this.matrix.scale(arguments[0], arguments[1]);
+ this.matrix.scale(arguments[0], arguments[1])
} else if (arguments.length === 3) {
this.checkMatrix(2);
- this.matrix.scale(arguments[0], arguments[1], arguments[2]);
+ this.matrix.scale(arguments[0], arguments[1], arguments[2])
} else {
this.checkMatrix(2);
- this.matrix.scale(arguments[0]);
+ this.matrix.scale(arguments[0])
}
},
- /**
- * @member PShape
- * The resetMatrix() function resets the matrix
- *
- * @see PMatrix2D#reset
- * @see PMatrix3D#reset
- */
resetMatrix: function() {
this.checkMatrix(2);
- this.matrix.reset();
+ this.matrix.reset()
},
- /**
- * @member PShape
- * The applyMatrix() function multiplies this matrix by another matrix of type PMatrix3D or PMatrix2D.
- * Individual elements can also be provided
- *
- * @param {PMatrix3D|PMatrix2D} matrix the matrix to multiply by
- *
- * @see PMatrix2D#apply
- * @see PMatrix3D#apply
- */
applyMatrix: function(matrix) {
- if (arguments.length === 1) {
- this.applyMatrix(matrix.elements[0],
- matrix.elements[1], 0,
- matrix.elements[2],
- matrix.elements[3],
- matrix.elements[4], 0,
- matrix.elements[5],
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- } else if (arguments.length === 6) {
+ if (arguments.length === 1) this.applyMatrix(matrix.elements[0], matrix.elements[1], 0, matrix.elements[2], matrix.elements[3], matrix.elements[4], 0, matrix.elements[5], 0, 0, 1, 0, 0, 0, 0, 1);
+ else if (arguments.length === 6) {
this.checkMatrix(2);
- this.matrix.apply(arguments[0], arguments[1], arguments[2], 0,
- arguments[3], arguments[4], arguments[5], 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
-
+ this.matrix.apply(arguments[0], arguments[1], arguments[2], 0, arguments[3], arguments[4], arguments[5], 0, 0, 0, 1, 0, 0, 0, 0, 1)
} else if (arguments.length === 16) {
this.checkMatrix(3);
- this.matrix.apply(arguments[0],
- arguments[1],
- arguments[2],
- arguments[3],
- arguments[4],
- arguments[5],
- arguments[6],
- arguments[7],
- arguments[8],
- arguments[9],
- arguments[10],
- arguments[11],
- arguments[12],
- arguments[13],
- arguments[14],
- arguments[15]);
+ this.matrix.apply(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8], arguments[9], arguments[10], arguments[11], arguments[12], arguments[13], arguments[14], arguments[15])
}
}
};
-
- /**
- * SVG stands for Scalable Vector Graphics, a portable graphics format. It is
- * a vector format so it allows for infinite resolution and relatively small
- * file sizes. Most modern media software can view SVG files, including Adobe
- * products, Firefox, etc. Illustrator and Inkscape can edit SVG files.
- *
- * @param {PApplet} parent typically use "this"
- * @param {String} filename name of the SVG file to load
- * @param {XMLElement} xml an XMLElement element
- * @param {PShapeSVG} parent the parent PShapeSVG
- *
- * @see PShape
- */
var PShapeSVG = p.PShapeSVG = function() {
- p.PShape.call( this ); // PShape is the base class.
- if (arguments.length === 1) { //xml element coming in
- this.element = arguments[0] ;//new p.XMLElement(null, arguments[0]);
- // set values to their defaults according to the SVG spec
- this.vertexCodes = [];
- this.vertices = [];
- this.opacity = 1;
-
- this.stroke = false;
- this.strokeColor = PConstants.ALPHA_MASK;
- this.strokeWeight = 1;
- this.strokeCap = PConstants.SQUARE; // BUTT in svg spec
- this.strokeJoin = PConstants.MITER;
- this.strokeGradient = null;
+ p.PShape.call(this);
+ if (arguments.length === 1) {
+ this.element = arguments[0];
+ this.vertexCodes = [];
+ this.vertices = [];
+ this.opacity = 1;
+ this.stroke = false;
+ this.strokeColor = 4278190080;
+ this.strokeWeight = 1;
+ this.strokeCap = 'butt';
+ this.strokeJoin = 'miter';
+ this.strokeGradient = null;
this.strokeGradientPaint = null;
- this.strokeName = null;
- this.strokeOpacity = 1;
-
- this.fill = true;
- this.fillColor = PConstants.ALPHA_MASK;
- this.fillGradient = null;
- this.fillGradientPaint = null;
- this.fillName = null;
- this.fillOpacity = 1;
-
- if (this.element.getName() !== "svg") {
- throw("root is not