From 8c3a53dc9d6cead4043c8beff8c82a3f9f66675b Mon Sep 17 00:00:00 2001 From: Eric Rowell Date: Sun, 1 Sep 2013 01:13:52 -0700 Subject: [PATCH] started working on context tracing. Added first context trace unit test --- src/Context.js | 91 ++++++++++++++--- src/Global.js | 223 +++++++++++++++++++++-------------------- src/Shape.js | 4 +- src/shapes/Rect.js | 2 +- test/runner.html | 9 +- test/unit/Rect-test.js | 41 ++++++++ 6 files changed, 243 insertions(+), 127 deletions(-) create mode 100644 test/unit/Rect-test.js diff --git a/src/Context.js b/src/Context.js index ca964648..b17f3700 100644 --- a/src/Context.js +++ b/src/Context.js @@ -1,4 +1,11 @@ (function() { + var COMMA = ',', + OPEN_PAREN = '(', + CLOSE_PAREN = ')', + EMPTY_STRING = '', + CONTEXT_METHODS = ['clearRect', 'rect', 'restore', 'save', 'setTransform', 'transform'], + CONTEXT_PROPERTIES = ['fillStyle', 'lineWidth', 'strokeStyle']; + /** * Canvas Context constructor * @constructor @@ -13,6 +20,22 @@ init: function(canvas) { this.canvas = canvas; this._context = canvas._canvas.getContext('2d'); + + if (Kinetic.enableTrace) { + this.traceArr = []; + this._enableTrace(); + } + }, + _trace: function(str) { + var traceArr = this.traceArr, + len; + + traceArr.push(str); + len = traceArr.length; + + if (len >= Kinetic.traceArrMax) { + traceArr.shift(); + } }, /** * reset canvas context transform @@ -21,7 +44,7 @@ */ reset: function() { var pixelRatio = this.getCanvas().getPixelRatio(); - this._context.setTransform(1 * pixelRatio, 0, 0, 1 * pixelRatio, 0, 0); + this.setTransform(1 * pixelRatio, 0, 0, 1 * pixelRatio, 0, 0); }, getCanvas: function() { return this.canvas; @@ -32,17 +55,16 @@ * @memberof Kinetic.Context.prototype */ clear: function(clip) { - var _context = this._context, - canvas = this.getCanvas(), + var canvas = this.getCanvas(), pos, size; if (clip) { pos = Kinetic.Util._getXY(clip); size = Kinetic.Util._getSize(clip); - _context.clearRect(pos.x || 0, pos.y || 0, size.width, size.height); + this.clearRect(pos.x || 0, pos.y || 0, size.width, size.height); } else { - _context.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); + this.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); } }, /** @@ -93,11 +115,10 @@ * @param {Function} drawFunc */ applyShadow: function(shape, drawFunc) { - var _context = this._context; - _context.save(); + context.save(); this._applyShadow(shape); drawFunc(); - _context.restore(); + context.restore(); drawFunc(); }, _applyLineCap: function(shape) { @@ -120,7 +141,7 @@ }, _applyAncestorTransforms: function(shape) { var m = shape.getAbsoluteTransform().getMatrix(); - this._context.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + this.transform(m[0], m[1], m[2], m[3], m[4], m[5]); }, _clip: function(container) { var _context = this._context, @@ -129,14 +150,59 @@ clipWidth = container.getClipWidth(), clipHeight = container.getClipHeight(); - _context.save(); + this.save(); this._applyAncestorTransforms(container); _context.beginPath(); - _context.rect(clipX, clipY, clipWidth, clipHeight); + this.rect(clipX, clipY, clipWidth, clipHeight); _context.clip(); this.reset(); container._drawChildren(this.getCanvas()); - _context.restore(); + this.restore(); + }, + // context pass through methods + clearRect: function(x, y, width, height) { + this._context.clearRect(x, y, width, height); + }, + rect: function(x, y, width, height) { + this._context.rect(x, y, width, height); + }, + restore: function() { + this._context.restore(); + }, + save: function() { + this._context.save(); + }, + setTransform: function(a, b, c, d, e, f) { + this._context.setTransform(a, b, c, d, e, f); + }, + transform: function(a, b, c, d, e, f) { + this._context.transform(a, b, c, d, e, f); + }, + _enableTrace: function() { + var that = this, + len = CONTEXT_METHODS.length, + n; + + // methods + for (n=0; n + * x: 5,
+ * y: 10,
+ * fill: 'red',
+ * // a Kinetic.Canvas renderer is passed into the drawFunc function
+ * drawFunc: function(canvas) {
+ * var context = canvas.getContext();
+ * context.beginPath();
+ * context.moveTo(200, 50);
+ * context.lineTo(420, 80);
+ * context.quadraticCurveTo(300, 100, 260, 170);
+ * context.closePath();
+ * canvas.fillStroke(this);
+ * }
+ *}); + */ + Shape: function(config) { + this.__init(config); + }, - /** - * Shape constructor. Shapes are primitive objects such as rectangles, - * circles, text, lines, etc. - * @constructor - * @memberof Kinetic - * @augments Kinetic.Node - * @param {Object} config - * @@shapeParams - * @@nodeParams - * @example - * var customShape = new Kinetic.Shape({
- * x: 5,
- * y: 10,
- * fill: 'red',
- * // a Kinetic.Canvas renderer is passed into the drawFunc function
- * drawFunc: function(canvas) {
- * var context = canvas.getContext();
- * context.beginPath();
- * context.moveTo(200, 50);
- * context.lineTo(420, 80);
- * context.quadraticCurveTo(300, 100, 260, 170);
- * context.closePath();
- * canvas.fillStroke(this);
- * }
- *}); - */ - Kinetic.Shape = function(config) { - this.__init(config); - }; + /** + * Container constructor.  Containers are used to contain nodes or other containers + * @constructor + * @memberof Kinetic + * @augments Kinetic.Node + * @abstract + * @param {Object} config + * @@nodeParams + * @@containerParams + */ + Container: function(config) { + this.__init(config); + }, - /** - * Container constructor.  Containers are used to contain nodes or other containers - * @constructor - * @memberof Kinetic - * @augments Kinetic.Node - * @abstract - * @param {Object} config - * @@nodeParams - * @@containerParams - */ - Kinetic.Container = function(config) { - this.__init(config); - }; + /** + * Stage constructor. A stage is used to contain multiple layers + * @constructor + * @memberof Kinetic + * @augments Kinetic.Container + * @param {Object} config + * @param {String|DomElement} config.container Container id or DOM element + * @@nodeParams + * @@containerParams + * @example + * var stage = new Kinetic.Stage({
+ * width: 500,
+ * height: 800,
+ * container: 'containerId'
+ * }); + */ + Stage: function(config) { + this.___init(config); + }, - /** - * Stage constructor. A stage is used to contain multiple layers - * @constructor - * @memberof Kinetic - * @augments Kinetic.Container - * @param {Object} config - * @param {String|DomElement} config.container Container id or DOM element - * @@nodeParams - * @@containerParams - * @example - * var stage = new Kinetic.Stage({
- * width: 500,
- * height: 800,
- * container: 'containerId'
- * }); - */ - Kinetic.Stage = function(config) { - this.___init(config); - }; + /** + * Layer constructor. Layers are tied to their own canvas element and are used + * to contain groups or shapes + * @constructor + * @memberof Kinetic + * @augments Kinetic.Container + * @param {Object} config + * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want + * to clear the canvas before each layer draw. The default value is true. + * @@nodeParams + * @@containerParams + * @example + * var layer = new Kinetic.Layer(); + */ + Layer: function(config) { + this.___init(config); + }, - /** - * Layer constructor. Layers are tied to their own canvas element and are used - * to contain groups or shapes - * @constructor - * @memberof Kinetic - * @augments Kinetic.Container - * @param {Object} config - * @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want - * to clear the canvas before each layer draw. The default value is true. - * @@nodeParams - * @@containerParams - * @example - * var layer = new Kinetic.Layer(); - */ - Kinetic.Layer = function(config) { - this.___init(config); - }; - - /** - * Group constructor. Groups are used to contain shapes or other groups. - * @constructor - * @memberof Kinetic - * @augments Kinetic.Container - * @param {Object} config - * @@nodeParams - * @@containerParams - * @example - * var group = new Kinetic.Group(); - */ - Kinetic.Group = function(config) { - this.___init(config); + /** + * Group constructor. Groups are used to contain shapes or other groups. + * @constructor + * @memberof Kinetic + * @augments Kinetic.Container + * @param {Object} config + * @@nodeParams + * @@containerParams + * @example + * var group = new Kinetic.Group(); + */ + Group: function(config) { + this.___init(config); + } }; /** diff --git a/src/Shape.js b/src/Shape.js index 81cd308d..5eb1f4bf 100644 --- a/src/Shape.js +++ b/src/Shape.js @@ -215,12 +215,12 @@ context = canvas.getContext(); if(drawFunc && this.isVisible()) { - context._context.save(); + context.save(); context._applyOpacity(this); context._applyLineJoin(this); context._applyAncestorTransforms(this); drawFunc.call(this, context); - context._context.restore(); + context.restore(); } return this; }, diff --git a/src/shapes/Rect.js b/src/shapes/Rect.js index 59825bdf..623698d5 100644 --- a/src/shapes/Rect.js +++ b/src/shapes/Rect.js @@ -36,7 +36,7 @@ if(!cornerRadius) { // simple rect - don't bother doing all that complicated maths stuff. - _context.rect(0, 0, width, height); + context.rect(0, 0, width, height); } else { // arcTo would be nicer, but browser support is patchy (Opera) diff --git a/test/runner.html b/test/runner.html index 3fe5a9a7..a20ae623 100644 --- a/test/runner.html +++ b/test/runner.html @@ -1,19 +1,26 @@ - Mocha Tests + KineticJS Mocha Tests
+ + +
+ +