fix Konva.Transformer for shapes with offset. close #386

This commit is contained in:
Anton Lavrenov 2018-05-17 13:08:29 +09:00
parent 74d3a12921
commit c08de940e4
12 changed files with 576 additions and 553 deletions

View File

@ -5,6 +5,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [new version][unreleased]
## Fixed
* `Konva.Transformer` automatically track shape changes
* `Konva.Transformer` works with shapes with offset too
## [2.1.2][2018-05-16]
## Fixed

547
konva.js
View File

@ -4919,31 +4919,34 @@
Konva.Collection.mapMethods(Konva.Node);
})(Konva);
(function() {
'use strict';
/**
* Grayscale Filter
* @function
* @memberof Konva.Filters
* @param {Object} imageData
* @example
* node.cache();
* node.filters([Konva.Filters.Grayscale]);
*/
Konva.Filters.Grayscale = function(imageData) {
var data = imageData.data, len = data.length, i, brightness;
for (i = 0; i < len; i += 4) {
brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
// red
data[i] = brightness;
// green
data[i + 1] = brightness;
// blue
data[i + 2] = brightness;
}
};
})();
(function() {
'use strict';
/**
* Grayscale Filter
* @function
* @memberof Konva.Filters
* @param {Object} imageData
* @example
* node.cache();
* node.filters([Konva.Filters.Grayscale]);
*/
Konva.Filters.Grayscale = function(imageData) {
var data = imageData.data,
len = data.length,
i,
brightness;
for (i = 0; i < len; i += 4) {
brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
// red
data[i] = brightness;
// green
data[i + 1] = brightness;
// blue
data[i + 2] = brightness;
}
};
})();
(function(Konva) {
'use strict';
@ -4991,30 +4994,32 @@
*/
})(Konva);
(function() {
'use strict';
/**
* Invert Filter
* @function
* @memberof Konva.Filters
* @param {Object} imageData
* @example
* node.cache();
* node.filters([Konva.Filters.Invert]);
*/
Konva.Filters.Invert = function(imageData) {
var data = imageData.data, len = data.length, i;
for (i = 0; i < len; i += 4) {
// red
data[i] = 255 - data[i];
// green
data[i + 1] = 255 - data[i + 1];
// blue
data[i + 2] = 255 - data[i + 2];
}
};
})();
(function() {
'use strict';
/**
* Invert Filter
* @function
* @memberof Konva.Filters
* @param {Object} imageData
* @example
* node.cache();
* node.filters([Konva.Filters.Invert]);
*/
Konva.Filters.Invert = function(imageData) {
var data = imageData.data,
len = data.length,
i;
for (i = 0; i < len; i += 4) {
// red
data[i] = 255 - data[i];
// green
data[i + 1] = 255 - data[i + 1];
// blue
data[i + 2] = 255 - data[i + 2];
}
};
})();
/*
the Gauss filter
@ -6920,216 +6925,216 @@
*/
})();
(function() {
'use strict';
/**
* Noise Filter. Randomly adds or substracts to the color channels
* @function
* @name Noise
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Noise]);
* node.noise(0.8);
*/
Konva.Filters.Noise = function(imageData) {
var amount = this.noise() * 255,
data = imageData.data,
nPixels = data.length,
half = amount / 2,
i;
for (i = 0; i < nPixels; i += 4) {
data[i + 0] += half - 2 * half * Math.random();
data[i + 1] += half - 2 * half * Math.random();
data[i + 2] += half - 2 * half * Math.random();
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'noise',
0.2,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set noise amount. Must be a value between 0 and 1. Use with {@link Konva.Filters.Noise} filter.
* @name noise
* @method
* @memberof Konva.Node.prototype
* @param {Number} noise
* @returns {Number}
*/
})();
(function() {
'use strict';
/**
* Noise Filter. Randomly adds or substracts to the color channels
* @function
* @name Noise
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Noise]);
* node.noise(0.8);
*/
Konva.Filters.Noise = function(imageData) {
var amount = this.noise() * 255,
data = imageData.data,
nPixels = data.length,
half = amount / 2,
i;
/*eslint-disable max-depth */
(function() {
'use strict';
/**
* Pixelate Filter. Averages groups of pixels and redraws
* them as larger pixels
* @function
* @name Pixelate
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Pixelate]);
* node.pixelSize(10);
*/
Konva.Filters.Pixelate = function(imageData) {
var pixelSize = Math.ceil(this.pixelSize()),
width = imageData.width,
height = imageData.height,
x,
y,
i,
//pixelsPerBin = pixelSize * pixelSize,
red,
green,
blue,
alpha,
nBinsX = Math.ceil(width / pixelSize),
nBinsY = Math.ceil(height / pixelSize),
xBinStart,
xBinEnd,
yBinStart,
yBinEnd,
xBin,
yBin,
pixelsInBin;
imageData = imageData.data;
if (pixelSize <= 0) {
Konva.Util.error('pixelSize value can not be <= 0');
return;
}
for (xBin = 0; xBin < nBinsX; xBin += 1) {
for (yBin = 0; yBin < nBinsY; yBin += 1) {
// Initialize the color accumlators to 0
red = 0;
green = 0;
blue = 0;
alpha = 0;
// Determine which pixels are included in this bin
xBinStart = xBin * pixelSize;
xBinEnd = xBinStart + pixelSize;
yBinStart = yBin * pixelSize;
yBinEnd = yBinStart + pixelSize;
// Add all of the pixels to this bin!
pixelsInBin = 0;
for (x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) {
continue;
}
for (y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) {
continue;
}
i = (width * y + x) * 4;
red += imageData[i + 0];
green += imageData[i + 1];
blue += imageData[i + 2];
alpha += imageData[i + 3];
pixelsInBin += 1;
}
}
// Make sure the channels are between 0-255
red = red / pixelsInBin;
green = green / pixelsInBin;
blue = blue / pixelsInBin;
alpha = alpha / pixelsInBin;
// Draw this bin
for (x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) {
continue;
}
for (y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) {
continue;
}
i = (width * y + x) * 4;
imageData[i + 0] = red;
imageData[i + 1] = green;
imageData[i + 2] = blue;
imageData[i + 3] = alpha;
}
}
}
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'pixelSize',
8,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set pixel size. Use with {@link Konva.Filters.Pixelate} filter.
* @name pixelSize
* @method
* @memberof Konva.Node.prototype
* @param {Integer} pixelSize
* @returns {Integer}
*/
})();
for (i = 0; i < nPixels; i += 4) {
data[i + 0] += half - 2 * half * Math.random();
data[i + 1] += half - 2 * half * Math.random();
data[i + 2] += half - 2 * half * Math.random();
}
};
(function() {
'use strict';
/**
* Threshold Filter. Pushes any value above the mid point to
* the max and any value below the mid point to the min.
* This affects the alpha channel.
* @function
* @name Threshold
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Threshold]);
* node.threshold(0.1);
*/
Konva.Filters.Threshold = function(imageData) {
var level = this.threshold() * 255,
data = imageData.data,
len = data.length,
i;
for (i = 0; i < len; i += 1) {
data[i] = data[i] < level ? 0 : 255;
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'threshold',
0.5,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set threshold. Must be a value between 0 and 1. Use with {@link Konva.Filters.Threshold} or {@link Konva.Filters.Mask} filter.
* @name threshold
* @method
* @memberof Konva.Node.prototype
* @param {Number} threshold
* @returns {Number}
*/
})();
Konva.Factory.addGetterSetter(
Konva.Node,
'noise',
0.2,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set noise amount. Must be a value between 0 and 1. Use with {@link Konva.Filters.Noise} filter.
* @name noise
* @method
* @memberof Konva.Node.prototype
* @param {Number} noise
* @returns {Number}
*/
})();
/*eslint-disable max-depth */
(function() {
'use strict';
/**
* Pixelate Filter. Averages groups of pixels and redraws
* them as larger pixels
* @function
* @name Pixelate
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Pixelate]);
* node.pixelSize(10);
*/
Konva.Filters.Pixelate = function(imageData) {
var pixelSize = Math.ceil(this.pixelSize()),
width = imageData.width,
height = imageData.height,
x,
y,
i,
//pixelsPerBin = pixelSize * pixelSize,
red,
green,
blue,
alpha,
nBinsX = Math.ceil(width / pixelSize),
nBinsY = Math.ceil(height / pixelSize),
xBinStart,
xBinEnd,
yBinStart,
yBinEnd,
xBin,
yBin,
pixelsInBin;
imageData = imageData.data;
if (pixelSize <= 0) {
Konva.Util.error('pixelSize value can not be <= 0');
return;
}
for (xBin = 0; xBin < nBinsX; xBin += 1) {
for (yBin = 0; yBin < nBinsY; yBin += 1) {
// Initialize the color accumlators to 0
red = 0;
green = 0;
blue = 0;
alpha = 0;
// Determine which pixels are included in this bin
xBinStart = xBin * pixelSize;
xBinEnd = xBinStart + pixelSize;
yBinStart = yBin * pixelSize;
yBinEnd = yBinStart + pixelSize;
// Add all of the pixels to this bin!
pixelsInBin = 0;
for (x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) {
continue;
}
for (y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) {
continue;
}
i = (width * y + x) * 4;
red += imageData[i + 0];
green += imageData[i + 1];
blue += imageData[i + 2];
alpha += imageData[i + 3];
pixelsInBin += 1;
}
}
// Make sure the channels are between 0-255
red = red / pixelsInBin;
green = green / pixelsInBin;
blue = blue / pixelsInBin;
alpha = alpha / pixelsInBin;
// Draw this bin
for (x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) {
continue;
}
for (y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) {
continue;
}
i = (width * y + x) * 4;
imageData[i + 0] = red;
imageData[i + 1] = green;
imageData[i + 2] = blue;
imageData[i + 3] = alpha;
}
}
}
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'pixelSize',
8,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set pixel size. Use with {@link Konva.Filters.Pixelate} filter.
* @name pixelSize
* @method
* @memberof Konva.Node.prototype
* @param {Integer} pixelSize
* @returns {Integer}
*/
})();
(function() {
'use strict';
/**
* Threshold Filter. Pushes any value above the mid point to
* the max and any value below the mid point to the min.
* This affects the alpha channel.
* @function
* @name Threshold
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Threshold]);
* node.threshold(0.1);
*/
Konva.Filters.Threshold = function(imageData) {
var level = this.threshold() * 255,
data = imageData.data,
len = data.length,
i;
for (i = 0; i < len; i += 1) {
data[i] = data[i] < level ? 0 : 255;
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'threshold',
0.5,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set threshold. Must be a value between 0 and 1. Use with {@link Konva.Filters.Threshold} or {@link Konva.Filters.Mask} filter.
* @name threshold
* @method
* @memberof Konva.Node.prototype
* @param {Number} threshold
* @returns {Number}
*/
})();
(function() {
'use strict';
@ -10946,14 +10951,14 @@
(function(Konva) {
'use strict';
/**
* BaseLayer constructor.
* @constructor
* @memberof Konva
* @augments Konva.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* @param {Number} [config.x]
* BaseLayer constructor.
* @constructor
* @memberof Konva
* @augments Konva.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* @param {Number} [config.x]
* @param {Number} [config.y]
* @param {Number} [config.width]
* @param {Number} [config.height]
@ -10973,14 +10978,14 @@
* the entire stage by dragging any portion of the stage
* @param {Number} [config.dragDistance]
* @param {Function} [config.dragBoundFunc]
* * @param {Object} [config.clip] set clip
* * @param {Object} [config.clip] set clip
* @param {Number} [config.clipX] set clip x
* @param {Number} [config.clipY] set clip y
* @param {Number} [config.clipWidth] set clip width
* @param {Number} [config.clipHeight] set clip height
* @param {Function} [config.clipFunc] set clip func
*/
*/
Konva.BaseLayer = function(config) {
this.___init(config);
};
@ -18864,8 +18869,8 @@
var rect = node.getClientRect({ skipTransform: true });
var rotation = Konva.getAngle(node.rotation());
var dx = rect.x * node.scaleX() - node.offsetX();
var dy = rect.y * node.scaleY() - node.offsetY();
var dx = rect.x * node.scaleX() - node.offsetX() * node.scaleX();
var dy = rect.y * node.scaleY() - node.offsetY() * node.scaleY();
return {
x: node.x() + dx * Math.cos(rotation) + dy * Math.sin(-rotation),
@ -19235,8 +19240,8 @@
var scaleY = (newAttrs.height - padding * 2) / pure.height;
var rotation = Konva.getAngle(node.getRotation());
var dx = pure.x * scaleX - padding;
var dy = pure.y * scaleY - padding;
var dx = pure.x * scaleX - padding - node.offsetX() * scaleX;
var dy = pure.y * scaleY - padding - node.offsetY() * scaleY;
this.getNode().setAttrs({
scaleX: scaleX,

2
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -57,5 +57,6 @@
"type": "git",
"url": "git://github.com/konvajs/konva.git"
},
"license": "MIT"
"license": "MIT",
"dependencies": {}
}

View File

@ -1,16 +1,16 @@
(function(Konva) {
'use strict';
/**
* BaseLayer constructor.
* @constructor
* @memberof Konva
* @augments Konva.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* @@nodeParams
* @@containerParams
*/
* BaseLayer constructor.
* @constructor
* @memberof Konva
* @augments Konva.Container
* @param {Object} config
* @param {Boolean} [config.clearBeforeDraw] set this property to false if you don't want
* to clear the canvas before each layer draw. The default value is true.
* @@nodeParams
* @@containerParams
*/
Konva.BaseLayer = function(config) {
this.___init(config);
};

View File

@ -1,25 +1,28 @@
(function() {
'use strict';
/**
* Grayscale Filter
* @function
* @memberof Konva.Filters
* @param {Object} imageData
* @example
* node.cache();
* node.filters([Konva.Filters.Grayscale]);
*/
Konva.Filters.Grayscale = function(imageData) {
var data = imageData.data, len = data.length, i, brightness;
for (i = 0; i < len; i += 4) {
brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
// red
data[i] = brightness;
// green
data[i + 1] = brightness;
// blue
data[i + 2] = brightness;
}
};
})();
(function() {
'use strict';
/**
* Grayscale Filter
* @function
* @memberof Konva.Filters
* @param {Object} imageData
* @example
* node.cache();
* node.filters([Konva.Filters.Grayscale]);
*/
Konva.Filters.Grayscale = function(imageData) {
var data = imageData.data,
len = data.length,
i,
brightness;
for (i = 0; i < len; i += 4) {
brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
// red
data[i] = brightness;
// green
data[i + 1] = brightness;
// blue
data[i + 2] = brightness;
}
};
})();

View File

@ -1,24 +1,26 @@
(function() {
'use strict';
/**
* Invert Filter
* @function
* @memberof Konva.Filters
* @param {Object} imageData
* @example
* node.cache();
* node.filters([Konva.Filters.Invert]);
*/
Konva.Filters.Invert = function(imageData) {
var data = imageData.data, len = data.length, i;
for (i = 0; i < len; i += 4) {
// red
data[i] = 255 - data[i];
// green
data[i + 1] = 255 - data[i + 1];
// blue
data[i + 2] = 255 - data[i + 2];
}
};
})();
(function() {
'use strict';
/**
* Invert Filter
* @function
* @memberof Konva.Filters
* @param {Object} imageData
* @example
* node.cache();
* node.filters([Konva.Filters.Invert]);
*/
Konva.Filters.Invert = function(imageData) {
var data = imageData.data,
len = data.length,
i;
for (i = 0; i < len; i += 4) {
// red
data[i] = 255 - data[i];
// green
data[i + 1] = 255 - data[i + 1];
// blue
data[i + 2] = 255 - data[i + 2];
}
};
})();

View File

@ -1,44 +1,44 @@
(function() {
'use strict';
/**
* Noise Filter. Randomly adds or substracts to the color channels
* @function
* @name Noise
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Noise]);
* node.noise(0.8);
*/
Konva.Filters.Noise = function(imageData) {
var amount = this.noise() * 255,
data = imageData.data,
nPixels = data.length,
half = amount / 2,
i;
for (i = 0; i < nPixels; i += 4) {
data[i + 0] += half - 2 * half * Math.random();
data[i + 1] += half - 2 * half * Math.random();
data[i + 2] += half - 2 * half * Math.random();
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'noise',
0.2,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set noise amount. Must be a value between 0 and 1. Use with {@link Konva.Filters.Noise} filter.
* @name noise
* @method
* @memberof Konva.Node.prototype
* @param {Number} noise
* @returns {Number}
*/
})();
(function() {
'use strict';
/**
* Noise Filter. Randomly adds or substracts to the color channels
* @function
* @name Noise
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Noise]);
* node.noise(0.8);
*/
Konva.Filters.Noise = function(imageData) {
var amount = this.noise() * 255,
data = imageData.data,
nPixels = data.length,
half = amount / 2,
i;
for (i = 0; i < nPixels; i += 4) {
data[i + 0] += half - 2 * half * Math.random();
data[i + 1] += half - 2 * half * Math.random();
data[i + 2] += half - 2 * half * Math.random();
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'noise',
0.2,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set noise amount. Must be a value between 0 and 1. Use with {@link Konva.Filters.Noise} filter.
* @name noise
* @method
* @memberof Konva.Node.prototype
* @param {Number} noise
* @returns {Number}
*/
})();

View File

@ -1,120 +1,120 @@
/*eslint-disable max-depth */
(function() {
'use strict';
/**
* Pixelate Filter. Averages groups of pixels and redraws
* them as larger pixels
* @function
* @name Pixelate
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Pixelate]);
* node.pixelSize(10);
*/
Konva.Filters.Pixelate = function(imageData) {
var pixelSize = Math.ceil(this.pixelSize()),
width = imageData.width,
height = imageData.height,
x,
y,
i,
//pixelsPerBin = pixelSize * pixelSize,
red,
green,
blue,
alpha,
nBinsX = Math.ceil(width / pixelSize),
nBinsY = Math.ceil(height / pixelSize),
xBinStart,
xBinEnd,
yBinStart,
yBinEnd,
xBin,
yBin,
pixelsInBin;
imageData = imageData.data;
if (pixelSize <= 0) {
Konva.Util.error('pixelSize value can not be <= 0');
return;
}
for (xBin = 0; xBin < nBinsX; xBin += 1) {
for (yBin = 0; yBin < nBinsY; yBin += 1) {
// Initialize the color accumlators to 0
red = 0;
green = 0;
blue = 0;
alpha = 0;
// Determine which pixels are included in this bin
xBinStart = xBin * pixelSize;
xBinEnd = xBinStart + pixelSize;
yBinStart = yBin * pixelSize;
yBinEnd = yBinStart + pixelSize;
// Add all of the pixels to this bin!
pixelsInBin = 0;
for (x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) {
continue;
}
for (y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) {
continue;
}
i = (width * y + x) * 4;
red += imageData[i + 0];
green += imageData[i + 1];
blue += imageData[i + 2];
alpha += imageData[i + 3];
pixelsInBin += 1;
}
}
// Make sure the channels are between 0-255
red = red / pixelsInBin;
green = green / pixelsInBin;
blue = blue / pixelsInBin;
alpha = alpha / pixelsInBin;
// Draw this bin
for (x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) {
continue;
}
for (y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) {
continue;
}
i = (width * y + x) * 4;
imageData[i + 0] = red;
imageData[i + 1] = green;
imageData[i + 2] = blue;
imageData[i + 3] = alpha;
}
}
}
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'pixelSize',
8,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set pixel size. Use with {@link Konva.Filters.Pixelate} filter.
* @name pixelSize
* @method
* @memberof Konva.Node.prototype
* @param {Integer} pixelSize
* @returns {Integer}
*/
})();
/*eslint-disable max-depth */
(function() {
'use strict';
/**
* Pixelate Filter. Averages groups of pixels and redraws
* them as larger pixels
* @function
* @name Pixelate
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Pixelate]);
* node.pixelSize(10);
*/
Konva.Filters.Pixelate = function(imageData) {
var pixelSize = Math.ceil(this.pixelSize()),
width = imageData.width,
height = imageData.height,
x,
y,
i,
//pixelsPerBin = pixelSize * pixelSize,
red,
green,
blue,
alpha,
nBinsX = Math.ceil(width / pixelSize),
nBinsY = Math.ceil(height / pixelSize),
xBinStart,
xBinEnd,
yBinStart,
yBinEnd,
xBin,
yBin,
pixelsInBin;
imageData = imageData.data;
if (pixelSize <= 0) {
Konva.Util.error('pixelSize value can not be <= 0');
return;
}
for (xBin = 0; xBin < nBinsX; xBin += 1) {
for (yBin = 0; yBin < nBinsY; yBin += 1) {
// Initialize the color accumlators to 0
red = 0;
green = 0;
blue = 0;
alpha = 0;
// Determine which pixels are included in this bin
xBinStart = xBin * pixelSize;
xBinEnd = xBinStart + pixelSize;
yBinStart = yBin * pixelSize;
yBinEnd = yBinStart + pixelSize;
// Add all of the pixels to this bin!
pixelsInBin = 0;
for (x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) {
continue;
}
for (y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) {
continue;
}
i = (width * y + x) * 4;
red += imageData[i + 0];
green += imageData[i + 1];
blue += imageData[i + 2];
alpha += imageData[i + 3];
pixelsInBin += 1;
}
}
// Make sure the channels are between 0-255
red = red / pixelsInBin;
green = green / pixelsInBin;
blue = blue / pixelsInBin;
alpha = alpha / pixelsInBin;
// Draw this bin
for (x = xBinStart; x < xBinEnd; x += 1) {
if (x >= width) {
continue;
}
for (y = yBinStart; y < yBinEnd; y += 1) {
if (y >= height) {
continue;
}
i = (width * y + x) * 4;
imageData[i + 0] = red;
imageData[i + 1] = green;
imageData[i + 2] = blue;
imageData[i + 3] = alpha;
}
}
}
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'pixelSize',
8,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set pixel size. Use with {@link Konva.Filters.Pixelate} filter.
* @name pixelSize
* @method
* @memberof Konva.Node.prototype
* @param {Integer} pixelSize
* @returns {Integer}
*/
})();

View File

@ -1,44 +1,44 @@
(function() {
'use strict';
/**
* Threshold Filter. Pushes any value above the mid point to
* the max and any value below the mid point to the min.
* This affects the alpha channel.
* @function
* @name Threshold
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Threshold]);
* node.threshold(0.1);
*/
Konva.Filters.Threshold = function(imageData) {
var level = this.threshold() * 255,
data = imageData.data,
len = data.length,
i;
for (i = 0; i < len; i += 1) {
data[i] = data[i] < level ? 0 : 255;
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'threshold',
0.5,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set threshold. Must be a value between 0 and 1. Use with {@link Konva.Filters.Threshold} or {@link Konva.Filters.Mask} filter.
* @name threshold
* @method
* @memberof Konva.Node.prototype
* @param {Number} threshold
* @returns {Number}
*/
})();
(function() {
'use strict';
/**
* Threshold Filter. Pushes any value above the mid point to
* the max and any value below the mid point to the min.
* This affects the alpha channel.
* @function
* @name Threshold
* @memberof Konva.Filters
* @param {Object} imageData
* @author ippo615
* @example
* node.cache();
* node.filters([Konva.Filters.Threshold]);
* node.threshold(0.1);
*/
Konva.Filters.Threshold = function(imageData) {
var level = this.threshold() * 255,
data = imageData.data,
len = data.length,
i;
for (i = 0; i < len; i += 1) {
data[i] = data[i] < level ? 0 : 255;
}
};
Konva.Factory.addGetterSetter(
Konva.Node,
'threshold',
0.5,
null,
Konva.Factory.afterSetFilter
);
/**
* get/set threshold. Must be a value between 0 and 1. Use with {@link Konva.Filters.Threshold} or {@link Konva.Filters.Mask} filter.
* @name threshold
* @method
* @memberof Konva.Node.prototype
* @param {Number} threshold
* @returns {Number}
*/
})();

View File

@ -240,8 +240,8 @@
var rect = node.getClientRect({ skipTransform: true });
var rotation = Konva.getAngle(node.rotation());
var dx = rect.x * node.scaleX() - node.offsetX();
var dy = rect.y * node.scaleY() - node.offsetY();
var dx = rect.x * node.scaleX() - node.offsetX() * node.scaleX();
var dy = rect.y * node.scaleY() - node.offsetY() * node.scaleY();
return {
x: node.x() + dx * Math.cos(rotation) + dy * Math.sin(-rotation),
@ -611,8 +611,8 @@
var scaleY = (newAttrs.height - padding * 2) / pure.height;
var rotation = Konva.getAngle(node.getRotation());
var dx = pure.x * scaleX - padding;
var dy = pure.y * scaleY - padding;
var dx = pure.x * scaleX - padding - node.offsetX() * scaleX;
var dy = pure.y * scaleY - padding - node.offsetY() * scaleY;
this.getNode().setAttrs({
scaleX: scaleX,

View File

@ -178,11 +178,13 @@ suite('Transformer', function() {
stage.add(layer);
var rect = new Konva.Rect({
x: 50,
y: 50,
x: 100,
y: 100,
draggable: true,
width: 100,
height: 100,
scaleX: 2,
scaleY: 2,
fill: 'yellow',
offsetX: 50,
offsetY: 50
@ -196,14 +198,14 @@ suite('Transformer', function() {
layer.draw();
assert.equal(tr.getClassName(), 'Transformer');
assert.equal(tr.x(), rect.x() - 50);
assert.equal(tr.y(), rect.y() - 50);
assert.equal(tr.x(), 0);
assert.equal(tr.y(), 0);
assert.equal(tr.width(), rect.width() * rect.scaleX());
assert.equal(tr.height(), rect.height() * rect.scaleY());
assert.equal(tr.rotation(), rect.rotation());
});
test.skip('fit rect with offset', function() {
test('fit rect with offset', function() {
var stage = addStage();
var layer = new Konva.Layer();
stage.add(layer);
@ -225,19 +227,24 @@ suite('Transformer', function() {
tr.attachTo(rect);
tr._fitNodeInto({
x: 50,
y: 50,
x: 0,
y: 0,
width: 200,
height: 100
});
layer.draw();
assert.equal(rect.x(), 100);
assert.equal(rect.y(), 100);
assert.equal(rect.y(), 50);
assert.equal(rect.width() * rect.scaleX(), 200);
assert.equal(rect.height() * rect.scaleY(), 100);
assert.equal(rect.rotation(), rect.rotation());
layer.draw();
assert.equal(tr.x(), 0);
assert.equal(tr.y(), 0);
assert.equal(tr.width(), 200);
assert.equal(tr.height(), 100);
assert.equal(rect.rotation(), rect.rotation());
});
test('add transformer for circle', function() {