mirror of
https://github.com/konvajs/konva.git
synced 2025-09-18 09:50:05 +08:00
beginning to prep for 5.0.0 release. Disabling Ripple and Kaleidoscope filters for now because they aren't quite ready
This commit is contained in:
@@ -24,10 +24,8 @@ module.exports = function(grunt) {
|
||||
'src/filters/Threshold.js',
|
||||
'src/filters/Sepia.js',
|
||||
'src/filters/Solarize.js',
|
||||
'src/filters/Ripple.js',
|
||||
'src/filters/Kaleidoscope.js',
|
||||
//'src/filters/FilterWrapper.js',
|
||||
//'src/filters/Polar.js',
|
||||
//'src/filters/Ripple.js',
|
||||
//'src/filters/Kaleidoscope.js',
|
||||
|
||||
// core
|
||||
'src/Animation.js',
|
||||
|
@@ -1,50 +0,0 @@
|
||||
(function () {
|
||||
Kinetic.Util._FilterWrapDoubleBuffer = function(filter,defaultOpt){
|
||||
return function(src,dst,opt) {
|
||||
// If no dst imageData is provided: make an imitation
|
||||
// blank one, the same size as the src image data
|
||||
var isOnlySrc = ! dst;
|
||||
var data = [],
|
||||
srcData = src.data,
|
||||
l = srcData.length, i;
|
||||
if( isOnlySrc ){
|
||||
dst = {
|
||||
width: src.width,
|
||||
height: src.height
|
||||
};
|
||||
for( i=0; i<l; i+=1 ){
|
||||
data.push(0);
|
||||
}
|
||||
dst.data = data;
|
||||
}
|
||||
|
||||
filter.call(this, src, dst, opt || defaultOpt);
|
||||
|
||||
// Copy the dst to the src if this was called the old way
|
||||
if( isOnlySrc ){
|
||||
var dstData = dst.data;
|
||||
for( i=0; i<l; i+=1 ){
|
||||
srcData[i] = dstData[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Kinetic.Util._FilterWrapSingleBuffer = function(filter,defaultOpt){
|
||||
return function(src,dst,opt) {
|
||||
// If no dst imageData is provided: use the src imageData
|
||||
filter.call(this, src, dst||src, opt || defaultOpt);
|
||||
};
|
||||
};
|
||||
|
||||
Kinetic.Util._FilterReplaceBuffer = function(src,dst){
|
||||
var i, l = src.length;
|
||||
for( i=0; i<l; ){
|
||||
dst[i] = src[i]; i++;
|
||||
dst[i] = src[i]; i++;
|
||||
dst[i] = src[i]; i++;
|
||||
dst[i] = src[i]; i++;
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
@@ -165,27 +165,27 @@
|
||||
* @memberof Kinetic.Filters
|
||||
* @param {Object} imageData
|
||||
*/
|
||||
Kinetic.Filters.Mask = function(idata) {
|
||||
Kinetic.Filters.Mask = function(imageData) {
|
||||
// Detect pixels close to the background color
|
||||
var threshold = this.threshold(),
|
||||
mask = backgroundMask(idata, threshold);
|
||||
mask = backgroundMask(imageData, threshold);
|
||||
if (mask) {
|
||||
// Erode
|
||||
mask = erodeMask(mask, idata.width, idata.height);
|
||||
mask = erodeMask(mask, imageData.width, imageData.height);
|
||||
|
||||
// Dilate
|
||||
mask = dilateMask(mask, idata.width, idata.height);
|
||||
mask = dilateMask(mask, imageData.width, imageData.height);
|
||||
|
||||
// Gradient
|
||||
mask = smoothEdgeMask(mask, idata.width, idata.height);
|
||||
mask = smoothEdgeMask(mask, imageData.width, imageData.height);
|
||||
|
||||
// Apply mask
|
||||
applyMask(idata, mask);
|
||||
applyMask(imageData, mask);
|
||||
|
||||
// todo : Update hit region function according to mask
|
||||
}
|
||||
|
||||
return idata;
|
||||
return imageData;
|
||||
};
|
||||
|
||||
Kinetic.Factory.addFilterGetterSetter(Kinetic.Node, 'threshold', 0);
|
||||
|
@@ -1,221 +0,0 @@
|
||||
(function () {
|
||||
|
||||
/**
|
||||
* ToPolar Filter. Converts image data to polar coordinates. Performs
|
||||
* w*h*4 pixel reads and w*h pixel writes. The r axis is placed along
|
||||
* what would be the y axis and the theta axis along the x axis.
|
||||
* @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.polarCenterX] horizontal location for the center of the circle,
|
||||
* default is in the middle
|
||||
* @param {Number} [opt.polarCenterY] vertical location for the center of the circle,
|
||||
* default is in the middle
|
||||
*/
|
||||
|
||||
var ToPolar = function(src,dst,opt){
|
||||
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
xMid = opt.polarCenterX || xSize/2,
|
||||
yMid = opt.polarCenterY || ySize/2,
|
||||
i, m, x, y, k, tmp, r=0,g=0,b=0,a=0;
|
||||
|
||||
// Find the largest radius
|
||||
var rad, rMax = Math.sqrt( xMid*xMid + yMid*yMid );
|
||||
x = xSize - xMid;
|
||||
y = ySize - yMid;
|
||||
rad = Math.sqrt( x*x + y*y );
|
||||
rMax = (rad > rMax)?rad:rMax;
|
||||
|
||||
// We'll be uisng y as the radius, and x as the angle (theta=t)
|
||||
var rSize = ySize,
|
||||
tSize = xSize,
|
||||
radius, theta;
|
||||
|
||||
// We want to cover all angles (0-360) and we need to convert to
|
||||
// radians (*PI/180)
|
||||
var conversion = 360/tSize*Math.PI/180, sin, cos;
|
||||
|
||||
var x1, x2, x1i, x2i, y1, y2, y1i, y2i, scale;
|
||||
|
||||
for( theta=0; theta<tSize; theta+=1 ){
|
||||
sin = Math.sin(theta*conversion);
|
||||
cos = Math.cos(theta*conversion);
|
||||
for( radius=0; radius<rSize; radius+=1 ){
|
||||
x = xMid+rMax*radius/rSize*cos;
|
||||
y = yMid+rMax*radius/rSize*sin;
|
||||
if( x <= 1 ){ x = 1; }
|
||||
if( x >= xSize-0.5 ){ x = xSize-1; }
|
||||
if( y <= 1 ){ y = 1; }
|
||||
if( y >= ySize-0.5 ){ y = ySize-1; }
|
||||
|
||||
// Interpolate x and y by going +-0.5 around the pixel's central point
|
||||
// this gives us the 4 nearest pixels to our 1x1 non-aligned pixel.
|
||||
// We average the vaules of those pixels based on how much of our
|
||||
// non-aligned pixel overlaps each of them.
|
||||
x1 = x - 0.5;
|
||||
x2 = x + 0.5;
|
||||
x1i = Math.floor(x1);
|
||||
x2i = Math.floor(x2);
|
||||
y1 = y - 0.5;
|
||||
y2 = y + 0.5;
|
||||
y1i = Math.floor(y1);
|
||||
y2i = Math.floor(y2);
|
||||
|
||||
scale = (1-(x1-x1i))*(1-(y1-y1i));
|
||||
i = (y1i*xSize + x1i)*4;
|
||||
r = srcPixels[i+0]*scale;
|
||||
g = srcPixels[i+1]*scale;
|
||||
b = srcPixels[i+2]*scale;
|
||||
a = srcPixels[i+3]*scale;
|
||||
|
||||
scale = (1-(x1-x1i))*(y2-y2i);
|
||||
i = (y2i*xSize + x1i)*4;
|
||||
r += srcPixels[i+0]*scale;
|
||||
g += srcPixels[i+1]*scale;
|
||||
b += srcPixels[i+2]*scale;
|
||||
a += srcPixels[i+3]*scale;
|
||||
|
||||
scale = (x2-x2i)*(y2-y2i);
|
||||
i = (y2i*xSize + x2i)*4;
|
||||
r += srcPixels[i+0]*scale;
|
||||
g += srcPixels[i+1]*scale;
|
||||
b += srcPixels[i+2]*scale;
|
||||
a += srcPixels[i+3]*scale;
|
||||
|
||||
scale = (x2-x2i)*(1-(y1-y1i));
|
||||
i = (y1i*xSize + x2i)*4;
|
||||
r += srcPixels[i+0]*scale;
|
||||
g += srcPixels[i+1]*scale;
|
||||
b += srcPixels[i+2]*scale;
|
||||
a += srcPixels[i+3]*scale;
|
||||
|
||||
// Store it
|
||||
//i = (theta * xSize + radius) * 4;
|
||||
i = (theta + radius*xSize) * 4;
|
||||
dstPixels[i+0] = r;
|
||||
dstPixels[i+1] = g;
|
||||
dstPixels[i+2] = b;
|
||||
dstPixels[i+3] = a;
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* FromPolar Filter. Converts image data from polar coordinates back to rectangular.
|
||||
* Performs w*h*4 pixel reads and w*h pixel writes.
|
||||
* @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.polarCenterX] horizontal location for the center of the circle,
|
||||
* default is in the middle
|
||||
* @param {Number} [opt.polarCenterY] vertical location for the center of the circle,
|
||||
* default is in the middle
|
||||
* @param {Number} [opt.polarRotation] amount to rotate the image counterclockwis,
|
||||
* 0 is no rotation, 360 degrees is a full rotation
|
||||
*/
|
||||
|
||||
var FromPolar = function(src,dst,opt){
|
||||
|
||||
var srcPixels = src.data,
|
||||
dstPixels = dst.data,
|
||||
xSize = src.width,
|
||||
ySize = src.height,
|
||||
xMid = opt.polarCenterX || xSize/2,
|
||||
yMid = opt.polarCenterY || ySize/2,
|
||||
i, m, x, y, dx, dy, k, tmp, r=0,g=0,b=0,a=0;
|
||||
|
||||
|
||||
// Find the largest radius
|
||||
var rad, rMax = Math.sqrt( xMid*xMid + yMid*yMid );
|
||||
x = xSize - xMid;
|
||||
y = ySize - yMid;
|
||||
rad = Math.sqrt( x*x + y*y );
|
||||
rMax = (rad > rMax)?rad:rMax;
|
||||
|
||||
// We'll be uisng x as the radius, and y as the angle (theta=t)
|
||||
var rSize = ySize,
|
||||
tSize = xSize,
|
||||
radius, theta,
|
||||
phaseShift = opt.polarRotation || 0;
|
||||
|
||||
// We need to convert to degrees and we need to make sure
|
||||
// it's between (0-360)
|
||||
// var conversion = tSize/360*180/Math.PI;
|
||||
var conversion = tSize/360*180/Math.PI;
|
||||
|
||||
var x1, x2, x1i, x2i, y1, y2, y1i, y2i, scale;
|
||||
|
||||
for( x=0; x<xSize; x+=1 ){
|
||||
for( y=0; y<ySize; y+=1 ){
|
||||
dx = x - xMid;
|
||||
dy = y - yMid;
|
||||
radius = Math.sqrt(dx*dx + dy*dy)*rSize/rMax;
|
||||
theta = (Math.atan2(dy,dx)*180/Math.PI + 360 + phaseShift)%360;
|
||||
theta = theta*tSize/360;
|
||||
|
||||
// Interpolate x and y by going +-0.5 around the pixel's central point
|
||||
// this gives us the 4 nearest pixels to our 1x1 non-aligned pixel.
|
||||
// We average the vaules of those pixels based on how much of our
|
||||
// non-aligned pixel overlaps each of them.
|
||||
x1 = theta - 0.5;
|
||||
x2 = theta + 0.5;
|
||||
x1i = Math.floor(x1);
|
||||
x2i = Math.floor(x2);
|
||||
y1 = radius - 0.5;
|
||||
y2 = radius + 0.5;
|
||||
y1i = Math.floor(y1);
|
||||
y2i = Math.floor(y2);
|
||||
|
||||
scale = (1-(x1-x1i))*(1-(y1-y1i));
|
||||
i = (y1i*xSize + x1i)*4;
|
||||
r = srcPixels[i+0]*scale;
|
||||
g = srcPixels[i+1]*scale;
|
||||
b = srcPixels[i+2]*scale;
|
||||
a = srcPixels[i+3]*scale;
|
||||
|
||||
scale = (1-(x1-x1i))*(y2-y2i);
|
||||
i = (y2i*xSize + x1i)*4;
|
||||
r += srcPixels[i+0]*scale;
|
||||
g += srcPixels[i+1]*scale;
|
||||
b += srcPixels[i+2]*scale;
|
||||
a += srcPixels[i+3]*scale;
|
||||
|
||||
scale = (x2-x2i)*(y2-y2i);
|
||||
i = (y2i*xSize + x2i)*4;
|
||||
r += srcPixels[i+0]*scale;
|
||||
g += srcPixels[i+1]*scale;
|
||||
b += srcPixels[i+2]*scale;
|
||||
a += srcPixels[i+3]*scale;
|
||||
|
||||
scale = (x2-x2i)*(1-(y1-y1i));
|
||||
i = (y1i*xSize + x2i)*4;
|
||||
r += srcPixels[i+0]*scale;
|
||||
g += srcPixels[i+1]*scale;
|
||||
b += srcPixels[i+2]*scale;
|
||||
a += srcPixels[i+3]*scale;
|
||||
|
||||
// Store it
|
||||
i = (y*xSize + x)*4;
|
||||
dstPixels[i+0] = r;
|
||||
dstPixels[i+1] = g;
|
||||
dstPixels[i+2] = b;
|
||||
dstPixels[i+3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Kinetic.Filters.ToPolar = Kinetic.Util._FilterWrapDoubleBuffer(ToPolar);
|
||||
Kinetic.Filters.FromPolar = Kinetic.Util._FilterWrapDoubleBuffer(FromPolar);
|
||||
})();
|
@@ -87,7 +87,6 @@
|
||||
<script src="unit/filters/Mask-test.js"></script>
|
||||
<script src="unit/filters/Grayscale-test.js"></script>
|
||||
<script src="unit/filters/Enhance-test.js"></script>
|
||||
<!--<script src="unit/filters/Polar-test.js"></script>-->
|
||||
<script src="unit/filters/Pixelate-test.js"></script>
|
||||
<script src="unit/filters/Noise-test.js"></script>
|
||||
<script src="unit/filters/Threshold-test.js"></script>
|
||||
@@ -95,8 +94,11 @@
|
||||
<script src="unit/filters/Sepia-test.js"></script>
|
||||
<script src="unit/filters/Emboss-test.js"></script>
|
||||
<script src="unit/filters/Solarize-test.js"></script>
|
||||
|
||||
<!--
|
||||
<script src="unit/filters/Ripple-test.js"></script>
|
||||
<script src="unit/filters/Kaleidoscope-test.js"></script>
|
||||
-->
|
||||
|
||||
|
||||
<!--=============== functional tests ================-->
|
||||
|
Reference in New Issue
Block a user