Conflicts:
	Gruntfile.js
This commit is contained in:
ippo615
2014-01-05 13:01:46 -05:00
29 changed files with 328 additions and 299 deletions

View File

@@ -264,10 +264,7 @@
if (this.shouldDrawHit()) {
if (cachedHitCanvas) {
context.save();
context._applyTransform(this);
context.drawImage(cachedHitCanvas._canvas, 0, 0);
context.restore();
this._drawCachedHitCanvas(context);
}
else {
this._drawChildren(canvas, 'drawHit');

View File

@@ -31,8 +31,8 @@
'skewXChange.kinetic',
'skewYChange.kinetic',
'rotationChange.kinetic',
'offsetXChange.kinetic',
'offsetYChange.kinetic',
'centerXChange.kinetic',
'centerYChange.kinetic',
'transformsEnabledChange.kinetic'
].join(SPACE);
@@ -104,9 +104,8 @@
delete this._cache.canvas;
},
/**
* cache node to improve drawing performance.
* NOTE: if you have filters applied to your node, your shape is already cached.
* explicitly calling cache() will override your filters.
* cache node to improve drawing performance, apply filters, or create more accurate
* hit regions
* @method
* @memberof Kinetic.Node.prototype
* @returns {Kinetic.Node}
@@ -119,17 +118,17 @@
y = box.y || 0,
width = box.width || this.width(),
height = box.height || this.height(),
sceneCanvasCache = new Kinetic.SceneCanvas({
cachedSceneCanvas = new Kinetic.SceneCanvas({
pixelRatio: 1,
width: width,
height: height
}),
filterCanvasCache = new Kinetic.SceneCanvas({
cachedFilterCanvas = new Kinetic.SceneCanvas({
pixelRatio: 1,
width: width,
height: height
}),
hitCanvasCache = new Kinetic.HitCanvas({
cachedHitCanvas = new Kinetic.HitCanvas({
width: width,
height: height
}),
@@ -141,24 +140,28 @@
this.x(x * -1);
this.y(y * -1);
this.drawScene(sceneCanvasCache);
this.drawHit(hitCanvasCache);
this.drawScene(cachedSceneCanvas);
this.drawHit(cachedHitCanvas);
this.x(origX);
this.y(origY);
this.transformsEnabled(origTransEnabled);
this._cache.canvas = {
scene: sceneCanvasCache,
filter: filterCanvasCache,
hit: hitCanvasCache,
x: x,
y: y
scene: cachedSceneCanvas,
filter: cachedFilterCanvas,
hit: cachedHitCanvas
};
return this;
},
_drawCachedSceneCanvas: function(context) {
context.save();
context._applyTransform(this);
context.drawImage(this._getCachedSceneCanvas()._canvas, 0, 0);
context.restore();
},
_getCachedSceneCanvas: function() {
var filters = this.filters(),
cachedCanvas = this._cache.canvas,
sceneCanvas = cachedCanvas.scene,
@@ -166,9 +169,6 @@
filterContext = filterCanvas.getContext(),
len, imageData, n, filter;
context.save();
context._applyTransform(this);
if (filters) {
if (!this._filterUpToDate) {
try {
@@ -192,13 +192,20 @@
this._filterUpToDate = true;
}
context.drawImage(filterCanvas._canvas, 0, 0);
return filterCanvas;
}
else {
context.drawImage(sceneCanvas._canvas, 0, 0);
return sceneCanvas;
}
},
_drawCachedHitCanvas: function(context) {
var cachedCanvas = this._cache.canvas,
hitCanvas = cachedCanvas.hit;
context.restore();
context.save();
context._applyTransform(this);
context.drawImage(hitCanvas._canvas, 0, 0);
context.restore();
},
/*
* the default isDraggable method returns false.
@@ -654,11 +661,11 @@
getAbsolutePosition: function() {
var absoluteMatrix = this.getAbsoluteTransform().getMatrix(),
absoluteTransform = new Kinetic.Transform(),
offset = this.offset();
center = this.center();
// clone the matrix array
absoluteTransform.m = absoluteMatrix.slice();
absoluteTransform.translate(offset.x, offset.y);
absoluteTransform.translate(center.x, center.y);
return absoluteTransform.getTranslation();
},
@@ -713,8 +720,8 @@
rotation: this.getRotation(),
scaleX: this.getScaleX(),
scaleY: this.getScaleY(),
offsetX: this.getOffsetX(),
offsetY: this.getOffsetY(),
centerX: this.getCenterX(),
centerY: this.getCenterY(),
skewX: this.getSkewX(),
skewY: this.getSkewY()
};
@@ -724,8 +731,8 @@
this.attrs.rotation = 0;
this.attrs.scaleX = 1;
this.attrs.scaleY = 1;
this.attrs.offsetX = 0;
this.attrs.offsetY = 0;
this.attrs.centerX = 0;
this.attrs.centerY = 0;
this.attrs.skewX = 0;
this.attrs.skewY = 0;
@@ -1071,8 +1078,8 @@
scaleY = this.getScaleY(),
skewX = this.getSkewX(),
skewY = this.getSkewY(),
offsetX = this.getOffsetX(),
offsetY = this.getOffsetY();
centerX = this.getCenterX(),
centerY = this.getCenterY();
if(x !== 0 || y !== 0) {
m.translate(x, y);
@@ -1086,8 +1093,8 @@
if(scaleX !== 1 || scaleY !== 1) {
m.scale(scaleX, scaleY);
}
if(offsetX !== 0 || offsetY !== 0) {
m.translate(-1 * offsetX, -1 * offsetY);
if(centerX !== 0 || centerY !== 0) {
m.translate(-1 * centerX, -1 * centerY);
}
return m;
@@ -1726,35 +1733,35 @@
* @returns {Number}
*/
Kinetic.Factory.addPointGetterSetter(Kinetic.Node, 'offset', 0);
Kinetic.Factory.addPointGetterSetter(Kinetic.Node, 'center', 0);
/**
* get/set offset. A node's offset defines the position and rotation point
* get/set center. A node's center defines the position and rotation point
* @method
* @memberof Kinetic.Node.prototype
* @param {Object} offset
* @param {Number} offset.x
* @param {Number} offset.y
* @param {Object} center
* @param {Number} center.x
* @param {Number} center.y
* @returns {Object}
* @example
* // set x and y <br>
* shape.offset({<br>
* shape.center({<br>
* x: 20<br>
* y: 10<br>
* });<br><br>
*/
/**
* get/set offset x
* @name offsetX
* get/set center x
* @name centerX
* @memberof Kinetic.Node.prototype
* @param {Number} x
* @returns {Integer}
*/
/**
* get/set offset y
* @name offsetY
* get/set center y
* @name centerY
* @method
* @memberof Kinetic.Node.prototype
* @param {Number} y

View File

@@ -236,7 +236,7 @@
var canvas = can || this.getLayer().getCanvas(),
context = canvas.getContext(),
cachedCanvas = this._cache.canvas,
drawFunc = this.getDrawFunc(),
drawFunc = this.sceneFunc(),
hasShadow = this.hasShadow(),
stage, bufferCanvas, bufferContext;
@@ -293,17 +293,14 @@
drawHit: function(can) {
var canvas = can || this.getLayer().hitCanvas,
context = canvas.getContext(),
drawFunc = this.getDrawHitFunc() || this.getDrawFunc(),
drawFunc = this.hitFunc() || this.sceneFunc(),
cachedCanvas = this._cache.canvas,
cachedHitCanvas = cachedCanvas && cachedCanvas.hit;
if(this.shouldDrawHit()) {
if (cachedHitCanvas) {
context.save();
context._applyTransform(this);
context.drawImage(cachedHitCanvas._canvas, 0, 0);
context.restore();
this._drawCachedHitCanvas(context);
}
else if (drawFunc) {
context.save();
@@ -317,7 +314,59 @@
}
return this;
}
},
/**
* draw hit graph using the cached scene canvas
* @method
* @memberof Kinetic.Shape.prototype
* @param {Integer} alphaThreshold alpha channel threshold that determines whether or not
* a pixel should be drawn onto the hit graph. Must be a value between 0 and 255.
* The default is 0
* @returns {Kinetic.Shape}
* @example
* shape.cache();
* shape.drawHitFromCache();
*/
drawHitFromCache: function(alphaThreshold) {
var threshold = alphaThreshold || 0,
cachedCanvas = this._cache.canvas,
sceneCanvas = this._getCachedSceneCanvas(),
sceneContext = sceneCanvas.getContext(),
hitCanvas = cachedCanvas.hit,
hitContext = hitCanvas.getContext(),
width = sceneCanvas.getWidth(),
height = sceneCanvas.getHeight(),
sceneImageData, sceneData, hitImageData, hitData, len, rgbColorKey, i, alpha;
hitContext.clear();
//try {
sceneImageData = sceneContext.getImageData(0, 0, width, height);
sceneData = sceneImageData.data;
hitImageData = hitContext.getImageData(0, 0, width, height);
hitData = hitImageData.data;
len = sceneData.length;
rgbColorKey = Kinetic.Util._hexToRgb(this.colorKey);
// replace non transparent pixels with color key
for(i = 0; i < len; i += 4) {
alpha = sceneData[i + 3];
if (alpha > threshold) {
hitData[i] = rgbColorKey.r;
hitData[i + 1] = rgbColorKey.g;
hitData[i + 2] = rgbColorKey.b;
hitData[i + 3] = 255;
}
}
hitContext.putImageData(hitImageData, 0, 0);
// }
// catch(e) {
// Kinetic.Util.warn('Unable to draw hit graph from cached scene canvas. ' + e.message);
// }
return this;
},
});
Kinetic.Util.extend(Kinetic.Shape, Kinetic.Node);
@@ -475,7 +524,7 @@
* @returns {Number}
*/
Kinetic.Factory.addGetterSetter(Kinetic.Shape, 'drawFunc');
Kinetic.Factory.addGetterSetter(Kinetic.Shape, 'sceneFunc');
/**
* set draw function
@@ -494,7 +543,7 @@
* @returns {Function}
*/
Kinetic.Factory.addGetterSetter(Kinetic.Shape, 'drawHitFunc');
Kinetic.Factory.addGetterSetter(Kinetic.Shape, 'hitFunc');
/**
* set draw hit function used for hit detection

View File

@@ -174,9 +174,9 @@
___init: function(config) {
Kinetic.Shape.call(this, config);
this.className = 'Tag';
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var width = this.getWidth(),
height = this.getHeight(),
pointerDirection = this.getPointerDirection(),

View File

@@ -36,9 +36,9 @@
that.dataArray = Kinetic.Path.parsePathData(this.getData());
});
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function (context) {
_sceneFunc: function(context) {
var ca = this.dataArray,
closedPath = false;

View File

@@ -29,9 +29,9 @@
// call super constructor
Kinetic.Shape.call(this, config);
this.className = 'RegularPolygon';
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var sides = this.attrs.sides,
radius = this.attrs.radius,
n, x, y;

View File

@@ -31,9 +31,9 @@
// call super constructor
Kinetic.Shape.call(this, config);
this.className = 'Star';
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var innerRadius = this.innerRadius(),
outerRadius = this.outerRadius(),
numPoints = this.numPoints();

View File

@@ -65,9 +65,9 @@
// update text data for certain attr changes
this.on('textChange.kinetic textStroke.kinetic textStrokeWidth.kinetic', that._setTextData);
that._setTextData();
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
context.setAttr('font', this._getContextFont());
context.setAttr('textBaseline', 'middle');
context.setAttr('textAlign', 'left');

View File

@@ -32,9 +32,9 @@
// call super constructor
Kinetic.Shape.call(this, config);
this.className = 'Arc';
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
context.beginPath();
context.arc(0, 0, this.getOuterRadius(), 0, this.getAngle(), this.getClockwise());
context.arc(0, 0, this.getInnerRadius(), this.getAngle(), 0, !this.getClockwise());

View File

@@ -40,9 +40,9 @@
// call super constructor
Kinetic.Shape.call(this, config);
this.className = CIRCLE;
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
context.beginPath();
context.arc(0, 0, this.getRadius(), 0, PIx2, false);
context.closePath();

View File

@@ -21,9 +21,9 @@
// call super constructor
Kinetic.Shape.call(this, config);
this.className = ELLIPSE;
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var r = this.getRadius();
context.beginPath();

View File

@@ -36,13 +36,13 @@
// call super constructor
Kinetic.Shape.call(this, config);
this.className = IMAGE;
this.setDrawFunc(this._drawFunc);
this.setDrawHitFunc(this._drawHitFunc);
this.sceneFunc(this._sceneFunc);
this.hitFunc(this._hitFunc);
},
_useBufferCanvas: function() {
return (this.hasShadow() || this.getAbsoluteOpacity() !== 1) && this.hasStroke();
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var width = this.getWidth(),
height = this.getHeight(),
image = this.getImage(),
@@ -69,85 +69,14 @@
context.drawImage.apply(context, params);
}
},
_drawHitFunc: function(context) {
_hitFunc: function(context) {
var width = this.getWidth(),
height = this.getHeight(),
imageHitRegion = this.imageHitRegion;
height = this.getHeight();
if(imageHitRegion) {
context.drawImage(imageHitRegion, 0, 0);
context.beginPath();
context.rect(0, 0, width, height);
context.closePath();
context.strokeShape(this);
}
else {
context.beginPath();
context.rect(0, 0, width, height);
context.closePath();
context.fillStrokeShape(this);
}
},
/**
* create image hit region which enables more accurate hit detection mapping of the image
* by avoiding event detections for transparent pixels
* @method
* @memberof Kinetic.Image.prototype
* @param {Function} [callback] callback function to be called once
* the image hit region has been created
* @example
* image.createImageHitRegion(function() {<br>
* layer.drawHit();<br>
* });
*/
createImageHitRegion: function(callback) {
var that = this,
width = this.getWidth(),
height = this.getHeight(),
canvas = new Kinetic.SceneCanvas({
width: width,
height: height,
pixelRatio: 1
}),
_context = canvas.getContext()._context,
image = this.getImage(),
imageData, data, rgbColorKey, i, len;
_context.drawImage(image, 0, 0);
try {
imageData = _context.getImageData(0, 0, width, height);
data = imageData.data;
len = data.length;
rgbColorKey = Kinetic.Util._hexToRgb(this.colorKey);
// replace non transparent pixels with color key
for(i = 0; i < len; i += 4) {
if (data[i + 3] > 0) {
data[i] = rgbColorKey.r;
data[i + 1] = rgbColorKey.g;
data[i + 2] = rgbColorKey.b;
}
}
Kinetic.Util._getImage(imageData, function(imageObj) {
that.imageHitRegion = imageObj;
if(callback) {
callback();
}
});
}
catch(e) {
Kinetic.Util.warn('Unable to create image hit region. ' + e.message);
}
},
/**
* clear image hit region
* @method
* @memberof Kinetic.Image.prototype
*/
clearImageHitRegion: function() {
delete this.imageHitRegion;
context.beginPath();
context.rect(0, 0, width, height);
context.closePath();
context.fillStrokeShape(this);
},
getWidth: function() {
var image = this.getImage();

View File

@@ -35,9 +35,9 @@
this._clearCache('tensionPoints');
});
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var points = this.getPoints(),
length = points.length,
tension = this.getTension(),

View File

@@ -25,9 +25,9 @@
___init: function(config) {
Kinetic.Shape.call(this, config);
this.className = 'Rect';
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var cornerRadius = this.getCornerRadius(),
width = this.getWidth(),
height = this.getHeight();

View File

@@ -32,9 +32,9 @@
// call super constructor
Kinetic.Shape.call(this, config);
this.className = 'Ring';
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
context.beginPath();
context.arc(0, 0, this.getInnerRadius(), 0, PIx2, false);
context.moveTo(this.getOuterRadius(), 0);

View File

@@ -82,10 +82,10 @@
this.setIndex(0);
});
this.setDrawFunc(this._drawFunc);
this.setDrawHitFunc(this._drawHitFunc);
this.sceneFunc(this._sceneFunc);
this.hitFunc(this._hitFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var anim = this.getAnimation(),
index = this.getIndex(),
f = this.getAnimations()[anim][index],
@@ -95,7 +95,7 @@
context.drawImage(image, f.x, f.y, f.width, f.height, 0, 0, f.width, f.height);
}
},
_drawHitFunc: function(context) {
_hitFunc: function(context) {
var anim = this.getAnimation(),
index = this.getIndex(),
f = this.getAnimations()[anim][index];

View File

@@ -86,10 +86,10 @@
}
this._setTextData();
this.setDrawFunc(this._drawFunc);
this.setDrawHitFunc(this._drawHitFunc);
this.sceneFunc(this._sceneFunc);
this.hitFunc(this._hitFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
var p = this.getPadding(),
textHeight = this.getTextHeight(),
lineHeightPx = this.getLineHeight() * textHeight,
@@ -127,7 +127,7 @@
}
context.restore();
},
_drawHitFunc: function(context) {
_hitFunc: function(context) {
var width = this.getWidth(),
height = this.getHeight();

View File

@@ -30,9 +30,9 @@
// call super constructor
Kinetic.Shape.call(this, config);
this.className = 'Wedge';
this.setDrawFunc(this._drawFunc);
this.sceneFunc(this._sceneFunc);
},
_drawFunc: function(context) {
_sceneFunc: function(context) {
context.beginPath();
context.arc(0, 0, this.getRadius(), 0, this.getAngle(), this.getClockwise());
context.lineTo(0, 0);