Skip to content

Commit

Permalink
feat: add filter2
Browse files Browse the repository at this point in the history
  • Loading branch information
quarksb committed Sep 3, 2024
1 parent 583fccf commit 535e731
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,6 @@ export const Factory = {
},
afterSetFilter(this: Node) {
this._filterUpToDate = false;
this._filter2UpToDate = false;
},
};
52 changes: 52 additions & 0 deletions src/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import { Shape } from './Shape';
import { Layer } from './Layer';

export type Filter = (this: Node, imageData: ImageData) => void;
/**### A combination of HTMLCanvas adn OffscreenCanvas */
export type LegalCanvas = HTMLCanvasElement | OffscreenCanvas;
/**### different from Filter, which is use canvas instead of imageData */
export type Filter2 = (this: Node, canvas: LegalCanvas) => LegalCanvas;

type globalCompositeOperationType =
| ''
Expand Down Expand Up @@ -156,6 +160,8 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
_needClearTransformCache = false;

_filterUpToDate = false;
/** update signature for filter2 */
_filter2UpToDate = false;
_isUnderCache = false;
nodeType!: string;
className!: string;
Expand Down Expand Up @@ -389,6 +395,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {

this._cache.delete(CANVAS);
this._filterUpToDate = false;
this._filter2UpToDate = false;

if (conf.imageSmoothingEnabled === false) {
cachedSceneCanvas.getContext()._context.imageSmoothingEnabled = false;
Expand Down Expand Up @@ -571,6 +578,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
imageData,
n,
filter;
const filter2s = this.filter2s()

if (filters) {
if (!this._filterUpToDate) {
Expand Down Expand Up @@ -625,6 +633,44 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {

return filterCanvas;
}
if (filter2s && filter2s.length > 0) {
if (!this._filter2UpToDate) {
var ratio = sceneCanvas.pixelRatio;
filterCanvas.setSize(
sceneCanvas.width / sceneCanvas.pixelRatio,
sceneCanvas.height / sceneCanvas.pixelRatio
);
try {
len = filter2s.length;
filterContext.clear();

// copy cached canvas onto filter context
filterContext.drawImage(
sceneCanvas._canvas,
0,
0,
sceneCanvas.getWidth() / ratio,
sceneCanvas.getHeight() / ratio
);
let currentCanvas = filterCanvas._canvas;
for (n = 0; n < len; n++) {
currentCanvas = filter2s[n].call(this, currentCanvas);
}
filterContext.clearRect(0, 0, filterCanvas.getWidth(), filterCanvas.getHeight());
filterContext.drawImage(currentCanvas, 0, 0);
} catch (e: any) {
Util.error(
'Unable to apply filter. ' +
e.message +
' This post my help you https://konvajs.org/docs/posts/Tainted_Canvas.html.'
);
}

this._filter2UpToDate = true;
}

return filterCanvas;
}
return sceneCanvas;
}
/**
Expand Down Expand Up @@ -2644,6 +2690,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
embossWhiteLevel: GetSet<number, this>;
enhance: GetSet<number, this>;
filters: GetSet<Filter[], this>;
filter2s: GetSet<Filter2[], this>;
position: GetSet<Vector2d, this>;
absolutePosition: GetSet<Vector2d, this>;
size: GetSet<{ width: number; height: number }, this>;
Expand Down Expand Up @@ -3197,6 +3244,11 @@ addGetterSetter(Node, 'filters', null, function (this: Node, val) {
this._filterUpToDate = false;
return val;
});

addGetterSetter(Node, 'filter2s', null, function (this: Node, val) {
this._filter2UpToDate = false;
return val;
});
/**
* get/set filters. Filters are applied to cached canvases
* @name Konva.Node#filters
Expand Down
9 changes: 9 additions & 0 deletions src/Util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,15 @@ export const Util = {
} catch (e) {}
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() {
return document.createElement('img');
},
Expand Down

0 comments on commit 535e731

Please sign in to comment.