mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
started working on context tracing. Added first context trace unit test
This commit is contained in:
parent
f144c67264
commit
8c3a53dc9d
@ -1,4 +1,11 @@
|
|||||||
(function() {
|
(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
|
* Canvas Context constructor
|
||||||
* @constructor
|
* @constructor
|
||||||
@ -13,6 +20,22 @@
|
|||||||
init: function(canvas) {
|
init: function(canvas) {
|
||||||
this.canvas = canvas;
|
this.canvas = canvas;
|
||||||
this._context = canvas._canvas.getContext('2d');
|
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
|
* reset canvas context transform
|
||||||
@ -21,7 +44,7 @@
|
|||||||
*/
|
*/
|
||||||
reset: function() {
|
reset: function() {
|
||||||
var pixelRatio = this.getCanvas().getPixelRatio();
|
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() {
|
getCanvas: function() {
|
||||||
return this.canvas;
|
return this.canvas;
|
||||||
@ -32,17 +55,16 @@
|
|||||||
* @memberof Kinetic.Context.prototype
|
* @memberof Kinetic.Context.prototype
|
||||||
*/
|
*/
|
||||||
clear: function(clip) {
|
clear: function(clip) {
|
||||||
var _context = this._context,
|
var canvas = this.getCanvas(),
|
||||||
canvas = this.getCanvas(),
|
|
||||||
pos, size;
|
pos, size;
|
||||||
|
|
||||||
if (clip) {
|
if (clip) {
|
||||||
pos = Kinetic.Util._getXY(clip);
|
pos = Kinetic.Util._getXY(clip);
|
||||||
size = Kinetic.Util._getSize(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 {
|
else {
|
||||||
_context.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
|
this.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -93,11 +115,10 @@
|
|||||||
* @param {Function} drawFunc
|
* @param {Function} drawFunc
|
||||||
*/
|
*/
|
||||||
applyShadow: function(shape, drawFunc) {
|
applyShadow: function(shape, drawFunc) {
|
||||||
var _context = this._context;
|
context.save();
|
||||||
_context.save();
|
|
||||||
this._applyShadow(shape);
|
this._applyShadow(shape);
|
||||||
drawFunc();
|
drawFunc();
|
||||||
_context.restore();
|
context.restore();
|
||||||
drawFunc();
|
drawFunc();
|
||||||
},
|
},
|
||||||
_applyLineCap: function(shape) {
|
_applyLineCap: function(shape) {
|
||||||
@ -120,7 +141,7 @@
|
|||||||
},
|
},
|
||||||
_applyAncestorTransforms: function(shape) {
|
_applyAncestorTransforms: function(shape) {
|
||||||
var m = shape.getAbsoluteTransform().getMatrix();
|
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) {
|
_clip: function(container) {
|
||||||
var _context = this._context,
|
var _context = this._context,
|
||||||
@ -129,14 +150,59 @@
|
|||||||
clipWidth = container.getClipWidth(),
|
clipWidth = container.getClipWidth(),
|
||||||
clipHeight = container.getClipHeight();
|
clipHeight = container.getClipHeight();
|
||||||
|
|
||||||
_context.save();
|
this.save();
|
||||||
this._applyAncestorTransforms(container);
|
this._applyAncestorTransforms(container);
|
||||||
_context.beginPath();
|
_context.beginPath();
|
||||||
_context.rect(clipX, clipY, clipWidth, clipHeight);
|
this.rect(clipX, clipY, clipWidth, clipHeight);
|
||||||
_context.clip();
|
_context.clip();
|
||||||
this.reset();
|
this.reset();
|
||||||
container._drawChildren(this.getCanvas());
|
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<len; n++) {
|
||||||
|
(function(contextMethod) {
|
||||||
|
var method = that[contextMethod],
|
||||||
|
args;
|
||||||
|
|
||||||
|
that[contextMethod] = function() {
|
||||||
|
args = Array.prototype.slice.call(arguments, 0);
|
||||||
|
method.apply(that, arguments);
|
||||||
|
that._trace(contextMethod + OPEN_PAREN + args.join(COMMA) + CLOSE_PAREN);
|
||||||
|
};
|
||||||
|
})(CONTEXT_METHODS[n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// properties
|
||||||
|
len = CONTEXT_PROPERTIES.length;
|
||||||
|
|
||||||
|
for (n=0; n<len; n++) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -346,5 +412,4 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
Kinetic.Util.extend(Kinetic.HitContext, Kinetic.Context);
|
Kinetic.Util.extend(Kinetic.HitContext, Kinetic.Context);
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
223
src/Global.js
223
src/Global.js
@ -30,122 +30,125 @@
|
|||||||
*/
|
*/
|
||||||
var Kinetic = {};
|
var Kinetic = {};
|
||||||
(function() {
|
(function() {
|
||||||
Kinetic.version = '@@version';
|
Kinetic = {
|
||||||
|
version: '@@version',
|
||||||
|
enableTrace: false,
|
||||||
|
traceArrMax: 100,
|
||||||
|
/**
|
||||||
|
* @namespace Filters
|
||||||
|
* @memberof Kinetic
|
||||||
|
*/
|
||||||
|
Filters: {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @namespace Filters
|
* Node constructor. Nodes are entities that can be transformed, layered,
|
||||||
* @memberof Kinetic
|
* and have bound events. The stage, layers, groups, and shapes all extend Node.
|
||||||
*/
|
* @constructor
|
||||||
Kinetic.Filters = {};
|
* @memberof Kinetic
|
||||||
|
* @abstract
|
||||||
|
* @param {Object} config
|
||||||
|
* @@nodeParams
|
||||||
|
*/
|
||||||
|
Node: function(config) {
|
||||||
|
this._init(config);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node constructor. Nodes are entities that can be transformed, layered,
|
* Shape constructor. Shapes are primitive objects such as rectangles,
|
||||||
* and have bound events. The stage, layers, groups, and shapes all extend Node.
|
* circles, text, lines, etc.
|
||||||
* @constructor
|
* @constructor
|
||||||
* @memberof Kinetic
|
* @memberof Kinetic
|
||||||
* @abstract
|
* @augments Kinetic.Node
|
||||||
* @param {Object} config
|
* @param {Object} config
|
||||||
* @@nodeParams
|
* @@shapeParams
|
||||||
*/
|
* @@nodeParams
|
||||||
Kinetic.Node = function(config) {
|
* @example
|
||||||
this._init(config);
|
* var customShape = new Kinetic.Shape({<br>
|
||||||
};
|
* x: 5,<br>
|
||||||
|
* y: 10,<br>
|
||||||
|
* fill: 'red',<br>
|
||||||
|
* // a Kinetic.Canvas renderer is passed into the drawFunc function<br>
|
||||||
|
* drawFunc: function(canvas) {<br>
|
||||||
|
* var context = canvas.getContext();<br>
|
||||||
|
* context.beginPath();<br>
|
||||||
|
* context.moveTo(200, 50);<br>
|
||||||
|
* context.lineTo(420, 80);<br>
|
||||||
|
* context.quadraticCurveTo(300, 100, 260, 170);<br>
|
||||||
|
* context.closePath();<br>
|
||||||
|
* canvas.fillStroke(this);<br>
|
||||||
|
* }<br>
|
||||||
|
*});
|
||||||
|
*/
|
||||||
|
Shape: function(config) {
|
||||||
|
this.__init(config);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shape constructor. Shapes are primitive objects such as rectangles,
|
* Container constructor. Containers are used to contain nodes or other containers
|
||||||
* circles, text, lines, etc.
|
* @constructor
|
||||||
* @constructor
|
* @memberof Kinetic
|
||||||
* @memberof Kinetic
|
* @augments Kinetic.Node
|
||||||
* @augments Kinetic.Node
|
* @abstract
|
||||||
* @param {Object} config
|
* @param {Object} config
|
||||||
* @@shapeParams
|
* @@nodeParams
|
||||||
* @@nodeParams
|
* @@containerParams
|
||||||
* @example
|
*/
|
||||||
* var customShape = new Kinetic.Shape({<br>
|
Container: function(config) {
|
||||||
* x: 5,<br>
|
this.__init(config);
|
||||||
* y: 10,<br>
|
},
|
||||||
* fill: 'red',<br>
|
|
||||||
* // a Kinetic.Canvas renderer is passed into the drawFunc function<br>
|
|
||||||
* drawFunc: function(canvas) {<br>
|
|
||||||
* var context = canvas.getContext();<br>
|
|
||||||
* context.beginPath();<br>
|
|
||||||
* context.moveTo(200, 50);<br>
|
|
||||||
* context.lineTo(420, 80);<br>
|
|
||||||
* context.quadraticCurveTo(300, 100, 260, 170);<br>
|
|
||||||
* context.closePath();<br>
|
|
||||||
* canvas.fillStroke(this);<br>
|
|
||||||
* }<br>
|
|
||||||
*});
|
|
||||||
*/
|
|
||||||
Kinetic.Shape = function(config) {
|
|
||||||
this.__init(config);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container constructor. Containers are used to contain nodes or other containers
|
* Stage constructor. A stage is used to contain multiple layers
|
||||||
* @constructor
|
* @constructor
|
||||||
* @memberof Kinetic
|
* @memberof Kinetic
|
||||||
* @augments Kinetic.Node
|
* @augments Kinetic.Container
|
||||||
* @abstract
|
* @param {Object} config
|
||||||
* @param {Object} config
|
* @param {String|DomElement} config.container Container id or DOM element
|
||||||
* @@nodeParams
|
* @@nodeParams
|
||||||
* @@containerParams
|
* @@containerParams
|
||||||
*/
|
* @example
|
||||||
Kinetic.Container = function(config) {
|
* var stage = new Kinetic.Stage({<br>
|
||||||
this.__init(config);
|
* width: 500,<br>
|
||||||
};
|
* height: 800,<br>
|
||||||
|
* container: 'containerId'<br>
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
Stage: function(config) {
|
||||||
|
this.___init(config);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stage constructor. A stage is used to contain multiple layers
|
* Layer constructor. Layers are tied to their own canvas element and are used
|
||||||
* @constructor
|
* to contain groups or shapes
|
||||||
* @memberof Kinetic
|
* @constructor
|
||||||
* @augments Kinetic.Container
|
* @memberof Kinetic
|
||||||
* @param {Object} config
|
* @augments Kinetic.Container
|
||||||
* @param {String|DomElement} config.container Container id or DOM element
|
* @param {Object} config
|
||||||
* @@nodeParams
|
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
|
||||||
* @@containerParams
|
* to clear the canvas before each layer draw. The default value is true.
|
||||||
* @example
|
* @@nodeParams
|
||||||
* var stage = new Kinetic.Stage({<br>
|
* @@containerParams
|
||||||
* width: 500,<br>
|
* @example
|
||||||
* height: 800,<br>
|
* var layer = new Kinetic.Layer();
|
||||||
* container: 'containerId'<br>
|
*/
|
||||||
* });
|
Layer: function(config) {
|
||||||
*/
|
this.___init(config);
|
||||||
Kinetic.Stage = function(config) {
|
},
|
||||||
this.___init(config);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Layer constructor. Layers are tied to their own canvas element and are used
|
* Group constructor. Groups are used to contain shapes or other groups.
|
||||||
* to contain groups or shapes
|
* @constructor
|
||||||
* @constructor
|
* @memberof Kinetic
|
||||||
* @memberof Kinetic
|
* @augments Kinetic.Container
|
||||||
* @augments Kinetic.Container
|
* @param {Object} config
|
||||||
* @param {Object} config
|
* @@nodeParams
|
||||||
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
|
* @@containerParams
|
||||||
* to clear the canvas before each layer draw. The default value is true.
|
* @example
|
||||||
* @@nodeParams
|
* var group = new Kinetic.Group();
|
||||||
* @@containerParams
|
*/
|
||||||
* @example
|
Group: function(config) {
|
||||||
* var layer = new Kinetic.Layer();
|
this.___init(config);
|
||||||
*/
|
}
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -215,12 +215,12 @@
|
|||||||
context = canvas.getContext();
|
context = canvas.getContext();
|
||||||
|
|
||||||
if(drawFunc && this.isVisible()) {
|
if(drawFunc && this.isVisible()) {
|
||||||
context._context.save();
|
context.save();
|
||||||
context._applyOpacity(this);
|
context._applyOpacity(this);
|
||||||
context._applyLineJoin(this);
|
context._applyLineJoin(this);
|
||||||
context._applyAncestorTransforms(this);
|
context._applyAncestorTransforms(this);
|
||||||
drawFunc.call(this, context);
|
drawFunc.call(this, context);
|
||||||
context._context.restore();
|
context.restore();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
if(!cornerRadius) {
|
if(!cornerRadius) {
|
||||||
// simple rect - don't bother doing all that complicated maths stuff.
|
// simple rect - don't bother doing all that complicated maths stuff.
|
||||||
_context.rect(0, 0, width, height);
|
context.rect(0, 0, width, height);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// arcTo would be nicer, but browser support is patchy (Opera)
|
// arcTo would be nicer, but browser support is patchy (Opera)
|
||||||
|
@ -1,19 +1,26 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Mocha Tests</title>
|
<title>KineticJS Mocha Tests</title>
|
||||||
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
|
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="mocha"></div>
|
<div id="mocha"></div>
|
||||||
|
|
||||||
|
<!-- used for KineticJS container -->
|
||||||
|
<div id="container"></div>
|
||||||
|
|
||||||
<script src="../node_modules/mocha/mocha.js"></script>
|
<script src="../node_modules/mocha/mocha.js"></script>
|
||||||
<script src="../node_modules/chai/chai.js"></script>
|
<script src="../node_modules/chai/chai.js"></script>
|
||||||
<script src="../dist/kinetic-dev.js"></script>
|
<script src="../dist/kinetic-dev.js"></script>
|
||||||
<script>
|
<script>
|
||||||
mocha.ui('tdd');
|
mocha.ui('tdd');
|
||||||
var assert = chai.assert;
|
var assert = chai.assert;
|
||||||
|
|
||||||
|
Kinetic.enableTrace = true;
|
||||||
</script>
|
</script>
|
||||||
<script src="unit/Util-test.js"></script>
|
<script src="unit/Util-test.js"></script>
|
||||||
|
<script src="unit/Rect-test.js"></script>
|
||||||
<script>
|
<script>
|
||||||
if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
|
if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
|
||||||
else { mocha.run(); }
|
else { mocha.run(); }
|
||||||
|
41
test/unit/Rect-test.js
Normal file
41
test/unit/Rect-test.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
suite('Rect', function(){
|
||||||
|
var util;
|
||||||
|
|
||||||
|
setup(function(){
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
suite('add rect to stage', function(){
|
||||||
|
var stage = new Kinetic.Stage({
|
||||||
|
container: 'container',
|
||||||
|
width: 578,
|
||||||
|
height: 200
|
||||||
|
});
|
||||||
|
|
||||||
|
var layer = new Kinetic.Layer();
|
||||||
|
|
||||||
|
var rect = new Kinetic.Rect({
|
||||||
|
x: 100,
|
||||||
|
y: 50,
|
||||||
|
width: 100,
|
||||||
|
height: 50,
|
||||||
|
fill: 'green',
|
||||||
|
stroke: 'blue'
|
||||||
|
});
|
||||||
|
|
||||||
|
layer.add(rect);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
test('getters', function(){
|
||||||
|
assert.equal(rect.getX(), 100);
|
||||||
|
assert.equal(rect.getY(), 50);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
test('context trace array', function() {
|
||||||
|
var traceArr = layer.getContext().traceArr;
|
||||||
|
console.log(traceArr)
|
||||||
|
assert.equal(traceArr[0], 'clearRect(0,0,578,200)');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user