refactor: change Filter input and output

This commit is contained in:
quark 2024-08-19 09:57:31 +08:00
parent 583fccf249
commit de580be9b5
21 changed files with 239 additions and 81 deletions

View File

@ -15,7 +15,8 @@ import { Context } from './Context';
import { Shape } from './Shape'; import { Shape } from './Shape';
import { Layer } from './Layer'; import { Layer } from './Layer';
export type Filter = (this: Node, imageData: ImageData) => void; export type LegalCanvas = HTMLCanvasElement | OffscreenCanvas;
export type Filter = (this: Node, canvas: LegalCanvas) => void;
type globalCompositeOperationType = type globalCompositeOperationType =
| '' | ''
@ -163,7 +164,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
_dragEventId: number | null = null; _dragEventId: number | null = null;
_shouldFireChangeEvents = false; _shouldFireChangeEvents = false;
constructor(config?: Config) { constructor (config?: Config) {
// on initial set attrs wi don't need to fire change events // on initial set attrs wi don't need to fire change events
// because nobody is listening to them yet // because nobody is listening to them yet
this.setAttrs(config); this.setAttrs(config);
@ -366,10 +367,10 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
// console.log({ x, y, width, height }, rect); // console.log({ x, y, width, height }, rect);
var cachedSceneCanvas = new SceneCanvas({ var cachedSceneCanvas = new SceneCanvas({
pixelRatio: pixelRatio, pixelRatio: pixelRatio,
width: width, width: width,
height: height, height: height,
}), }),
cachedFilterCanvas = new SceneCanvas({ cachedFilterCanvas = new SceneCanvas({
pixelRatio: pixelRatio, pixelRatio: pixelRatio,
width: 0, width: 0,
@ -591,12 +592,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
sceneCanvas.getWidth() / ratio, sceneCanvas.getWidth() / ratio,
sceneCanvas.getHeight() / ratio sceneCanvas.getHeight() / ratio
); );
imageData = filterContext.getImageData( let canvas = Util.createOffScreenCanvas(filterCanvas.getWidth(), filterCanvas.getHeight());
0,
0,
filterCanvas.getWidth(),
filterCanvas.getHeight()
);
// apply filters to filter context // apply filters to filter context
for (n = 0; n < len; n++) { for (n = 0; n < len; n++) {
@ -604,19 +600,20 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
if (typeof filter !== 'function') { if (typeof filter !== 'function') {
Util.error( Util.error(
'Filter should be type of function, but got ' + 'Filter should be type of function, but got ' +
typeof filter + typeof filter +
' instead. Please check correct filters' ' instead. Please check correct filters'
); );
continue; continue;
} }
filter.call(this, imageData); canvas = filter.call(this, canvas);
filterContext.putImageData(imageData, 0, 0);
} }
// draw the final result on top of scene canvas
filterContext.drawImage(canvas, 0, 0);
} catch (e: any) { } catch (e: any) {
Util.error( Util.error(
'Unable to apply filter. ' + 'Unable to apply filter. ' +
e.message + e.message +
' This post my help you https://konvajs.org/docs/posts/Tainted_Canvas.html.' ' This post my help you https://konvajs.org/docs/posts/Tainted_Canvas.html.'
); );
} }
@ -1435,10 +1432,10 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
if (zIndex < 0 || zIndex >= this.parent.children.length) { if (zIndex < 0 || zIndex >= this.parent.children.length) {
Util.warn( Util.warn(
'Unexpected value ' + 'Unexpected value ' +
zIndex + zIndex +
' for zIndex property. zIndex is just index of a node in children of its parent. Expected value is from 0 to ' + ' for zIndex property. zIndex is just index of a node in children of its parent. Expected value is from 0 to ' +
(this.parent.children.length - 1) + (this.parent.children.length - 1) +
'.' '.'
); );
} }
var index = this.index; var index = this.index;
@ -1619,8 +1616,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
if (!Util.isValidSelector(sel)) { if (!Util.isValidSelector(sel)) {
Util.warn( Util.warn(
'Selector "' + 'Selector "' +
sel + sel +
'" is invalid. Allowed selectors examples are "#foo", ".bar" or "Group".' '" is invalid. Allowed selectors examples are "#foo", ".bar" or "Group".'
); );
Util.warn( Util.warn(
'If you have a custom shape with such className, please change it to start with upper letter like "Triangle".' 'If you have a custom shape with such className, please change it to start with upper letter like "Triangle".'
@ -2714,8 +2711,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
if (!Konva[className]) { if (!Konva[className]) {
Util.warn( Util.warn(
'Can not find a node with class name "' + 'Can not find a node with class name "' +
className + className +
'". Fallback to "Shape".' '". Fallback to "Shape".'
); );
className = 'Shape'; className = 'Shape';
} }

View File

@ -29,7 +29,7 @@ import { IRect, RGB, RGBA, Vector2d } from './types';
export class Transform { export class Transform {
m: Array<number>; m: Array<number>;
dirty = false; dirty = false;
constructor(m = [1, 0, 0, 1, 0, 0]) { constructor (m = [1, 0, 0, 1, 0, 0]) {
this.m = (m && m.slice()) || [1, 0, 0, 1, 0, 0]; this.m = (m && m.slice()) || [1, 0, 0, 1, 0, 0];
} }
reset() { reset() {
@ -509,9 +509,18 @@ export const Util = {
// on some environments canvas.style is readonly // on some environments canvas.style is readonly
try { try {
(<any>canvas).style = canvas.style || {}; (<any>canvas).style = canvas.style || {};
} catch (e) {} } catch (e) { }
return canvas; return canvas;
}, },
createOffScreenCanvas(size: { width: number; height: number }) {
if (window.OffscreenCanvas !== undefined) {
return new OffscreenCanvas(size.width, size.height);
}
const canvas = this.createCanvasElement();
canvas.width = size.width;
canvas.height = size.height;
return canvas;
}
createImageElement() { createImageElement() {
return document.createElement('img'); return document.createElement('img');
}, },
@ -1005,7 +1014,7 @@ export const Util = {
topRight = topRight =
bottomLeft = bottomLeft =
bottomRight = bottomRight =
Math.min(cornerRadius, width / 2, height / 2); Math.min(cornerRadius, width / 2, height / 2);
} else { } else {
topLeft = Math.min(cornerRadius[0] || 0, width / 2, height / 2); topLeft = Math.min(cornerRadius[0] || 0, width / 2, height / 2);
topRight = Math.min(cornerRadius[1] || 0, width / 2, height / 2); topRight = Math.min(cornerRadius[1] || 0, width / 2, height / 2);

View File

@ -1,5 +1,5 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Node, Filter, LegalCanvas } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
/* /*
the Gauss filter the Gauss filter
@ -154,7 +154,7 @@ function filterGaussBlurRGBA(imageData, radius) {
g_sum = g_sum =
b_sum = b_sum =
a_sum = a_sum =
0; 0;
r_out_sum = radiusPlus1 * (pr = pixels[yi]); r_out_sum = radiusPlus1 * (pr = pixels[yi]);
g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]); g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]);
@ -254,7 +254,7 @@ function filterGaussBlurRGBA(imageData, radius) {
b_sum = b_sum =
a_sum = a_sum =
r_sum = r_sum =
0; 0;
yi = x << 2; yi = x << 2;
r_out_sum = radiusPlus1 * (pr = pixels[yi]); r_out_sum = radiusPlus1 * (pr = pixels[yi]);
@ -358,15 +358,20 @@ function filterGaussBlurRGBA(imageData, radius) {
* @function * @function
* @name Blur * @name Blur
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Blur]); * node.filters([Konva.Filters.Blur]);
* node.blurRadius(10); * node.blurRadius(10);
*/ */
export const Blur: Filter = function Blur(imageData) { export const Blur: Filter = function Blur(canvas: LegalCanvas) {
var radius = Math.round(this.blurRadius()); var radius = Math.round(this.blurRadius());
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
if (radius > 0) { if (radius > 0) {
filterGaussBlurRGBA(imageData, radius); filterGaussBlurRGBA(imageData, radius);
} }

View File

@ -1,18 +1,24 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Node, Filter, LegalCanvas } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
/** /**
* Brighten Filter. * Brighten Filter.
* @function * @function
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Brighten]); * node.filters([Konva.Filters.Brighten]);
* node.brightness(0.8); * node.brightness(0.8);
*/ */
export const Brighten: Filter = function (imageData) { export const Brighten: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var brightness = this.brightness() * 255, var brightness = this.brightness() * 255,
data = imageData.data, data = imageData.data,
len = data.length, len = data.length,
@ -26,6 +32,9 @@ export const Brighten: Filter = function (imageData) {
// blue // blue
data[i + 2] += brightness; data[i + 2] += brightness;
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter( Factory.addGetterSetter(

View File

@ -1,18 +1,24 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Node, Filter, LegalCanvas } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
/** /**
* Contrast Filter. * Contrast Filter.
* @function * @function
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Contrast]); * node.filters([Konva.Filters.Contrast]);
* node.contrast(10); * node.contrast(10);
*/ */
export const Contrast: Filter = function (imageData) { export const Contrast: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var adjust = Math.pow((this.contrast() + 100) / 100, 2); var adjust = Math.pow((this.contrast() + 100) / 100, 2);
var data = imageData.data, var data = imageData.data,
@ -56,6 +62,9 @@ export const Contrast: Filter = function (imageData) {
data[i + 1] = green; data[i + 1] = green;
data[i + 2] = blue; data[i + 2] = blue;
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
/** /**

View File

@ -1,5 +1,5 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Node, Filter, LegalCanvas } from '../Node';
import { Util } from '../Util'; import { Util } from '../Util';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
/** /**
@ -9,7 +9,7 @@ import { getNumberValidator } from '../Validators';
* License: [http://www.pixastic.com/lib/license.txt] * License: [http://www.pixastic.com/lib/license.txt]
* @function * @function
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Emboss]); * node.filters([Konva.Filters.Emboss]);
@ -18,11 +18,17 @@ import { getNumberValidator } from '../Validators';
* node.embossDirection('right'); * node.embossDirection('right');
* node.embossBlend(true); * node.embossBlend(true);
*/ */
export const Emboss: Filter = function (imageData) { export const Emboss: Filter = function (canvas: LegalCanvas) {
// pixastic strength is between 0 and 10. I want it between 0 and 1 // pixastic strength is between 0 and 10. I want it between 0 and 1
// pixastic greyLevel is between 0 and 255. I want it between 0 and 1. Also, // pixastic greyLevel is between 0 and 255. I want it between 0 and 1. Also,
// a max value of greyLevel yields a white emboss, and the min value yields a black // a max value of greyLevel yields a white emboss, and the min value yields a black
// emboss. Therefore, I changed greyLevel to whiteLevel // emboss. Therefore, I changed greyLevel to whiteLevel
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var strength = this.embossStrength() * 10, var strength = this.embossStrength() * 10,
greyLevel = this.embossWhiteLevel() * 255, greyLevel = this.embossWhiteLevel() * 255,
direction = this.embossDirection(), direction = this.embossDirection(),
@ -138,6 +144,9 @@ export const Emboss: Filter = function (imageData) {
} }
} while (--x); } while (--x);
} while (--y); } while (--y);
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter( Factory.addGetterSetter(

View File

@ -1,5 +1,5 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Node, Filter, LegalCanvas } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
function remap(fromValue, fromMin, fromMax, toMin, toMax) { function remap(fromValue, fromMin, fromMax, toMin, toMax) {
@ -30,14 +30,20 @@ function remap(fromValue, fromMin, fromMax, toMin, toMax) {
* @function * @function
* @name Enhance * @name Enhance
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @author ippo615 * @author ippo615
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Enhance]); * node.filters([Konva.Filters.Enhance]);
* node.enhance(0.4); * node.enhance(0.4);
*/ */
export const Enhance: Filter = function (imageData) { export const Enhance: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
nSubPixels = data.length, nSubPixels = data.length,
rMin = data[0], rMin = data[0],
@ -134,6 +140,8 @@ export const Enhance: Filter = function (imageData) {
data[i + 2] = remap(data[i + 2], bMin, bMax, bGoalMin, bGoalMax); data[i + 2] = remap(data[i + 2], bMin, bMax, bGoalMin, bGoalMax);
//data[i + 3] = remap(data[i + 3], aMin, aMax, aGoalMin, aGoalMax); //data[i + 3] = remap(data[i + 3], aMin, aMax, aGoalMin, aGoalMax);
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
/** /**

View File

@ -1,15 +1,21 @@
import { Filter } from '../Node'; import { Filter, LegalCanvas } from '../Node';
/** /**
* Grayscale Filter * Grayscale Filter
* @function * @function
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Grayscale]); * node.filters([Konva.Filters.Grayscale]);
*/ */
export const Grayscale: Filter = function (imageData) { export const Grayscale: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
len = data.length, len = data.length,
i, i,
@ -24,4 +30,6 @@ export const Grayscale: Filter = function (imageData) {
// blue // blue
data[i + 2] = brightness; data[i + 2] = brightness;
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };

View File

@ -1,5 +1,5 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Node, Filter, LegalCanvas } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
Factory.addGetterSetter( Factory.addGetterSetter(
@ -51,14 +51,20 @@ Factory.addGetterSetter(
* HSL Filter. Adjusts the hue, saturation and luminance (or lightness) * HSL Filter. Adjusts the hue, saturation and luminance (or lightness)
* @function * @function
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @author ippo615 * @author ippo615
* @example * @example
* image.filters([Konva.Filters.HSL]); * image.filters([Konva.Filters.HSL]);
* image.luminance(0.2); * image.luminance(0.2);
*/ */
export const HSL: Filter = function (imageData) { export const HSL: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
nPixels = data.length, nPixels = data.length,
v = 1, v = 1,
@ -105,4 +111,6 @@ export const HSL: Filter = function (imageData) {
data[i + 2] = br * r + bg * g + bb * b + l; data[i + 2] = br * r + bg * g + bb * b + l;
data[i + 3] = a; // alpha data[i + 3] = a; // alpha
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };

View File

@ -7,14 +7,20 @@ import { getNumberValidator } from '../Validators';
* @function * @function
* @name HSV * @name HSV
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @author ippo615 * @author ippo615
* @example * @example
* image.filters([Konva.Filters.HSV]); * image.filters([Konva.Filters.HSV]);
* image.value(200); * image.value(200);
*/ */
export const HSV: Filter = function (imageData) { export const HSV: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
nPixels = data.length, nPixels = data.length,
v = Math.pow(2, this.value()), v = Math.pow(2, this.value()),
@ -60,6 +66,8 @@ export const HSV: Filter = function (imageData) {
data[i + 2] = br * r + bg * g + bb * b; data[i + 2] = br * r + bg * g + bb * b;
data[i + 3] = a; // alpha data[i + 3] = a; // alpha
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter( Factory.addGetterSetter(

View File

@ -3,12 +3,18 @@ import { Filter } from '../Node';
* Invert Filter * Invert Filter
* @function * @function
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Invert]); * node.filters([Konva.Filters.Invert]);
*/ */
export const Invert: Filter = function (imageData) { export const Invert: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
len = data.length, len = data.length,
i; i;
@ -21,4 +27,6 @@ export const Invert: Filter = function (imageData) {
// blue // blue
data[i + 2] = 255 - data[i + 2]; data[i + 2] = 255 - data[i + 2];
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };

View File

@ -177,7 +177,13 @@ var FromPolar = function (src, dst, opt) {
* node.kaleidoscopePower(3); * node.kaleidoscopePower(3);
* node.kaleidoscopeAngle(45); * node.kaleidoscopeAngle(45);
*/ */
export const Kaleidoscope: Filter = function (imageData) { export const Kaleidoscope: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var xSize = imageData.width, var xSize = imageData.width,
ySize = imageData.height; ySize = imageData.height;
@ -263,6 +269,8 @@ export const Kaleidoscope: Filter = function (imageData) {
// Convert back from polar coordinates // Convert back from polar coordinates
FromPolar(scratchData, imageData, { polarRotation: 0 }); FromPolar(scratchData, imageData, { polarRotation: 0 });
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
/** /**

View File

@ -1,5 +1,5 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Node, Filter, LegalCanvas } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
function pixelAt(idata, x, y) { function pixelAt(idata, x, y) {
@ -17,8 +17,8 @@ function pixelAt(idata, x, y) {
function rgbDistance(p1, p2) { function rgbDistance(p1, p2) {
return Math.sqrt( return Math.sqrt(
Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[0] - p2[0], 2) +
Math.pow(p1[1] - p2[1], 2) + Math.pow(p1[1] - p2[1], 2) +
Math.pow(p1[2] - p2[2], 2) Math.pow(p1[2] - p2[2], 2)
); );
} }
@ -173,13 +173,19 @@ function smoothEdgeMask(mask, sw, sh) {
* @function * @function
* @name Mask * @name Mask
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Mask]); * node.filters([Konva.Filters.Mask]);
* node.threshold(200); * node.threshold(200);
*/ */
export const Mask: Filter = function (imageData) { export const Mask: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
// Detect pixels close to the background color // Detect pixels close to the background color
var threshold = this.threshold(), var threshold = this.threshold(),
mask = backgroundMask(imageData, threshold); mask = backgroundMask(imageData, threshold);
@ -197,7 +203,8 @@ export const Mask: Filter = function (imageData) {
applyMask(imageData, mask); applyMask(imageData, mask);
} }
return imageData; canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter( Factory.addGetterSetter(

View File

@ -7,14 +7,20 @@ import { getNumberValidator } from '../Validators';
* @function * @function
* @name Noise * @name Noise
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @author ippo615 * @author ippo615
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Noise]); * node.filters([Konva.Filters.Noise]);
* node.noise(0.8); * node.noise(0.8);
*/ */
export const Noise: Filter = function (imageData) { export const Noise: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var amount = this.noise() * 255, var amount = this.noise() * 255,
data = imageData.data, data = imageData.data,
nPixels = data.length, nPixels = data.length,
@ -26,6 +32,8 @@ export const Noise: Filter = function (imageData) {
data[i + 1] += half - 2 * half * Math.random(); data[i + 1] += half - 2 * half * Math.random();
data[i + 2] += half - 2 * half * Math.random(); data[i + 2] += half - 2 * half * Math.random();
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter( Factory.addGetterSetter(

View File

@ -10,7 +10,7 @@ import { getNumberValidator } from '../Validators';
* @function * @function
* @name Pixelate * @name Pixelate
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @author ippo615 * @author ippo615
* @example * @example
* node.cache(); * node.cache();
@ -18,7 +18,13 @@ import { getNumberValidator } from '../Validators';
* node.pixelSize(10); * node.pixelSize(10);
*/ */
export const Pixelate: Filter = function (imageData) { export const Pixelate: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var pixelSize = Math.ceil(this.pixelSize()), var pixelSize = Math.ceil(this.pixelSize()),
width = imageData.width, width = imageData.width,
height = imageData.height, height = imageData.height,
@ -103,6 +109,9 @@ export const Pixelate: Filter = function (imageData) {
} }
} }
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter( Factory.addGetterSetter(

View File

@ -1,5 +1,5 @@
import { Factory } from '../Factory'; import { Factory } from '../Factory';
import { Node, Filter } from '../Node'; import { Node, Filter, LegalCanvas } from '../Node';
import { getNumberValidator } from '../Validators'; import { getNumberValidator } from '../Validators';
/** /**
* Posterize Filter. Adjusts the channels so that there are no more * Posterize Filter. Adjusts the channels so that there are no more
@ -9,14 +9,20 @@ import { getNumberValidator } from '../Validators';
* @name Posterize * @name Posterize
* @author ippo615 * @author ippo615
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Posterize]); * node.filters([Konva.Filters.Posterize]);
* node.levels(0.8); // between 0 and 1 * node.levels(0.8); // between 0 and 1
*/ */
export const Posterize: Filter = function (imageData) { export const Posterize: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
// level must be between 1 and 255 // level must be between 1 and 255
var levels = Math.round(this.levels() * 254) + 1, var levels = Math.round(this.levels() * 254) + 1,
data = imageData.data, data = imageData.data,
@ -27,6 +33,8 @@ export const Posterize: Filter = function (imageData) {
for (i = 0; i < len; i += 1) { for (i = 0; i < len; i += 1) {
data[i] = Math.floor(data[i] / scale) * scale; data[i] = Math.floor(data[i] / scale) * scale;
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter( Factory.addGetterSetter(

View File

@ -7,7 +7,7 @@ import { RGBComponent } from '../Validators';
* @function * @function
* @name RGB * @name RGB
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @author ippo615 * @author ippo615
* @example * @example
* node.cache(); * node.cache();
@ -16,7 +16,13 @@ import { RGBComponent } from '../Validators';
* node.green(200); * node.green(200);
*/ */
export const RGB: Filter = function (imageData) { export const RGB: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
nPixels = data.length, nPixels = data.length,
red = this.red(), red = this.red(),
@ -33,6 +39,8 @@ export const RGB: Filter = function (imageData) {
data[i + 2] = brightness * blue; // b data[i + 2] = brightness * blue; // b
data[i + 3] = data[i + 3]; // alpha data[i + 3] = data[i + 3]; // alpha
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter(Node, 'red', 0, function (this: Node, val) { Factory.addGetterSetter(Node, 'red', 0, function (this: Node, val) {

View File

@ -7,7 +7,7 @@ import { RGBComponent } from '../Validators';
* @function * @function
* @name RGBA * @name RGBA
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @author codefo * @author codefo
* @example * @example
* node.cache(); * node.cache();
@ -17,7 +17,13 @@ import { RGBComponent } from '../Validators';
* node.alpha(0.3); * node.alpha(0.3);
*/ */
export const RGBA: Filter = function (imageData) { export const RGBA: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
nPixels = data.length, nPixels = data.length,
red = this.red(), red = this.red(),
@ -34,6 +40,8 @@ export const RGBA: Filter = function (imageData) {
data[i + 1] = green * alpha + data[i + 1] * ia; // g data[i + 1] = green * alpha + data[i + 1] * ia; // g
data[i + 2] = blue * alpha + data[i + 2] * ia; // b data[i + 2] = blue * alpha + data[i + 2] * ia; // b
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter(Node, 'red', 0, function (this: Node, val: number) { Factory.addGetterSetter(Node, 'red', 0, function (this: Node, val: number) {

View File

@ -6,12 +6,18 @@ import { Filter } from '../Node';
* @function * @function
* @name Sepia * @name Sepia
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Sepia]); * node.filters([Konva.Filters.Sepia]);
*/ */
export const Sepia: Filter = function (imageData) { export const Sepia: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
nPixels = data.length, nPixels = data.length,
i, i,
@ -28,4 +34,6 @@ export const Sepia: Filter = function (imageData) {
data[i + 1] = Math.min(255, r * 0.349 + g * 0.686 + b * 0.168); data[i + 1] = Math.min(255, r * 0.349 + g * 0.686 + b * 0.168);
data[i + 2] = Math.min(255, r * 0.272 + g * 0.534 + b * 0.131); data[i + 2] = Math.min(255, r * 0.272 + g * 0.534 + b * 0.131);
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };

View File

@ -7,13 +7,19 @@ import { Filter } from '../Node';
* @function * @function
* @name Solarize * @name Solarize
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @example * @example
* node.cache(); * node.cache();
* node.filters([Konva.Filters.Solarize]); * node.filters([Konva.Filters.Solarize]);
*/ */
export const Solarize: Filter = function (imageData) { export const Solarize: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var data = imageData.data, var data = imageData.data,
w = imageData.width, w = imageData.width,
h = imageData.height, h = imageData.height,
@ -44,4 +50,6 @@ export const Solarize: Filter = function (imageData) {
data[offset + 2] = b; data[offset + 2] = b;
} while (--x); } while (--x);
} while (--y); } while (--y);
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };

View File

@ -8,7 +8,7 @@ import { getNumberValidator } from '../Validators';
* @function * @function
* @name Threshold * @name Threshold
* @memberof Konva.Filters * @memberof Konva.Filters
* @param {Object} imageData * * @param {LegalCanvas} canvas
* @author ippo615 * @author ippo615
* @example * @example
* node.cache(); * node.cache();
@ -16,7 +16,13 @@ import { getNumberValidator } from '../Validators';
* node.threshold(0.1); * node.threshold(0.1);
*/ */
export const Threshold: Filter = function (imageData) { export const Threshold: Filter = function (canvas: LegalCanvas) {
const imageData = canvas.context.getImageData(
0,
0,
canvas.width,
canvas.height
);
var level = this.threshold() * 255, var level = this.threshold() * 255,
data = imageData.data, data = imageData.data,
len = data.length, len = data.length,
@ -25,6 +31,8 @@ export const Threshold: Filter = function (imageData) {
for (i = 0; i < len; i += 1) { for (i = 0; i < len; i += 1) {
data[i] = data[i] < level ? 0 : 255; data[i] = data[i] < level ? 0 : 255;
} }
canvas.context.putImageData(imageData, 0, 0);
return canvas;
}; };
Factory.addGetterSetter( Factory.addGetterSetter(