mirror of
https://github.com/konvajs/konva.git
synced 2025-09-19 10:47:59 +08:00
first pass at integrating filters into new caching mechanism. added group filter test. Removed blurX and blurY filters because I don't think they'll be needed in their current state. Commented out half filter blur test because it's not a common use case. other filter tests have been disabled for now. Working on enabling them with future commits
This commit is contained in:
45
Gruntfile.js
45
Gruntfile.js
@@ -1,12 +1,33 @@
|
|||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
var sourceFiles = [
|
var sourceFiles = [
|
||||||
// core / anim + tween + dd
|
// core
|
||||||
'src/Global.js',
|
'src/Global.js',
|
||||||
'src/Util.js',
|
'src/Util.js',
|
||||||
'src/Canvas.js',
|
'src/Canvas.js',
|
||||||
'src/Context.js',
|
'src/Context.js',
|
||||||
'src/Factory.js',
|
'src/Factory.js',
|
||||||
'src/Node.js',
|
'src/Node.js',
|
||||||
|
|
||||||
|
// filters
|
||||||
|
'src/filters/FilterWrapper.js',
|
||||||
|
'src/filters/Grayscale.js',
|
||||||
|
'src/filters/Brighten.js',
|
||||||
|
'src/filters/Invert.js',
|
||||||
|
'src/filters/Blur.js',
|
||||||
|
'src/filters/Mask.js',
|
||||||
|
'src/filters/ColorPack.js',
|
||||||
|
'src/filters/ConvolvePack.js',
|
||||||
|
'src/filters/ColorStretch.js',
|
||||||
|
'src/filters/Flip.js',
|
||||||
|
'src/filters/Levels.js',
|
||||||
|
'src/filters/Mirror.js',
|
||||||
|
'src/filters/Noise.js',
|
||||||
|
'src/filters/Pixelate.js',
|
||||||
|
'src/filters/Polar.js',
|
||||||
|
'src/filters/Threshold.js',
|
||||||
|
'src/filters/Sepia.js',
|
||||||
|
|
||||||
|
// core
|
||||||
'src/Animation.js',
|
'src/Animation.js',
|
||||||
'src/Tween.js',
|
'src/Tween.js',
|
||||||
'src/DragAndDrop.js',
|
'src/DragAndDrop.js',
|
||||||
@@ -33,27 +54,7 @@ module.exports = function(grunt) {
|
|||||||
'src/plugins/TextPath.js',
|
'src/plugins/TextPath.js',
|
||||||
'src/plugins/RegularPolygon.js',
|
'src/plugins/RegularPolygon.js',
|
||||||
'src/plugins/Star.js',
|
'src/plugins/Star.js',
|
||||||
'src/plugins/Label.js',
|
'src/plugins/Label.js'
|
||||||
|
|
||||||
// filters
|
|
||||||
'src/filters/FilterWrapper.js',
|
|
||||||
'src/filters/Grayscale.js',
|
|
||||||
'src/filters/Brighten.js',
|
|
||||||
'src/filters/Invert.js',
|
|
||||||
'src/filters/Blur.js',
|
|
||||||
'src/filters/QuickBlur.js',
|
|
||||||
'src/filters/Mask.js',
|
|
||||||
'src/filters/ColorPack.js',
|
|
||||||
'src/filters/ConvolvePack.js',
|
|
||||||
'src/filters/ColorStretch.js',
|
|
||||||
'src/filters/Flip.js',
|
|
||||||
'src/filters/Levels.js',
|
|
||||||
'src/filters/Mirror.js',
|
|
||||||
'src/filters/Noise.js',
|
|
||||||
'src/filters/Pixelate.js',
|
|
||||||
'src/filters/Polar.js',
|
|
||||||
'src/filters/Threshold.js',
|
|
||||||
'src/filters/Sepia.js'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Project configuration.
|
// Project configuration.
|
||||||
|
@@ -241,26 +241,41 @@
|
|||||||
drawScene: function(can) {
|
drawScene: function(can) {
|
||||||
var layer = this.getLayer(),
|
var layer = this.getLayer(),
|
||||||
canvas = can || (layer && layer.getCanvas()),
|
canvas = can || (layer && layer.getCanvas()),
|
||||||
|
context = canvas && canvas.getContext(),
|
||||||
cachedCanvas = this._cache.canvas,
|
cachedCanvas = this._cache.canvas,
|
||||||
cachedSceneCanvas = cachedCanvas && cachedCanvas.scene;
|
cachedSceneCanvas = cachedCanvas && cachedCanvas.scene;
|
||||||
|
|
||||||
if (this.isVisible()) {
|
if (this.isVisible()) {
|
||||||
this._draw(canvas, cachedSceneCanvas, 'drawScene');
|
if (cachedSceneCanvas) {
|
||||||
|
this._drawCachedSceneCanvas(context);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._drawChildren(canvas, 'drawScene');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
drawHit: function(can) {
|
drawHit: function(can) {
|
||||||
var layer = this.getLayer(),
|
var layer = this.getLayer(),
|
||||||
canvas = can || (layer && layer.hitCanvas),
|
canvas = can || (layer && layer.hitCanvas),
|
||||||
|
context = canvas && canvas.getContext(),
|
||||||
cachedCanvas = this._cache.canvas,
|
cachedCanvas = this._cache.canvas,
|
||||||
cachedHitCanvas = cachedCanvas && cachedCanvas.hit;
|
cachedHitCanvas = cachedCanvas && cachedCanvas.hit;
|
||||||
|
|
||||||
if (this.shouldDrawHit()) {
|
if (this.shouldDrawHit()) {
|
||||||
this._draw(canvas, cachedHitCanvas, 'drawHit');
|
if (cachedHitCanvas) {
|
||||||
|
context.save();
|
||||||
|
context._applyTransform(this);
|
||||||
|
context.drawImage(cachedHitCanvas._canvas, 0, 0);
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._drawChildren(canvas, 'drawHit');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
_draw: function(canvas, cachedCanvas, drawMethod) {
|
_drawChildren: function(canvas, drawMethod) {
|
||||||
var context = canvas && canvas.getContext(),
|
var context = canvas && canvas.getContext(),
|
||||||
clipWidth = this.getClipWidth(),
|
clipWidth = this.getClipWidth(),
|
||||||
clipHeight = this.getClipHeight(),
|
clipHeight = this.getClipHeight(),
|
||||||
@@ -279,17 +294,9 @@
|
|||||||
context.reset();
|
context.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cachedCanvas) {
|
this.children.each(function(child) {
|
||||||
context.save();
|
child[drawMethod](canvas);
|
||||||
context._applyTransform(this);
|
});
|
||||||
context.drawImage(cachedCanvas._canvas, 0, 0);
|
|
||||||
context.restore();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.children.each(function(child) {
|
|
||||||
child[drawMethod](canvas);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasClip) {
|
if (hasClip) {
|
||||||
context.restore();
|
context.restore();
|
||||||
|
@@ -111,11 +111,17 @@
|
|||||||
this.addColorComponentSetter(constructor, attr, G);
|
this.addColorComponentSetter(constructor, attr, G);
|
||||||
this.addColorComponentSetter(constructor, attr, B);
|
this.addColorComponentSetter(constructor, attr, B);
|
||||||
|
|
||||||
|
// overloaders
|
||||||
this.addOverloadedGetterSetter(constructor, attr + RGB);
|
this.addOverloadedGetterSetter(constructor, attr + RGB);
|
||||||
this.addOverloadedGetterSetter(constructor, attr + UPPER_R);
|
this.addOverloadedGetterSetter(constructor, attr + UPPER_R);
|
||||||
this.addOverloadedGetterSetter(constructor, attr + UPPER_G);
|
this.addOverloadedGetterSetter(constructor, attr + UPPER_G);
|
||||||
this.addOverloadedGetterSetter(constructor, attr + UPPER_B);
|
this.addOverloadedGetterSetter(constructor, attr + UPPER_B);
|
||||||
},
|
},
|
||||||
|
addFilterGetterSetter: function(constructor, attr, def) {
|
||||||
|
this.addGetter(constructor, attr, def);
|
||||||
|
this.addFilterSetter(constructor, attr);
|
||||||
|
this.addOverloadedGetterSetter(constructor, attr);
|
||||||
|
},
|
||||||
|
|
||||||
// getter adders
|
// getter adders
|
||||||
addColorRGBGetter: function(constructor, attr) {
|
addColorRGBGetter: function(constructor, attr) {
|
||||||
@@ -237,6 +243,15 @@
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
addFilterSetter: function(constructor, attr) {
|
||||||
|
var method = SET + Kinetic.Util._capitalize(attr);
|
||||||
|
|
||||||
|
constructor.prototype[method] = function(val) {
|
||||||
|
this._setAttr(attr, val);
|
||||||
|
this._filterUpToDate = false;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
},
|
||||||
addPointSetter: function(constructor, attr) {
|
addPointSetter: function(constructor, attr) {
|
||||||
var that = this,
|
var that = this,
|
||||||
baseMethod = SET + Kinetic.Util._capitalize(attr);
|
baseMethod = SET + Kinetic.Util._capitalize(attr);
|
||||||
|
82
src/Node.js
82
src/Node.js
@@ -43,6 +43,7 @@
|
|||||||
this.eventListeners = {};
|
this.eventListeners = {};
|
||||||
this.attrs = {};
|
this.attrs = {};
|
||||||
this._cache = {};
|
this._cache = {};
|
||||||
|
this._filterUpToDate = false;
|
||||||
this.setAttrs(config);
|
this.setAttrs(config);
|
||||||
|
|
||||||
// event bindings for cache handling
|
// event bindings for cache handling
|
||||||
@@ -112,18 +113,25 @@
|
|||||||
* @example
|
* @example
|
||||||
* node.cache();
|
* node.cache();
|
||||||
*/
|
*/
|
||||||
cache: function(box) {
|
cache: function(b) {
|
||||||
var x = box.x || 0,
|
var box = b || {},
|
||||||
|
x = box.x || 0,
|
||||||
y = box.y || 0,
|
y = box.y || 0,
|
||||||
|
width = box.width || this.width(),
|
||||||
|
height = box.height || this.height(),
|
||||||
sceneCanvasCache = new Kinetic.SceneCanvas({
|
sceneCanvasCache = new Kinetic.SceneCanvas({
|
||||||
pixelRatio: 1,
|
pixelRatio: 1,
|
||||||
width: box.width,
|
width: width,
|
||||||
height: box.height
|
height: height
|
||||||
|
}),
|
||||||
|
filterCanvasCache = new Kinetic.SceneCanvas({
|
||||||
|
pixelRatio: 1,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
}),
|
}),
|
||||||
hitCanvasCache = new Kinetic.HitCanvas({
|
hitCanvasCache = new Kinetic.HitCanvas({
|
||||||
pixelRatio: 1,
|
width: width,
|
||||||
width: box.width,
|
height: height
|
||||||
height: box.height
|
|
||||||
}),
|
}),
|
||||||
origTransEnabled = this.transformsEnabled(),
|
origTransEnabled = this.transformsEnabled(),
|
||||||
origX = this.x(),
|
origX = this.x(),
|
||||||
@@ -142,6 +150,7 @@
|
|||||||
|
|
||||||
this._cache.canvas = {
|
this._cache.canvas = {
|
||||||
scene: sceneCanvasCache,
|
scene: sceneCanvasCache,
|
||||||
|
filter: filterCanvasCache,
|
||||||
hit: hitCanvasCache,
|
hit: hitCanvasCache,
|
||||||
x: x,
|
x: x,
|
||||||
y: y
|
y: y
|
||||||
@@ -149,6 +158,48 @@
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
_drawCachedSceneCanvas: function(context) {
|
||||||
|
var filters = this.filters(),
|
||||||
|
cachedCanvas = this._cache.canvas,
|
||||||
|
sceneCanvas = cachedCanvas.scene,
|
||||||
|
filterCanvas = cachedCanvas.filter,
|
||||||
|
filterContext = filterCanvas.getContext(),
|
||||||
|
len, imageData, n, filter;
|
||||||
|
|
||||||
|
context.save();
|
||||||
|
context._applyTransform(this);
|
||||||
|
|
||||||
|
if (filters) {
|
||||||
|
if (!this._filterUpToDate) {
|
||||||
|
try {
|
||||||
|
len = filters.length;
|
||||||
|
filterContext.clear();
|
||||||
|
// copy cached canvas onto filter context
|
||||||
|
filterContext.drawImage(sceneCanvas._canvas, 0, 0);
|
||||||
|
imageData = filterContext.getImageData(0, 0, filterCanvas.getWidth(), filterCanvas.getHeight());
|
||||||
|
|
||||||
|
// apply filters to filter context
|
||||||
|
for (n=0; n<len; n++) {
|
||||||
|
filter = filters[n];
|
||||||
|
filter.call(this, imageData);
|
||||||
|
filterContext.putImageData(imageData, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
Kinetic.Util.warn('Unable to apply filter. ' + e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._filterUpToDate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.drawImage(filterCanvas._canvas, 0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
context.drawImage(sceneCanvas._canvas, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.restore();
|
||||||
|
},
|
||||||
/*
|
/*
|
||||||
* the default isDraggable method returns false.
|
* the default isDraggable method returns false.
|
||||||
* if the DragAndDrop module is included, this is overwritten
|
* if the DragAndDrop module is included, this is overwritten
|
||||||
@@ -1753,6 +1804,23 @@
|
|||||||
* @returns {Boolean|String}
|
* @returns {Boolean|String}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'filters');
|
||||||
|
/**
|
||||||
|
* get/set filters
|
||||||
|
* @name filters
|
||||||
|
* @method
|
||||||
|
* @memberof Kinetic.Node.prototype
|
||||||
|
* @param {Array} filters array of filters
|
||||||
|
* @returns {Array}
|
||||||
|
* @example
|
||||||
|
* // set a single filter<br>
|
||||||
|
* node.filters([Kinetic.Filters.Blur]);<br><br>
|
||||||
|
*
|
||||||
|
* // get filters<br>
|
||||||
|
* var filters = node.filters();
|
||||||
|
*/
|
||||||
|
|
||||||
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'visible', 'inherit');
|
Kinetic.Factory.addGetterSetter(Kinetic.Node, 'visible', 'inherit');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
22
src/Shape.js
22
src/Shape.js
@@ -236,19 +236,16 @@
|
|||||||
var canvas = can || this.getLayer().getCanvas(),
|
var canvas = can || this.getLayer().getCanvas(),
|
||||||
context = canvas.getContext(),
|
context = canvas.getContext(),
|
||||||
cachedCanvas = this._cache.canvas,
|
cachedCanvas = this._cache.canvas,
|
||||||
cachedSceneCanvas = cachedCanvas && cachedCanvas.scene,
|
|
||||||
drawFunc = this.getDrawFunc(),
|
drawFunc = this.getDrawFunc(),
|
||||||
hasShadow = this.hasShadow(),
|
hasShadow = this.hasShadow(),
|
||||||
stage, bufferCanvas, bufferContext;
|
stage, bufferCanvas, bufferContext;
|
||||||
|
|
||||||
if(this.isVisible()) {
|
if(this.isVisible()) {
|
||||||
context.save();
|
if (cachedCanvas) {
|
||||||
|
this._drawCachedSceneCanvas(context);
|
||||||
if (cachedSceneCanvas) {
|
|
||||||
context._applyTransform(this);
|
|
||||||
context.drawImage(cachedSceneCanvas._canvas, 0, 0);
|
|
||||||
}
|
}
|
||||||
else if (drawFunc) {
|
else if (drawFunc) {
|
||||||
|
context.save();
|
||||||
// if buffer canvas is needed
|
// if buffer canvas is needed
|
||||||
if (this._useBufferCanvas()) {
|
if (this._useBufferCanvas()) {
|
||||||
stage = this.getStage();
|
stage = this.getStage();
|
||||||
@@ -286,10 +283,9 @@
|
|||||||
|
|
||||||
context._applyOpacity(this);
|
context._applyOpacity(this);
|
||||||
drawFunc.call(this, context);
|
drawFunc.call(this, context);
|
||||||
}
|
}
|
||||||
|
context.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
context.restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@@ -302,18 +298,22 @@
|
|||||||
cachedHitCanvas = cachedCanvas && cachedCanvas.hit;
|
cachedHitCanvas = cachedCanvas && cachedCanvas.hit;
|
||||||
|
|
||||||
if(this.shouldDrawHit()) {
|
if(this.shouldDrawHit()) {
|
||||||
context.save();
|
|
||||||
if (cachedHitCanvas) {
|
if (cachedHitCanvas) {
|
||||||
|
context.save();
|
||||||
context._applyTransform(this);
|
context._applyTransform(this);
|
||||||
context.drawImage(cachedHitCanvas._canvas, 0, 0);
|
context.drawImage(cachedHitCanvas._canvas, 0, 0);
|
||||||
|
context.restore();
|
||||||
}
|
}
|
||||||
else if (drawFunc) {
|
else if (drawFunc) {
|
||||||
|
context.save();
|
||||||
context._applyLineJoin(this);
|
context._applyLineJoin(this);
|
||||||
context._applyTransform(this);
|
context._applyTransform(this);
|
||||||
|
|
||||||
drawFunc.call(this, context);
|
drawFunc.call(this, context);
|
||||||
|
context.restore();
|
||||||
}
|
}
|
||||||
context.restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@@ -352,24 +352,19 @@
|
|||||||
Blur(src, dst||src, opt );
|
Blur(src, dst||src, opt );
|
||||||
}else{
|
}else{
|
||||||
Blur.call(this, src, dst||src, opt || {
|
Blur.call(this, src, dst||src, opt || {
|
||||||
filterRadius: this.getFilterRadius()
|
filterRadius: this.blurRadius()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterRadius', 0);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'blurRadius', 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get filter radius. Returns the radius for Gaussian blur filter.
|
* get/set blur radius
|
||||||
* @name getFilterRadius
|
* @name blurRadius
|
||||||
* @method
|
|
||||||
* @memberof Kinetic.Image.prototype
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get filter radius. Set the radius for Gaussian blur filter.
|
|
||||||
* @name setFilterRadius
|
|
||||||
* @method
|
* @method
|
||||||
* @memberof Kinetic.Image.prototype
|
* @memberof Kinetic.Image.prototype
|
||||||
|
* @param {Integer} radius
|
||||||
|
* @returns {Integer}
|
||||||
*/
|
*/
|
||||||
})();
|
})();
|
@@ -18,7 +18,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterBrightness', 0);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'brightness', 0);
|
||||||
/**
|
/**
|
||||||
* get filter brightness. The brightness is a number between -255 and 255. Positive values
|
* get filter brightness. The brightness is a number between -255 and 255. Positive values
|
||||||
* increase the brightness and negative values decrease the brightness, making the image darker
|
* increase the brightness and negative values decrease the brightness, making the image darker
|
||||||
|
@@ -70,9 +70,9 @@
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterHue', 0);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'hue', 0);
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterSaturation', 1);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'saturation', 1);
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterValue', 1);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'value', 1);
|
||||||
|
|
||||||
Kinetic.Filters.HSV = function(src,dst,opt){
|
Kinetic.Filters.HSV = function(src,dst,opt){
|
||||||
if( this === Kinetic.Filters ){
|
if( this === Kinetic.Filters ){
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterHueShiftDeg', 0);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'hueShiftDeg', 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get filter hue. Returns the hue shift for the HSV filter.
|
* get filter hue. Returns the hue shift for the HSV filter.
|
||||||
@@ -184,7 +184,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterColorizeColor', [255,0,0] );
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'colorizeColor', [255,0,0] );
|
||||||
/**
|
/**
|
||||||
* Gets the colorizing color.
|
* Gets the colorizing color.
|
||||||
* @name getFilterColorizeColor
|
* @name getFilterColorizeColor
|
||||||
|
@@ -68,7 +68,7 @@
|
|||||||
return kernel;
|
return kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterAmount', 50);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'convoltion', 50);
|
||||||
/**
|
/**
|
||||||
* get the current filter amount
|
* get the current filter amount
|
||||||
* @name getFilterAmount
|
* @name getFilterAmount
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'quantizationLevels', 4);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'quantizationLevels', 4);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get quantization levels. Returns the number of unique levels for each color
|
* get quantization levels. Returns the number of unique levels for each color
|
||||||
|
@@ -191,7 +191,7 @@
|
|||||||
return idata;
|
return idata;
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filterThreshold', 0);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'threshold', 0);
|
||||||
|
|
||||||
//threshold The RGB euclidian distance threshold (default : 10)
|
//threshold The RGB euclidian distance threshold (default : 10)
|
||||||
|
|
||||||
|
@@ -40,7 +40,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'noiseAmount', 32);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'noise', 32);
|
||||||
|
|
||||||
Kinetic.Filters.Noise = function(src,dst,opt){
|
Kinetic.Filters.Noise = function(src,dst,opt){
|
||||||
if( this === Kinetic.Filters ){
|
if( this === Kinetic.Filters ){
|
||||||
|
@@ -86,16 +86,15 @@
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'pixelWidth', 8);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'pixelationSize', 8);
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'pixelHeight', 8);
|
|
||||||
|
|
||||||
Kinetic.Filters.Pixelate = function(src,dst,opt){
|
Kinetic.Filters.Pixelate = function(src,dst,opt){
|
||||||
if( this === Kinetic.Filters ){
|
if( this === Kinetic.Filters ){
|
||||||
Pixelate(src, dst||src, opt );
|
Pixelate(src, dst||src, opt );
|
||||||
}else{
|
}else{
|
||||||
Pixelate.call(this, src, dst||src, opt || {
|
Pixelate.call(this, src, dst||src, opt || {
|
||||||
pixelWidth: this.getPixelWidth(),
|
pixelWidth: this.pixelationSize(),
|
||||||
pixelHeight: this.getPixelHeight()
|
pixelHeight: this.pixelationSize()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -1,198 +0,0 @@
|
|||||||
(function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BlurX Filter. Blurs the image in the X direction (horizontally). It
|
|
||||||
* performs w*h pixel reads, and w*h pixel writes. It is faster than a
|
|
||||||
* Gaussian blur but does not look as nice. Use Kinetic.Filters.Blur for
|
|
||||||
* a Gaussian blur.
|
|
||||||
* @function
|
|
||||||
* @author ippo615
|
|
||||||
* @memberof Kinetic.Filters
|
|
||||||
* @param {ImageData} src, the source image data (what will be transformed)
|
|
||||||
* @param {ImageData} dst, the destination image data (where it will be saved)
|
|
||||||
* @param {Object} opt
|
|
||||||
* @param {Number} [opt.blurWidth] how many neighboring pixels to will affect the
|
|
||||||
* blurred pixel, default: 5
|
|
||||||
*/
|
|
||||||
|
|
||||||
var BlurX = function(src,dst,opt){
|
|
||||||
|
|
||||||
var srcPixels = src.data,
|
|
||||||
dstPixels = dst.data,
|
|
||||||
xSize = src.width,
|
|
||||||
ySize = src.height,
|
|
||||||
i, m, x, y, k, tmp, r=0,g=0,b=0,a=0;
|
|
||||||
|
|
||||||
// DONT USE: kSize = opt.blurWidth || 5;
|
|
||||||
// HINT: consider when (opt.blurWidth = 0)
|
|
||||||
var kSize = 5;
|
|
||||||
if( opt.hasOwnProperty('blurWidth') ){
|
|
||||||
kSize = Math.round( Math.abs(opt.blurWidth) )+1;
|
|
||||||
}
|
|
||||||
var kMid = Math.floor(kSize/2);
|
|
||||||
|
|
||||||
//console.info('Blur Width: '+kSize);
|
|
||||||
//console.info('Blur Middle: '+kMid);
|
|
||||||
|
|
||||||
var xEnd = xSize - kMid;
|
|
||||||
|
|
||||||
for (y = 0; y < ySize; y += 1) {
|
|
||||||
r=0;g=0;b=0;a=0;
|
|
||||||
for (x=-kMid; x<kMid; x+=1 ){
|
|
||||||
// Add the new
|
|
||||||
//if( y === 0 ){ console.info('Loading pixel at: '+((x+xSize)%xSize) ); }
|
|
||||||
i = (y * xSize + (x+xSize)%xSize ) * 4;
|
|
||||||
r += srcPixels[i+0];
|
|
||||||
g += srcPixels[i+1];
|
|
||||||
b += srcPixels[i+2];
|
|
||||||
a += srcPixels[i+3];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x = 0; x < xSize; x += 1) {
|
|
||||||
//if( y === 0 ){ console.info('Added pixel at: '+(x+kMid)); }
|
|
||||||
//if( y === 0 ){ console.info('Recorded pixel at: '+x); }
|
|
||||||
//if( y === 0 ){ console.info('Removed pixel at: '+((x-kMid+xSize)%xSize) ); }
|
|
||||||
// Add the new
|
|
||||||
i = (y * xSize + (x+kMid)%xSize ) * 4;
|
|
||||||
r += srcPixels[i+0];
|
|
||||||
g += srcPixels[i+1];
|
|
||||||
b += srcPixels[i+2];
|
|
||||||
a += srcPixels[i+3];
|
|
||||||
// Store the result
|
|
||||||
i = (y * xSize + x) * 4;
|
|
||||||
dstPixels[i+0] = r/kSize;
|
|
||||||
dstPixels[i+1] = g/kSize;
|
|
||||||
dstPixels[i+2] = b/kSize;
|
|
||||||
dstPixels[i+3] = a/kSize;
|
|
||||||
// Subtract the old
|
|
||||||
i = (y * xSize + (x-kMid+xSize)%xSize ) * 4;
|
|
||||||
r -= srcPixels[i+0];
|
|
||||||
g -= srcPixels[i+1];
|
|
||||||
b -= srcPixels[i+2];
|
|
||||||
a -= srcPixels[i+3];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BlurY Filter. Blurs the image in the Y direction (vertically). It
|
|
||||||
* performs w*h pixel reads, and w*h pixel writes. It is faster than a
|
|
||||||
* Gaussian blur but does not look as nice. Use Kinetic.Filters.Blur for
|
|
||||||
* a Gaussian blur.
|
|
||||||
* @function
|
|
||||||
* @author ippo615
|
|
||||||
* @memberof Kinetic.Filters
|
|
||||||
* @param {ImageData} src, the source image data (what will be transformed)
|
|
||||||
* @param {ImageData} dst, the destination image data (where it will be saved)
|
|
||||||
* @param {Object} opt
|
|
||||||
* @param {Number} [opt.blurHeight] how many neighboring pixels to will affect the
|
|
||||||
* blurred pixel, default: 5
|
|
||||||
*/
|
|
||||||
|
|
||||||
var BlurY = function(src,dst,opt){
|
|
||||||
|
|
||||||
var srcPixels = src.data,
|
|
||||||
dstPixels = dst.data,
|
|
||||||
xSize = src.width,
|
|
||||||
ySize = src.height,
|
|
||||||
i, m, x, y, k, tmp, r=0,g=0,b=0,a=0;
|
|
||||||
|
|
||||||
var kSize = 5;
|
|
||||||
if( opt.hasOwnProperty('blurHeight') ){
|
|
||||||
kSize = Math.round( Math.abs(opt.blurHeight) )+1;
|
|
||||||
}
|
|
||||||
var kMid = Math.floor(kSize/2);
|
|
||||||
|
|
||||||
var yEnd = ySize - kMid;
|
|
||||||
|
|
||||||
for (x = 0; x < xSize; x += 1) {
|
|
||||||
r=0;g=0;b=0;a=0;
|
|
||||||
for (y=-kMid; y<kMid; y+=1 ){
|
|
||||||
// Add the new
|
|
||||||
i = ((y+ySize)%ySize * xSize + x ) * 4;
|
|
||||||
r += srcPixels[i+0];
|
|
||||||
g += srcPixels[i+1];
|
|
||||||
b += srcPixels[i+2];
|
|
||||||
a += srcPixels[i+3];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y = 0; y < ySize; y += 1) {
|
|
||||||
// Add the new
|
|
||||||
i = ((y+kMid+ySize)%ySize * xSize + x ) * 4;
|
|
||||||
r += srcPixels[i+0];
|
|
||||||
g += srcPixels[i+1];
|
|
||||||
b += srcPixels[i+2];
|
|
||||||
a += srcPixels[i+3];
|
|
||||||
// Store the result
|
|
||||||
i = (y * xSize + x) * 4;
|
|
||||||
dstPixels[i+0] = r/kSize;
|
|
||||||
dstPixels[i+1] = g/kSize;
|
|
||||||
dstPixels[i+2] = b/kSize;
|
|
||||||
dstPixels[i+3] = a/kSize;
|
|
||||||
// Subtract the old
|
|
||||||
i = ((y-kMid+ySize)%ySize * xSize + x ) * 4;
|
|
||||||
r -= srcPixels[i+0];
|
|
||||||
g -= srcPixels[i+1];
|
|
||||||
b -= srcPixels[i+2];
|
|
||||||
a -= srcPixels[i+3];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'blurWidth', 5);
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'blurHeight', 5);
|
|
||||||
|
|
||||||
Kinetic.Filters.BlurX = function(src,dst,opt){
|
|
||||||
if( this === Kinetic.Filters ){
|
|
||||||
BlurX(src, dst||src, opt );
|
|
||||||
}else{
|
|
||||||
BlurX.call(this, src, dst||src, opt || {
|
|
||||||
blurWidth: this.getBlurWidth()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Kinetic.Filters.BlurY = function(src,dst,opt){
|
|
||||||
if( this === Kinetic.Filters ){
|
|
||||||
BlurY(src, dst||src, opt );
|
|
||||||
}else{
|
|
||||||
BlurY.call(this, src, dst||src, opt || {
|
|
||||||
blurHeight: this.getBlurHeight()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get filter blur width. Returns the width of a blurred pixel. Must be
|
|
||||||
* an integer greater than 0.
|
|
||||||
* @name getBlurWidth
|
|
||||||
* @method
|
|
||||||
* @memberof Kinetic.Image.prototype
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set filter blur width.
|
|
||||||
* @name setBlurWidth
|
|
||||||
* @method
|
|
||||||
* @memberof Kinetic.Image.prototype
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get filter blur height. Returns the height of a blurred pixel. Must be
|
|
||||||
* an integer greater than 0.
|
|
||||||
* @name getBlurHeight
|
|
||||||
* @method
|
|
||||||
* @memberof Kinetic.Image.prototype
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set filter blur height.
|
|
||||||
* @name setBlurHeight
|
|
||||||
* @method
|
|
||||||
* @memberof Kinetic.Image.prototype
|
|
||||||
*/
|
|
||||||
|
|
||||||
})();
|
|
@@ -33,7 +33,7 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'thresholdLevel', 128);
|
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'threshold', 128);
|
||||||
|
|
||||||
Kinetic.Filters.Threshold = function(src,dst,opt){
|
Kinetic.Filters.Threshold = function(src,dst,opt){
|
||||||
if( this === Kinetic.Filters ){
|
if( this === Kinetic.Filters ){
|
||||||
|
@@ -45,36 +45,18 @@
|
|||||||
_drawFunc: function(context) {
|
_drawFunc: function(context) {
|
||||||
var width = this.getWidth(),
|
var width = this.getWidth(),
|
||||||
height = this.getHeight(),
|
height = this.getHeight(),
|
||||||
crop, cropWidth, cropHeight,
|
image = this.getImage(),
|
||||||
params,
|
crop, cropWidth, cropHeight, params;
|
||||||
image;
|
|
||||||
|
|
||||||
//TODO: this logic needs to hook int othe new caching system
|
if (image) {
|
||||||
|
crop = this.getCrop(),
|
||||||
// if a filter is set, and the filter needs to be updated, reapply
|
cropWidth = crop.width;
|
||||||
if (this.getFilter() && this._applyFilter) {
|
cropHeight = crop.height;
|
||||||
this.applyFilter();
|
if (cropWidth && cropHeight) {
|
||||||
this._applyFilter = false;
|
params = [image, crop.x, crop.y, cropWidth, cropHeight, 0, 0, width, height];
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
// NOTE: this.filterCanvas may be set by the above code block
|
params = [image, 0, 0, width, height];
|
||||||
// In that case, cropping is already applied.
|
|
||||||
if (this.filterCanvas) {
|
|
||||||
image = this.filterCanvas._canvas;
|
|
||||||
params = [image, 0, 0, width, height];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
image = this.getImage();
|
|
||||||
|
|
||||||
if (image) {
|
|
||||||
crop = this.getCrop(),
|
|
||||||
cropWidth = crop.width;
|
|
||||||
cropHeight = crop.height;
|
|
||||||
if (cropWidth && cropHeight) {
|
|
||||||
params = [image, crop.x, crop.y, cropWidth, cropHeight, 0, 0, width, height];
|
|
||||||
} else {
|
|
||||||
params = [image, 0, 0, width, height];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,59 +88,6 @@
|
|||||||
context.fillStrokeShape(this);
|
context.fillStrokeShape(this);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
applyFilter: function() {
|
|
||||||
var image = this.getImage(),
|
|
||||||
width = this.getWidth(),
|
|
||||||
height = this.getHeight(),
|
|
||||||
filter = this.getFilter(),
|
|
||||||
crop = this.getCrop(),
|
|
||||||
filterCanvas, context, imageData;
|
|
||||||
|
|
||||||
// Determine the region we are cropping
|
|
||||||
crop.x = crop.x;
|
|
||||||
crop.y = crop.y;
|
|
||||||
crop.width = crop.width || width - crop.x;
|
|
||||||
crop.height = crop.height || height - crop.y;
|
|
||||||
|
|
||||||
// Make a filterCanvas the same size as the cropped image
|
|
||||||
if (this.filterCanvas &&
|
|
||||||
this.filterCanvas.getWidth() === crop.width &&
|
|
||||||
this.filterCanvas.getHeight() === crop.height) {
|
|
||||||
filterCanvas = this.filterCanvas;
|
|
||||||
filterCanvas.getContext().clear();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
filterCanvas = this.filterCanvas = new Kinetic.SceneCanvas({
|
|
||||||
width: crop.width,
|
|
||||||
height: crop.height,
|
|
||||||
pixelRatio: 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
context = filterCanvas.getContext();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Crop the image onto the filterCanvas then apply
|
|
||||||
// the filter to the filterCanvas
|
|
||||||
context.drawImage(image, crop.x, crop.y, crop.width, crop.height, 0,0,crop.width, crop.height);
|
|
||||||
imageData = context.getImageData(0, 0, crop.width, crop.height);
|
|
||||||
filter.call(this, imageData);
|
|
||||||
context.putImageData(imageData, 0, 0);
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
this.clearFilter();
|
|
||||||
Kinetic.Util.warn('Unable to apply filter. ' + e.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* clear filter
|
|
||||||
* @method
|
|
||||||
* @memberof Kinetic.Image.prototype
|
|
||||||
*/
|
|
||||||
clearFilter: function() {
|
|
||||||
this.filterCanvas = null;
|
|
||||||
this._applyFilter = false;
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* create image hit region which enables more accurate hit detection mapping of the image
|
* create image hit region which enables more accurate hit detection mapping of the image
|
||||||
* by avoiding event detections for transparent pixels
|
* by avoiding event detections for transparent pixels
|
||||||
@@ -227,31 +156,10 @@
|
|||||||
getHeight: function() {
|
getHeight: function() {
|
||||||
var image = this.getImage();
|
var image = this.getImage();
|
||||||
return this.attrs.height || (image ? image.height : 0);
|
return this.attrs.height || (image ? image.height : 0);
|
||||||
},
|
|
||||||
destroy: function(){
|
|
||||||
Kinetic.Shape.prototype.destroy.call(this);
|
|
||||||
delete this.filterCanvas;
|
|
||||||
delete this.attrs;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Kinetic.Util.extend(Kinetic.Image, Kinetic.Shape);
|
Kinetic.Util.extend(Kinetic.Image, Kinetic.Shape);
|
||||||
|
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter = function(constructor, attr, def) {
|
|
||||||
this.addGetter(constructor, attr, def);
|
|
||||||
this.addFilterSetter(constructor, attr);
|
|
||||||
};
|
|
||||||
|
|
||||||
Kinetic.Factory.addFilterSetter = function(constructor, attr) {
|
|
||||||
var method = SET + Kinetic.Util._capitalize(attr);
|
|
||||||
|
|
||||||
constructor.prototype[method] = function(val) {
|
|
||||||
this._setAttr(attr, val);
|
|
||||||
this._applyFilter = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// add getters setters
|
// add getters setters
|
||||||
Kinetic.Factory.addGetterSetter(Kinetic.Image, 'image');
|
Kinetic.Factory.addGetterSetter(Kinetic.Image, 'image');
|
||||||
|
|
||||||
@@ -363,22 +271,4 @@
|
|||||||
* @memberof Kinetic.Image.prototype
|
* @memberof Kinetic.Image.prototype
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Image, 'filter');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set filter
|
|
||||||
* @name setFilter
|
|
||||||
* @method
|
|
||||||
* @memberof Kinetic.Image.prototype
|
|
||||||
* @param {Function} filter
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get filter
|
|
||||||
* @name getFilter
|
|
||||||
* @method
|
|
||||||
* @memberof Kinetic.Image.prototype
|
|
||||||
* @returns {Function}
|
|
||||||
*/
|
|
||||||
})();
|
})();
|
||||||
|
@@ -80,7 +80,6 @@
|
|||||||
|
|
||||||
<!-- filters -->
|
<!-- filters -->
|
||||||
<script src="unit/filters/Blur-test.js"></script>
|
<script src="unit/filters/Blur-test.js"></script>
|
||||||
<script src="unit/filters/QuickBlur-test.js"></script>
|
|
||||||
<script src="unit/filters/Brighten-test.js"></script>
|
<script src="unit/filters/Brighten-test.js"></script>
|
||||||
<script src="unit/filters/ColorPack-test.js"></script>
|
<script src="unit/filters/ColorPack-test.js"></script>
|
||||||
<script src="unit/filters/Invert-test.js"></script>
|
<script src="unit/filters/Invert-test.js"></script>
|
||||||
|
@@ -17,11 +17,25 @@ suite('Blur', function() {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
darth.setFilter(Kinetic.Filters.Blur);
|
darth.cache();
|
||||||
darth.setFilterRadius(10);
|
darth.filters([Kinetic.Filters.Blur]);
|
||||||
|
darth.blurRadius(10);
|
||||||
|
|
||||||
|
assert.equal(darth.blurRadius(), 10);
|
||||||
|
assert.equal(darth._filterUpToDate, false);
|
||||||
|
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
assert.equal(darth.getFilterRadius(), 10);
|
assert.equal(darth._filterUpToDate, true);
|
||||||
|
|
||||||
|
darth.blurRadius(20);
|
||||||
|
|
||||||
|
assert.equal(darth.blurRadius(), 20);
|
||||||
|
assert.equal(darth._filterUpToDate, false);
|
||||||
|
|
||||||
|
layer.draw();
|
||||||
|
|
||||||
|
assert.equal(darth._filterUpToDate, true);
|
||||||
|
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
@@ -29,6 +43,78 @@ suite('Blur', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('blur group', function(){
|
||||||
|
var stage = addStage();
|
||||||
|
var layer = new Kinetic.Layer();
|
||||||
|
var group = new Kinetic.Group({
|
||||||
|
x: 100,
|
||||||
|
y: 100,
|
||||||
|
draggable: true
|
||||||
|
});
|
||||||
|
var top = new Kinetic.Circle({
|
||||||
|
x: 0,
|
||||||
|
y: -70,
|
||||||
|
radius: 30,
|
||||||
|
fill: 'blue',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 4
|
||||||
|
});
|
||||||
|
var right = new Kinetic.Circle({
|
||||||
|
x: 70,
|
||||||
|
y: 0,
|
||||||
|
radius: 30,
|
||||||
|
fill: 'blue',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 4
|
||||||
|
});
|
||||||
|
var bottom = new Kinetic.Circle({
|
||||||
|
x: 0,
|
||||||
|
y: 70,
|
||||||
|
radius: 30,
|
||||||
|
fill: 'blue',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 4
|
||||||
|
});
|
||||||
|
var left = new Kinetic.Circle({
|
||||||
|
x: -70,
|
||||||
|
y: 0,
|
||||||
|
radius: 30,
|
||||||
|
fill: 'blue',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 4
|
||||||
|
});
|
||||||
|
|
||||||
|
group.add(top).add(right).add(bottom).add(left);
|
||||||
|
layer.add(group);
|
||||||
|
stage.add(layer);
|
||||||
|
|
||||||
|
group.cache({
|
||||||
|
x: -150,
|
||||||
|
y: -150,
|
||||||
|
width: 300,
|
||||||
|
height: 300
|
||||||
|
});
|
||||||
|
|
||||||
|
group.offset({
|
||||||
|
x: 150,
|
||||||
|
y: 150
|
||||||
|
});
|
||||||
|
|
||||||
|
group.filters([Kinetic.Filters.Blur]);
|
||||||
|
group.blurRadius(20);
|
||||||
|
|
||||||
|
layer.draw();
|
||||||
|
|
||||||
|
//document.body.appendChild(group._cache.canvas.scene._canvas);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
showHit(layer);
|
||||||
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
test('tween blur', function(done) {
|
test('tween blur', function(done) {
|
||||||
var stage = addStage();
|
var stage = addStage();
|
||||||
@@ -47,14 +133,15 @@ suite('Blur', function() {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
darth.setFilter(Kinetic.Filters.Blur);
|
darth.cache();
|
||||||
darth.setFilterRadius(100);
|
darth.filters([Kinetic.Filters.Blur]);
|
||||||
|
darth.blurRadius(100);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
var tween = new Kinetic.Tween({
|
var tween = new Kinetic.Tween({
|
||||||
node: darth,
|
node: darth,
|
||||||
duration: 2.0,
|
duration: 2.0,
|
||||||
filterRadius: 0,
|
blurRadius: 0,
|
||||||
easing: Kinetic.Easings.EaseInOut
|
easing: Kinetic.Easings.EaseInOut
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -91,8 +178,9 @@ suite('Blur', function() {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
darth.setFilter(Kinetic.Filters.Blur);
|
darth.cache();
|
||||||
darth.setFilterRadius(10);
|
darth.filters([Kinetic.Filters.Blur]);
|
||||||
|
darth.blurRadius(10);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@@ -120,14 +208,15 @@ suite('Blur', function() {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
darth.setFilter(Kinetic.Filters.Blur);
|
darth.cache();
|
||||||
darth.setFilterRadius(100);
|
darth.filters([Kinetic.Filters.Blur]);
|
||||||
|
darth.blurRadius(100);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
var tween = new Kinetic.Tween({
|
var tween = new Kinetic.Tween({
|
||||||
node: darth,
|
node: darth,
|
||||||
duration: 2.0,
|
duration: 2.0,
|
||||||
filterRadius: 0,
|
blurRadius: 0,
|
||||||
easing: Kinetic.Easings.EaseInOut
|
easing: Kinetic.Easings.EaseInOut
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -163,14 +252,15 @@ suite('Blur', function() {
|
|||||||
layer.add(darth);
|
layer.add(darth);
|
||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
darth.setFilter(Kinetic.Filters.Blur);
|
darth.cache();
|
||||||
darth.setFilterRadius(100);
|
darth.filters([Kinetic.Filters.Blur]);
|
||||||
|
darth.blurRadius(100);
|
||||||
layer.draw();
|
layer.draw();
|
||||||
|
|
||||||
var tween = new Kinetic.Tween({
|
var tween = new Kinetic.Tween({
|
||||||
node: darth,
|
node: darth,
|
||||||
duration: 2.0,
|
duration: 2.0,
|
||||||
filterRadius: 0,
|
blurRadius: 0,
|
||||||
easing: Kinetic.Easings.EaseInOut
|
easing: Kinetic.Easings.EaseInOut
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -189,64 +279,64 @@ suite('Blur', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
test('half layer gaussian blur', function (done) {
|
// test('half layer gaussian blur', function (done) {
|
||||||
var stage = addStage();
|
// var stage = addStage();
|
||||||
|
|
||||||
var shapesLayer = new Kinetic.Layer();
|
// var shapesLayer = new Kinetic.Layer();
|
||||||
|
|
||||||
// The important line!
|
// // The important line!
|
||||||
shapesLayer.on('draw', function () {
|
// shapesLayer.on('draw', function () {
|
||||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width/2,this.getCanvas().height);
|
// var imageData = this.getContext().getImageData(0,0,this.getCanvas().width/2,this.getCanvas().height);
|
||||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
// var scratchData = this.getContext().createImageData(imageData); // only size copied
|
||||||
Kinetic.Filters.Blur(imageData,scratchData,{filterRadius:24});
|
// Kinetic.Filters.Blur(imageData,scratchData,{filterRadius:24});
|
||||||
this.getContext().putImageData(scratchData,0,0);
|
// this.getContext().putImageData(scratchData,0,0);
|
||||||
});
|
// });
|
||||||
|
|
||||||
var triangle = new Kinetic.RegularPolygon({
|
// var triangle = new Kinetic.RegularPolygon({
|
||||||
x: stage.getWidth() / 4,
|
// x: stage.getWidth() / 4,
|
||||||
y: stage.getHeight() / 2,
|
// y: stage.getHeight() / 2,
|
||||||
sides: 3,
|
// sides: 3,
|
||||||
radius: 80,
|
// radius: 80,
|
||||||
fillRadialGradientEndRadius: 70,
|
// fillRadialGradientEndRadius: 70,
|
||||||
fillRadialGradientColorStops: [0, '#881111', 0.5, '#888811', 1, '#000088'],
|
// fillRadialGradientColorStops: [0, '#881111', 0.5, '#888811', 1, '#000088'],
|
||||||
stroke: 'black',
|
// stroke: 'black',
|
||||||
strokeWidth: 4,
|
// strokeWidth: 4,
|
||||||
draggable: true
|
// draggable: true
|
||||||
});
|
// });
|
||||||
|
|
||||||
var circle = new Kinetic.Circle({
|
// var circle = new Kinetic.Circle({
|
||||||
x: 3 * stage.getWidth() / 4,
|
// x: 3 * stage.getWidth() / 4,
|
||||||
y: stage.getHeight() / 2,
|
// y: stage.getHeight() / 2,
|
||||||
radius: 70,
|
// radius: 70,
|
||||||
fill: '#880000',
|
// fill: '#880000',
|
||||||
stroke: 'black',
|
// stroke: 'black',
|
||||||
strokeWidth: 4,
|
// strokeWidth: 4,
|
||||||
draggable: true,
|
// draggable: true,
|
||||||
id: 'myCircle'
|
// id: 'myCircle'
|
||||||
});
|
// });
|
||||||
|
|
||||||
for( var i=0; i<10; i+=1 ){
|
// for( var i=0; i<10; i+=1 ){
|
||||||
for( var j=0; j<10; j+=1 ){
|
// for( var j=0; j<10; j+=1 ){
|
||||||
var rect = new Kinetic.Rect({
|
// var rect = new Kinetic.Rect({
|
||||||
x: i/10*stage.getWidth(),
|
// x: i/10*stage.getWidth(),
|
||||||
y: j/10*stage.getHeight(),
|
// y: j/10*stage.getHeight(),
|
||||||
width: stage.getWidth()/10,
|
// width: stage.getWidth()/10,
|
||||||
height: stage.getHeight()/10,
|
// height: stage.getHeight()/10,
|
||||||
fill: (i+j)%2===0?'#FF0000':'#FFFF00',
|
// fill: (i+j)%2===0?'#FF0000':'#FFFF00',
|
||||||
stroke: 'black',
|
// stroke: 'black',
|
||||||
strokeWidth: 4,
|
// strokeWidth: 4,
|
||||||
draggable: true
|
// draggable: true
|
||||||
});
|
// });
|
||||||
shapesLayer.add(rect);
|
// shapesLayer.add(rect);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
shapesLayer.add(circle);
|
// shapesLayer.add(circle);
|
||||||
shapesLayer.add(triangle);
|
// shapesLayer.add(triangle);
|
||||||
|
|
||||||
stage.add(shapesLayer);
|
// stage.add(shapesLayer);
|
||||||
|
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
|
|
||||||
});
|
});
|
@@ -1,154 +0,0 @@
|
|||||||
suite('Quick Blur', function() {
|
|
||||||
|
|
||||||
// ======================================================
|
|
||||||
test('half layer blur', function (done) {
|
|
||||||
var stage = addStage();
|
|
||||||
|
|
||||||
var shapesLayer = new Kinetic.Layer();
|
|
||||||
|
|
||||||
// The important line!
|
|
||||||
shapesLayer.on('draw', function () {
|
|
||||||
var imageData = this.getContext().getImageData(0,0,this.getCanvas().width/2,this.getCanvas().height);
|
|
||||||
var scratchData = this.getContext().createImageData(imageData); // only size copied
|
|
||||||
Kinetic.Filters.BlurX(imageData,scratchData,{blurWidth:24});
|
|
||||||
Kinetic.Filters.BlurY(scratchData,imageData,{blurHeight:24});
|
|
||||||
this.getContext().putImageData(imageData,0,0);
|
|
||||||
});
|
|
||||||
|
|
||||||
var triangle = new Kinetic.RegularPolygon({
|
|
||||||
x: stage.getWidth() / 4,
|
|
||||||
y: stage.getHeight() / 2,
|
|
||||||
sides: 3,
|
|
||||||
radius: 80,
|
|
||||||
fillRadialGradientStartPoint: 0,
|
|
||||||
fillRadialGradientStartRadius: 0,
|
|
||||||
fillRadialGradientEndPoint: 0,
|
|
||||||
fillRadialGradientEndRadius: 70,
|
|
||||||
fillRadialGradientColorStops: [0, '#881111', 0.5, '#888811', 1, '#000088'],
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 4,
|
|
||||||
draggable: true
|
|
||||||
});
|
|
||||||
|
|
||||||
var circle = new Kinetic.Circle({
|
|
||||||
x: 3 * stage.getWidth() / 4,
|
|
||||||
y: stage.getHeight() / 2,
|
|
||||||
radius: 70,
|
|
||||||
fill: '#880000',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 4,
|
|
||||||
draggable: true,
|
|
||||||
id: 'myCircle'
|
|
||||||
});
|
|
||||||
|
|
||||||
for( var i=0; i<10; i+=1 ){
|
|
||||||
for( var j=0; j<10; j+=1 ){
|
|
||||||
var rect = new Kinetic.Rect({
|
|
||||||
x: i/10*stage.getWidth(),
|
|
||||||
y: j/10*stage.getHeight(),
|
|
||||||
width: stage.getWidth()/10,
|
|
||||||
height: stage.getHeight()/10,
|
|
||||||
fill: (i+j)%2===0?'#FF0000':'#FFFF00',
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 4,
|
|
||||||
draggable: true
|
|
||||||
});
|
|
||||||
shapesLayer.add(rect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shapesLayer.add(circle);
|
|
||||||
shapesLayer.add(triangle);
|
|
||||||
|
|
||||||
stage.add(shapesLayer);
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
// ======================================================
|
|
||||||
test('tween x blur', function(done) {
|
|
||||||
var stage = addStage();
|
|
||||||
|
|
||||||
var imageObj = new Image();
|
|
||||||
imageObj.onload = function() {
|
|
||||||
|
|
||||||
var layer = new Kinetic.Layer();
|
|
||||||
darth = new Kinetic.Image({
|
|
||||||
x: 10,
|
|
||||||
y: 10,
|
|
||||||
image: imageObj,
|
|
||||||
draggable: true
|
|
||||||
});
|
|
||||||
|
|
||||||
layer.add(darth);
|
|
||||||
stage.add(layer);
|
|
||||||
|
|
||||||
darth.setFilter(Kinetic.Filters.BlurX);
|
|
||||||
darth.setBlurWidth(100);
|
|
||||||
layer.draw();
|
|
||||||
|
|
||||||
var tween = new Kinetic.Tween({
|
|
||||||
node: darth,
|
|
||||||
duration: 2.0,
|
|
||||||
blurWidth: 0,
|
|
||||||
easing: Kinetic.Easings.EaseInOut
|
|
||||||
});
|
|
||||||
|
|
||||||
darth.on('mouseover', function() {
|
|
||||||
tween.play();
|
|
||||||
});
|
|
||||||
|
|
||||||
darth.on('mouseout', function() {
|
|
||||||
tween.reverse();
|
|
||||||
});
|
|
||||||
|
|
||||||
done();
|
|
||||||
|
|
||||||
};
|
|
||||||
imageObj.src = 'assets/darth-vader.jpg';
|
|
||||||
});
|
|
||||||
|
|
||||||
// ======================================================
|
|
||||||
test('tween y blur', function(done) {
|
|
||||||
var stage = addStage();
|
|
||||||
|
|
||||||
var imageObj = new Image();
|
|
||||||
imageObj.onload = function() {
|
|
||||||
|
|
||||||
var layer = new Kinetic.Layer();
|
|
||||||
darth = new Kinetic.Image({
|
|
||||||
x: 10,
|
|
||||||
y: 10,
|
|
||||||
image: imageObj,
|
|
||||||
draggable: true
|
|
||||||
});
|
|
||||||
|
|
||||||
layer.add(darth);
|
|
||||||
stage.add(layer);
|
|
||||||
|
|
||||||
darth.setFilter(Kinetic.Filters.BlurY);
|
|
||||||
darth.setBlurHeight(100);
|
|
||||||
layer.draw();
|
|
||||||
|
|
||||||
var tween = new Kinetic.Tween({
|
|
||||||
node: darth,
|
|
||||||
duration: 2.0,
|
|
||||||
blurHeight: 0,
|
|
||||||
easing: Kinetic.Easings.EaseInOut
|
|
||||||
});
|
|
||||||
|
|
||||||
darth.on('mouseover', function() {
|
|
||||||
tween.play();
|
|
||||||
});
|
|
||||||
|
|
||||||
darth.on('mouseout', function() {
|
|
||||||
tween.reverse();
|
|
||||||
});
|
|
||||||
|
|
||||||
done();
|
|
||||||
|
|
||||||
};
|
|
||||||
imageObj.src = 'assets/darth-vader.jpg';
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
Reference in New Issue
Block a user