@nasser-sw/fabric 7.0.1-beta7 → 7.0.1-beta9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/debug/konva-master/CHANGELOG.md +1475 -0
- package/debug/konva-master/LICENSE +22 -0
- package/debug/konva-master/README.md +209 -0
- package/debug/konva-master/gulpfile.mjs +110 -0
- package/debug/konva-master/package.json +139 -0
- package/debug/konva-master/release.sh +62 -0
- package/debug/konva-master/resources/doc-includes/ContainerParams.txt +6 -0
- package/debug/konva-master/resources/doc-includes/NodeParams.txt +20 -0
- package/debug/konva-master/resources/doc-includes/ShapeParams.txt +53 -0
- package/debug/konva-master/resources/jsdoc.conf.json +28 -0
- package/debug/konva-master/rollup.config.mjs +32 -0
- package/debug/konva-master/src/Animation.ts +237 -0
- package/debug/konva-master/src/BezierFunctions.ts +826 -0
- package/debug/konva-master/src/Canvas.ts +230 -0
- package/debug/konva-master/src/Container.ts +649 -0
- package/debug/konva-master/src/Context.ts +1017 -0
- package/debug/konva-master/src/Core.ts +5 -0
- package/debug/konva-master/src/DragAndDrop.ts +173 -0
- package/debug/konva-master/src/Factory.ts +246 -0
- package/debug/konva-master/src/FastLayer.ts +29 -0
- package/debug/konva-master/src/Global.ts +210 -0
- package/debug/konva-master/src/Group.ts +31 -0
- package/debug/konva-master/src/Layer.ts +546 -0
- package/debug/konva-master/src/Node.ts +3477 -0
- package/debug/konva-master/src/PointerEvents.ts +67 -0
- package/debug/konva-master/src/Shape.ts +2081 -0
- package/debug/konva-master/src/Stage.ts +1000 -0
- package/debug/konva-master/src/Tween.ts +811 -0
- package/debug/konva-master/src/Util.ts +1123 -0
- package/debug/konva-master/src/Validators.ts +210 -0
- package/debug/konva-master/src/_CoreInternals.ts +85 -0
- package/debug/konva-master/src/_FullInternals.ts +171 -0
- package/debug/konva-master/src/canvas-backend.ts +36 -0
- package/debug/konva-master/src/filters/Blur.ts +388 -0
- package/debug/konva-master/src/filters/Brighten.ts +48 -0
- package/debug/konva-master/src/filters/Brightness.ts +30 -0
- package/debug/konva-master/src/filters/Contrast.ts +75 -0
- package/debug/konva-master/src/filters/Emboss.ts +207 -0
- package/debug/konva-master/src/filters/Enhance.ts +154 -0
- package/debug/konva-master/src/filters/Grayscale.ts +25 -0
- package/debug/konva-master/src/filters/HSL.ts +108 -0
- package/debug/konva-master/src/filters/HSV.ts +106 -0
- package/debug/konva-master/src/filters/Invert.ts +23 -0
- package/debug/konva-master/src/filters/Kaleidoscope.ts +274 -0
- package/debug/konva-master/src/filters/Mask.ts +220 -0
- package/debug/konva-master/src/filters/Noise.ts +44 -0
- package/debug/konva-master/src/filters/Pixelate.ts +107 -0
- package/debug/konva-master/src/filters/Posterize.ts +46 -0
- package/debug/konva-master/src/filters/RGB.ts +82 -0
- package/debug/konva-master/src/filters/RGBA.ts +103 -0
- package/debug/konva-master/src/filters/Sepia.ts +27 -0
- package/debug/konva-master/src/filters/Solarize.ts +29 -0
- package/debug/konva-master/src/filters/Threshold.ts +44 -0
- package/debug/konva-master/src/index.ts +3 -0
- package/debug/konva-master/src/shapes/Arc.ts +176 -0
- package/debug/konva-master/src/shapes/Arrow.ts +231 -0
- package/debug/konva-master/src/shapes/Circle.ts +76 -0
- package/debug/konva-master/src/shapes/Ellipse.ts +121 -0
- package/debug/konva-master/src/shapes/Image.ts +319 -0
- package/debug/konva-master/src/shapes/Label.ts +386 -0
- package/debug/konva-master/src/shapes/Line.ts +364 -0
- package/debug/konva-master/src/shapes/Path.ts +1013 -0
- package/debug/konva-master/src/shapes/Rect.ts +79 -0
- package/debug/konva-master/src/shapes/RegularPolygon.ts +167 -0
- package/debug/konva-master/src/shapes/Ring.ts +94 -0
- package/debug/konva-master/src/shapes/Sprite.ts +370 -0
- package/debug/konva-master/src/shapes/Star.ts +125 -0
- package/debug/konva-master/src/shapes/Text.ts +1065 -0
- package/debug/konva-master/src/shapes/TextPath.ts +583 -0
- package/debug/konva-master/src/shapes/Transformer.ts +1889 -0
- package/debug/konva-master/src/shapes/Wedge.ts +129 -0
- package/debug/konva-master/src/skia-backend.ts +35 -0
- package/debug/konva-master/src/types.ts +84 -0
- package/debug/konva-master/tsconfig.json +31 -0
- package/debug/konva-master/tsconfig.test.json +7 -0
- package/dist/index.js +977 -29
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.min.mjs +1 -1
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +977 -29
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +977 -29
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +977 -29
- package/dist/index.node.mjs.map +1 -1
- package/dist/package.json.min.mjs +1 -1
- package/dist/package.json.mjs +1 -1
- package/dist/src/shapes/Line.d.ts +1 -0
- package/dist/src/shapes/Line.d.ts.map +1 -1
- package/dist/src/shapes/Line.min.mjs +1 -1
- package/dist/src/shapes/Line.min.mjs.map +1 -1
- package/dist/src/shapes/Line.mjs +63 -6
- package/dist/src/shapes/Line.mjs.map +1 -1
- package/dist/src/shapes/Text/Text.d.ts +19 -0
- package/dist/src/shapes/Text/Text.d.ts.map +1 -1
- package/dist/src/shapes/Text/Text.min.mjs +1 -1
- package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
- package/dist/src/shapes/Text/Text.mjs +238 -4
- package/dist/src/shapes/Text/Text.mjs.map +1 -1
- package/dist/src/shapes/Textbox.d.ts +38 -1
- package/dist/src/shapes/Textbox.d.ts.map +1 -1
- package/dist/src/shapes/Textbox.min.mjs +1 -1
- package/dist/src/shapes/Textbox.min.mjs.map +1 -1
- package/dist/src/shapes/Textbox.mjs +497 -15
- package/dist/src/shapes/Textbox.mjs.map +1 -1
- package/dist/src/text/examples/arabicTextExample.d.ts +60 -0
- package/dist/src/text/examples/arabicTextExample.d.ts.map +1 -0
- package/dist/src/text/measure.d.ts +9 -0
- package/dist/src/text/measure.d.ts.map +1 -1
- package/dist/src/text/measure.min.mjs +1 -1
- package/dist/src/text/measure.min.mjs.map +1 -1
- package/dist/src/text/measure.mjs +175 -4
- package/dist/src/text/measure.mjs.map +1 -1
- package/dist/src/text/overlayEditor.d.ts.map +1 -1
- package/dist/src/text/overlayEditor.min.mjs +1 -1
- package/dist/src/text/overlayEditor.min.mjs.map +1 -1
- package/dist/src/text/overlayEditor.mjs +7 -0
- package/dist/src/text/overlayEditor.mjs.map +1 -1
- package/dist/src/text/scriptUtils.d.ts +142 -0
- package/dist/src/text/scriptUtils.d.ts.map +1 -0
- package/dist/src/text/scriptUtils.min.mjs +2 -0
- package/dist/src/text/scriptUtils.min.mjs.map +1 -0
- package/dist/src/text/scriptUtils.mjs +212 -0
- package/dist/src/text/scriptUtils.mjs.map +1 -0
- package/dist-extensions/src/shapes/Line.d.ts +1 -0
- package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Text/Text.d.ts +19 -0
- package/dist-extensions/src/shapes/Text/Text.d.ts.map +1 -1
- package/dist-extensions/src/shapes/Textbox.d.ts +38 -1
- package/dist-extensions/src/shapes/Textbox.d.ts.map +1 -1
- package/dist-extensions/src/text/measure.d.ts +9 -0
- package/dist-extensions/src/text/measure.d.ts.map +1 -1
- package/dist-extensions/src/text/overlayEditor.d.ts.map +1 -1
- package/dist-extensions/src/text/scriptUtils.d.ts +142 -0
- package/dist-extensions/src/text/scriptUtils.d.ts.map +1 -0
- package/fabric-test-editor.html +2401 -46
- package/fabric-test2.html +43 -0
- package/fonts/STV Bold.ttf +0 -0
- package/fonts/STV Light.ttf +0 -0
- package/fonts/STV Regular.ttf +0 -0
- package/package.json +1 -1
- package/src/shapes/Line.ts +132 -46
- package/src/shapes/Text/Text.ts +238 -5
- package/src/shapes/Textbox.ts +521 -11
- package/src/text/measure.ts +200 -50
- package/src/text/overlayEditor.ts +7 -0
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
import type { HitCanvas, SceneCanvas } from './Canvas.ts';
|
|
2
|
+
import type { SceneContext } from './Context.ts';
|
|
3
|
+
import { Factory } from './Factory.ts';
|
|
4
|
+
import type { NodeConfig } from './Node.ts';
|
|
5
|
+
import { Node } from './Node.ts';
|
|
6
|
+
import type { Shape } from './Shape.ts';
|
|
7
|
+
import type { GetSet, IRect } from './types.ts';
|
|
8
|
+
import { getNumberValidator } from './Validators.ts';
|
|
9
|
+
|
|
10
|
+
export type ClipFuncOutput =
|
|
11
|
+
| void
|
|
12
|
+
| [Path2D | CanvasFillRule]
|
|
13
|
+
| [Path2D, CanvasFillRule];
|
|
14
|
+
export interface ContainerConfig extends NodeConfig {
|
|
15
|
+
clearBeforeDraw?: boolean;
|
|
16
|
+
clipFunc?: (ctx: SceneContext) => ClipFuncOutput;
|
|
17
|
+
clipX?: number;
|
|
18
|
+
clipY?: number;
|
|
19
|
+
clipWidth?: number;
|
|
20
|
+
clipHeight?: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Container constructor. Containers are used to contain nodes or other containers
|
|
25
|
+
* @constructor
|
|
26
|
+
* @memberof Konva
|
|
27
|
+
* @augments Konva.Node
|
|
28
|
+
* @abstract
|
|
29
|
+
* @param {Object} config
|
|
30
|
+
* @@nodeParams
|
|
31
|
+
* @@containerParams
|
|
32
|
+
*/
|
|
33
|
+
export abstract class Container<
|
|
34
|
+
ChildType extends Node = Node,
|
|
35
|
+
> extends Node<ContainerConfig> {
|
|
36
|
+
children: Array<ChildType> = [];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* returns an array of direct descendant nodes
|
|
40
|
+
* @method
|
|
41
|
+
* @name Konva.Container#getChildren
|
|
42
|
+
* @param {Function} [filterFunc] filter function
|
|
43
|
+
* @returns {Array}
|
|
44
|
+
* @example
|
|
45
|
+
* // get all children
|
|
46
|
+
* var children = layer.getChildren();
|
|
47
|
+
*
|
|
48
|
+
* // get only circles
|
|
49
|
+
* var circles = layer.getChildren(function(node){
|
|
50
|
+
* return node.getClassName() === 'Circle';
|
|
51
|
+
* });
|
|
52
|
+
*/
|
|
53
|
+
getChildren(filterFunc?: (item: Node) => boolean) {
|
|
54
|
+
const children = this.children || [];
|
|
55
|
+
if (filterFunc) {
|
|
56
|
+
return children.filter(filterFunc);
|
|
57
|
+
}
|
|
58
|
+
return children;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* determine if node has children
|
|
62
|
+
* @method
|
|
63
|
+
* @name Konva.Container#hasChildren
|
|
64
|
+
* @returns {Boolean}
|
|
65
|
+
*/
|
|
66
|
+
hasChildren() {
|
|
67
|
+
return this.getChildren().length > 0;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* remove all children. Children will be still in memory.
|
|
71
|
+
* If you want to completely destroy all children please use "destroyChildren" method instead
|
|
72
|
+
* @method
|
|
73
|
+
* @name Konva.Container#removeChildren
|
|
74
|
+
*/
|
|
75
|
+
removeChildren() {
|
|
76
|
+
this.getChildren().forEach((child) => {
|
|
77
|
+
// reset parent to prevent many _setChildrenIndices calls
|
|
78
|
+
child.parent = null;
|
|
79
|
+
child.index = 0;
|
|
80
|
+
child.remove();
|
|
81
|
+
});
|
|
82
|
+
this.children = [];
|
|
83
|
+
// because all children were detached from parent, request draw via container
|
|
84
|
+
this._requestDraw();
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* destroy all children nodes.
|
|
89
|
+
* @method
|
|
90
|
+
* @name Konva.Container#destroyChildren
|
|
91
|
+
*/
|
|
92
|
+
destroyChildren() {
|
|
93
|
+
this.getChildren().forEach((child) => {
|
|
94
|
+
// reset parent to prevent many _setChildrenIndices calls
|
|
95
|
+
child.parent = null;
|
|
96
|
+
child.index = 0;
|
|
97
|
+
child.destroy();
|
|
98
|
+
});
|
|
99
|
+
this.children = [];
|
|
100
|
+
// because all children were detached from parent, request draw via container
|
|
101
|
+
this._requestDraw();
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
abstract _validateAdd(node: Node): void;
|
|
105
|
+
/**
|
|
106
|
+
* add a child and children into container
|
|
107
|
+
* @name Konva.Container#add
|
|
108
|
+
* @method
|
|
109
|
+
* @param {...Konva.Node} children
|
|
110
|
+
* @returns {Container}
|
|
111
|
+
* @example
|
|
112
|
+
* layer.add(rect);
|
|
113
|
+
* layer.add(shape1, shape2, shape3);
|
|
114
|
+
* // empty arrays are accepted, though each individual child must be defined
|
|
115
|
+
* layer.add(...shapes);
|
|
116
|
+
*/
|
|
117
|
+
add(...children: ChildType[]) {
|
|
118
|
+
if (children.length === 0) {
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
if (children.length > 1) {
|
|
122
|
+
for (let i = 0; i < children.length; i++) {
|
|
123
|
+
this.add(children[i]);
|
|
124
|
+
}
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
const child = children[0];
|
|
128
|
+
if (child.getParent()) {
|
|
129
|
+
child.moveTo(this);
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
this._validateAdd(child);
|
|
133
|
+
child.index = this.getChildren().length;
|
|
134
|
+
child.parent = this;
|
|
135
|
+
child._clearCaches();
|
|
136
|
+
this.getChildren().push(child);
|
|
137
|
+
this._fire('add', {
|
|
138
|
+
child: child,
|
|
139
|
+
});
|
|
140
|
+
this._requestDraw();
|
|
141
|
+
// chainable
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
destroy() {
|
|
145
|
+
if (this.hasChildren()) {
|
|
146
|
+
this.destroyChildren();
|
|
147
|
+
}
|
|
148
|
+
super.destroy();
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* return an array of nodes that match the selector.
|
|
153
|
+
* You can provide a string with '#' for id selections and '.' for name selections.
|
|
154
|
+
* Or a function that will return true/false when a node is passed through. See example below.
|
|
155
|
+
* With strings you can also select by type or class name. Pass multiple selectors
|
|
156
|
+
* separated by a comma.
|
|
157
|
+
* @method
|
|
158
|
+
* @name Konva.Container#find
|
|
159
|
+
* @param {String | Function} selector
|
|
160
|
+
* @returns {Array}
|
|
161
|
+
* @example
|
|
162
|
+
*
|
|
163
|
+
* Passing a string as a selector
|
|
164
|
+
* // select node with id foo
|
|
165
|
+
* var node = stage.find('#foo');
|
|
166
|
+
*
|
|
167
|
+
* // select nodes with name bar inside layer
|
|
168
|
+
* var nodes = layer.find('.bar');
|
|
169
|
+
*
|
|
170
|
+
* // select all groups inside layer
|
|
171
|
+
* var nodes = layer.find('Group');
|
|
172
|
+
*
|
|
173
|
+
* // select all rectangles inside layer
|
|
174
|
+
* var nodes = layer.find('Rect');
|
|
175
|
+
*
|
|
176
|
+
* // select node with an id of foo or a name of bar inside layer
|
|
177
|
+
* var nodes = layer.find('#foo, .bar');
|
|
178
|
+
*
|
|
179
|
+
* Passing a function as a selector
|
|
180
|
+
*
|
|
181
|
+
* // get all groups with a function
|
|
182
|
+
* var groups = stage.find(node => {
|
|
183
|
+
* return node.getType() === 'Group';
|
|
184
|
+
* });
|
|
185
|
+
*
|
|
186
|
+
* // get only Nodes with partial opacity
|
|
187
|
+
* var alphaNodes = layer.find(node => {
|
|
188
|
+
* return node.getType() === 'Node' && node.getAbsoluteOpacity() < 1;
|
|
189
|
+
* });
|
|
190
|
+
*/
|
|
191
|
+
find<ChildNode extends Node>(selector): Array<ChildNode> {
|
|
192
|
+
// protecting _generalFind to prevent user from accidentally adding
|
|
193
|
+
// second argument and getting unexpected `findOne` result
|
|
194
|
+
return this._generalFind<ChildNode>(selector, false);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* return a first node from `find` method
|
|
198
|
+
* @method
|
|
199
|
+
* @name Konva.Container#findOne
|
|
200
|
+
* @param {String | Function} selector
|
|
201
|
+
* @returns {Konva.Node | Undefined}
|
|
202
|
+
* @example
|
|
203
|
+
* // select node with id foo
|
|
204
|
+
* var node = stage.findOne('#foo');
|
|
205
|
+
*
|
|
206
|
+
* // select node with name bar inside layer
|
|
207
|
+
* var nodes = layer.findOne('.bar');
|
|
208
|
+
*
|
|
209
|
+
* // select the first node to return true in a function
|
|
210
|
+
* var node = stage.findOne(node => {
|
|
211
|
+
* return node.getType() === 'Shape'
|
|
212
|
+
* })
|
|
213
|
+
*/
|
|
214
|
+
findOne<ChildNode extends Node = Node>(
|
|
215
|
+
selector: string | Function
|
|
216
|
+
): ChildNode | undefined {
|
|
217
|
+
const result = this._generalFind<ChildNode>(selector, true);
|
|
218
|
+
return result.length > 0 ? result[0] : undefined;
|
|
219
|
+
}
|
|
220
|
+
_generalFind<ChildNode extends Node>(
|
|
221
|
+
selector: string | Function,
|
|
222
|
+
findOne: boolean
|
|
223
|
+
) {
|
|
224
|
+
const retArr: Array<ChildNode> = [];
|
|
225
|
+
|
|
226
|
+
this._descendants((node) => {
|
|
227
|
+
const valid = node._isMatch(selector);
|
|
228
|
+
if (valid) {
|
|
229
|
+
retArr.push(node as ChildNode);
|
|
230
|
+
}
|
|
231
|
+
if (valid && findOne) {
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
return false;
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
return retArr;
|
|
238
|
+
}
|
|
239
|
+
private _descendants(fn: (n: Node) => boolean) {
|
|
240
|
+
let shouldStop = false;
|
|
241
|
+
const children = this.getChildren();
|
|
242
|
+
for (const child of children) {
|
|
243
|
+
shouldStop = fn(child);
|
|
244
|
+
if (shouldStop) {
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
if (!child.hasChildren()) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
shouldStop = (child as unknown as Container)._descendants(fn);
|
|
251
|
+
if (shouldStop) {
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
// extenders
|
|
258
|
+
toObject() {
|
|
259
|
+
const obj = Node.prototype.toObject.call(this);
|
|
260
|
+
|
|
261
|
+
obj.children = [];
|
|
262
|
+
|
|
263
|
+
this.getChildren().forEach((child) => {
|
|
264
|
+
obj.children!.push(child.toObject());
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
return obj;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* determine if node is an ancestor
|
|
271
|
+
* of descendant
|
|
272
|
+
* @method
|
|
273
|
+
* @name Konva.Container#isAncestorOf
|
|
274
|
+
* @param {Konva.Node} node
|
|
275
|
+
*/
|
|
276
|
+
isAncestorOf(node: Node) {
|
|
277
|
+
let parent = node.getParent();
|
|
278
|
+
while (parent) {
|
|
279
|
+
if (parent._id === this._id) {
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
parent = parent.getParent();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
clone(obj?: any) {
|
|
288
|
+
// call super method
|
|
289
|
+
const node = Node.prototype.clone.call(this, obj);
|
|
290
|
+
|
|
291
|
+
this.getChildren().forEach(function (no) {
|
|
292
|
+
node.add(no.clone());
|
|
293
|
+
});
|
|
294
|
+
return node as this;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* get all shapes that intersect a point. Note: because this method must clear a temporary
|
|
298
|
+
* canvas and redraw every shape inside the container, it should only be used for special situations
|
|
299
|
+
* because it performs very poorly. Please use the {@link Konva.Stage#getIntersection} method if at all possible
|
|
300
|
+
* because it performs much better
|
|
301
|
+
* nodes with listening set to false will not be detected
|
|
302
|
+
* @method
|
|
303
|
+
* @name Konva.Container#getAllIntersections
|
|
304
|
+
* @param {Object} pos
|
|
305
|
+
* @param {Number} pos.x
|
|
306
|
+
* @param {Number} pos.y
|
|
307
|
+
* @returns {Array} array of shapes
|
|
308
|
+
*/
|
|
309
|
+
getAllIntersections(pos) {
|
|
310
|
+
const arr: Shape[] = [];
|
|
311
|
+
|
|
312
|
+
this.find<Shape>('Shape').forEach((shape) => {
|
|
313
|
+
if (shape.isVisible() && shape.intersects(pos)) {
|
|
314
|
+
arr.push(shape);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
return arr;
|
|
319
|
+
}
|
|
320
|
+
_clearSelfAndDescendantCache(attr?: string) {
|
|
321
|
+
super._clearSelfAndDescendantCache(attr);
|
|
322
|
+
// skip clearing if node is cached with canvas
|
|
323
|
+
// for performance reasons !!!
|
|
324
|
+
if (this.isCached()) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
this.children?.forEach(function (node) {
|
|
328
|
+
node._clearSelfAndDescendantCache(attr);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
_setChildrenIndices() {
|
|
332
|
+
this.children?.forEach(function (child, n) {
|
|
333
|
+
child.index = n;
|
|
334
|
+
});
|
|
335
|
+
this._requestDraw();
|
|
336
|
+
}
|
|
337
|
+
drawScene(can?: SceneCanvas, top?: Node, bufferCanvas?: SceneCanvas) {
|
|
338
|
+
const layer = this.getLayer()!,
|
|
339
|
+
canvas = can || (layer && layer.getCanvas()),
|
|
340
|
+
context = canvas && canvas.getContext(),
|
|
341
|
+
cachedCanvas = this._getCanvasCache(),
|
|
342
|
+
cachedSceneCanvas = cachedCanvas && cachedCanvas.scene;
|
|
343
|
+
|
|
344
|
+
const caching = canvas && canvas.isCache;
|
|
345
|
+
if (!this.isVisible() && !caching) {
|
|
346
|
+
return this;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (cachedSceneCanvas) {
|
|
350
|
+
context.save();
|
|
351
|
+
const m = this.getAbsoluteTransform(top).getMatrix();
|
|
352
|
+
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
353
|
+
this._drawCachedSceneCanvas(context);
|
|
354
|
+
context.restore();
|
|
355
|
+
} else {
|
|
356
|
+
this._drawChildren('drawScene', canvas, top, bufferCanvas);
|
|
357
|
+
}
|
|
358
|
+
return this;
|
|
359
|
+
}
|
|
360
|
+
drawHit(can?: HitCanvas, top?: Node) {
|
|
361
|
+
if (!this.shouldDrawHit(top)) {
|
|
362
|
+
return this;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const layer = this.getLayer()!,
|
|
366
|
+
canvas = can || (layer && layer.hitCanvas),
|
|
367
|
+
context = canvas && canvas.getContext(),
|
|
368
|
+
cachedCanvas = this._getCanvasCache(),
|
|
369
|
+
cachedHitCanvas = cachedCanvas && cachedCanvas.hit;
|
|
370
|
+
|
|
371
|
+
if (cachedHitCanvas) {
|
|
372
|
+
context.save();
|
|
373
|
+
const m = this.getAbsoluteTransform(top).getMatrix();
|
|
374
|
+
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
375
|
+
this._drawCachedHitCanvas(context);
|
|
376
|
+
context.restore();
|
|
377
|
+
} else {
|
|
378
|
+
this._drawChildren('drawHit', canvas, top);
|
|
379
|
+
}
|
|
380
|
+
return this;
|
|
381
|
+
}
|
|
382
|
+
_drawChildren(drawMethod, canvas, top, bufferCanvas?) {
|
|
383
|
+
const context = canvas && canvas.getContext(),
|
|
384
|
+
clipWidth = this.clipWidth(),
|
|
385
|
+
clipHeight = this.clipHeight(),
|
|
386
|
+
clipFunc = this.clipFunc(),
|
|
387
|
+
hasClip =
|
|
388
|
+
(typeof clipWidth === 'number' && typeof clipHeight === 'number') ||
|
|
389
|
+
clipFunc;
|
|
390
|
+
|
|
391
|
+
const selfCache = top === this;
|
|
392
|
+
|
|
393
|
+
if (hasClip) {
|
|
394
|
+
context.save();
|
|
395
|
+
const transform = this.getAbsoluteTransform(top);
|
|
396
|
+
let m = transform.getMatrix();
|
|
397
|
+
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
398
|
+
context.beginPath();
|
|
399
|
+
let clipArgs;
|
|
400
|
+
if (clipFunc) {
|
|
401
|
+
clipArgs = clipFunc.call(this, context, this);
|
|
402
|
+
} else {
|
|
403
|
+
const clipX = this.clipX();
|
|
404
|
+
const clipY = this.clipY();
|
|
405
|
+
context.rect(clipX || 0, clipY || 0, clipWidth, clipHeight);
|
|
406
|
+
}
|
|
407
|
+
context.clip.apply(context, clipArgs);
|
|
408
|
+
m = transform.copy().invert().getMatrix();
|
|
409
|
+
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const hasComposition =
|
|
413
|
+
!selfCache &&
|
|
414
|
+
this.globalCompositeOperation() !== 'source-over' &&
|
|
415
|
+
drawMethod === 'drawScene';
|
|
416
|
+
|
|
417
|
+
if (hasComposition) {
|
|
418
|
+
context.save();
|
|
419
|
+
context._applyGlobalCompositeOperation(this);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
this.children?.forEach(function (child) {
|
|
423
|
+
child[drawMethod](canvas, top, bufferCanvas);
|
|
424
|
+
});
|
|
425
|
+
if (hasComposition) {
|
|
426
|
+
context.restore();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (hasClip) {
|
|
430
|
+
context.restore();
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
getClientRect(
|
|
435
|
+
config: {
|
|
436
|
+
skipTransform?: boolean;
|
|
437
|
+
skipShadow?: boolean;
|
|
438
|
+
skipStroke?: boolean;
|
|
439
|
+
relativeTo?: Container<Node>;
|
|
440
|
+
} = {}
|
|
441
|
+
): IRect {
|
|
442
|
+
const skipTransform = config.skipTransform;
|
|
443
|
+
const relativeTo = config.relativeTo;
|
|
444
|
+
|
|
445
|
+
let minX, minY, maxX, maxY;
|
|
446
|
+
let selfRect = {
|
|
447
|
+
x: Infinity,
|
|
448
|
+
y: Infinity,
|
|
449
|
+
width: 0,
|
|
450
|
+
height: 0,
|
|
451
|
+
};
|
|
452
|
+
const that = this;
|
|
453
|
+
this.children?.forEach(function (child) {
|
|
454
|
+
// skip invisible children
|
|
455
|
+
if (!child.visible()) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const rect = child.getClientRect({
|
|
460
|
+
relativeTo: that,
|
|
461
|
+
skipShadow: config.skipShadow,
|
|
462
|
+
skipStroke: config.skipStroke,
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
// skip invisible children (like empty groups)
|
|
466
|
+
if (rect.width === 0 && rect.height === 0) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (minX === undefined) {
|
|
471
|
+
// initial value for first child
|
|
472
|
+
minX = rect.x;
|
|
473
|
+
minY = rect.y;
|
|
474
|
+
maxX = rect.x + rect.width;
|
|
475
|
+
maxY = rect.y + rect.height;
|
|
476
|
+
} else {
|
|
477
|
+
minX = Math.min(minX, rect.x);
|
|
478
|
+
minY = Math.min(minY, rect.y);
|
|
479
|
+
maxX = Math.max(maxX, rect.x + rect.width);
|
|
480
|
+
maxY = Math.max(maxY, rect.y + rect.height);
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// if child is group we need to make sure it has visible shapes inside
|
|
485
|
+
const shapes = this.find('Shape');
|
|
486
|
+
let hasVisible = false;
|
|
487
|
+
for (let i = 0; i < shapes.length; i++) {
|
|
488
|
+
const shape = shapes[i];
|
|
489
|
+
if (shape._isVisible(this)) {
|
|
490
|
+
hasVisible = true;
|
|
491
|
+
break;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (hasVisible && minX !== undefined) {
|
|
495
|
+
selfRect = {
|
|
496
|
+
x: minX,
|
|
497
|
+
y: minY,
|
|
498
|
+
width: maxX - minX,
|
|
499
|
+
height: maxY - minY,
|
|
500
|
+
};
|
|
501
|
+
} else {
|
|
502
|
+
selfRect = {
|
|
503
|
+
x: 0,
|
|
504
|
+
y: 0,
|
|
505
|
+
width: 0,
|
|
506
|
+
height: 0,
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (!skipTransform) {
|
|
511
|
+
return this._transformedRect(selfRect, relativeTo);
|
|
512
|
+
}
|
|
513
|
+
return selfRect;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
clip: GetSet<IRect, this>;
|
|
517
|
+
clipX: GetSet<number, this>;
|
|
518
|
+
clipY: GetSet<number, this>;
|
|
519
|
+
clipWidth: GetSet<number, this>;
|
|
520
|
+
clipHeight: GetSet<number, this>;
|
|
521
|
+
// there was "this" instead of "Container<ChildType>",
|
|
522
|
+
// but it breaks react-konva types: https://github.com/konvajs/react-konva/issues/390
|
|
523
|
+
clipFunc: GetSet<
|
|
524
|
+
(ctx: CanvasRenderingContext2D, shape: Container) => ClipFuncOutput,
|
|
525
|
+
this
|
|
526
|
+
>;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// add getters setters
|
|
530
|
+
Factory.addComponentsGetterSetter(Container, 'clip', [
|
|
531
|
+
'x',
|
|
532
|
+
'y',
|
|
533
|
+
'width',
|
|
534
|
+
'height',
|
|
535
|
+
]);
|
|
536
|
+
/**
|
|
537
|
+
* get/set clip
|
|
538
|
+
* @method
|
|
539
|
+
* @name Konva.Container#clip
|
|
540
|
+
* @param {Object} clip
|
|
541
|
+
* @param {Number} clip.x
|
|
542
|
+
* @param {Number} clip.y
|
|
543
|
+
* @param {Number} clip.width
|
|
544
|
+
* @param {Number} clip.height
|
|
545
|
+
* @returns {Object}
|
|
546
|
+
* @example
|
|
547
|
+
* // get clip
|
|
548
|
+
* var clip = container.clip();
|
|
549
|
+
*
|
|
550
|
+
* // set clip
|
|
551
|
+
* container.clip({
|
|
552
|
+
* x: 20,
|
|
553
|
+
* y: 20,
|
|
554
|
+
* width: 20,
|
|
555
|
+
* height: 20
|
|
556
|
+
* });
|
|
557
|
+
*/
|
|
558
|
+
|
|
559
|
+
Factory.addGetterSetter(Container, 'clipX', undefined, getNumberValidator());
|
|
560
|
+
/**
|
|
561
|
+
* get/set clip x
|
|
562
|
+
* @name Konva.Container#clipX
|
|
563
|
+
* @method
|
|
564
|
+
* @param {Number} x
|
|
565
|
+
* @returns {Number}
|
|
566
|
+
* @example
|
|
567
|
+
* // get clip x
|
|
568
|
+
* var clipX = container.clipX();
|
|
569
|
+
*
|
|
570
|
+
* // set clip x
|
|
571
|
+
* container.clipX(10);
|
|
572
|
+
*/
|
|
573
|
+
|
|
574
|
+
Factory.addGetterSetter(Container, 'clipY', undefined, getNumberValidator());
|
|
575
|
+
/**
|
|
576
|
+
* get/set clip y
|
|
577
|
+
* @name Konva.Container#clipY
|
|
578
|
+
* @method
|
|
579
|
+
* @param {Number} y
|
|
580
|
+
* @returns {Number}
|
|
581
|
+
* @example
|
|
582
|
+
* // get clip y
|
|
583
|
+
* var clipY = container.clipY();
|
|
584
|
+
*
|
|
585
|
+
* // set clip y
|
|
586
|
+
* container.clipY(10);
|
|
587
|
+
*/
|
|
588
|
+
|
|
589
|
+
Factory.addGetterSetter(
|
|
590
|
+
Container,
|
|
591
|
+
'clipWidth',
|
|
592
|
+
undefined,
|
|
593
|
+
getNumberValidator()
|
|
594
|
+
);
|
|
595
|
+
/**
|
|
596
|
+
* get/set clip width
|
|
597
|
+
* @name Konva.Container#clipWidth
|
|
598
|
+
* @method
|
|
599
|
+
* @param {Number} width
|
|
600
|
+
* @returns {Number}
|
|
601
|
+
* @example
|
|
602
|
+
* // get clip width
|
|
603
|
+
* var clipWidth = container.clipWidth();
|
|
604
|
+
*
|
|
605
|
+
* // set clip width
|
|
606
|
+
* container.clipWidth(100);
|
|
607
|
+
*/
|
|
608
|
+
|
|
609
|
+
Factory.addGetterSetter(
|
|
610
|
+
Container,
|
|
611
|
+
'clipHeight',
|
|
612
|
+
undefined,
|
|
613
|
+
getNumberValidator()
|
|
614
|
+
);
|
|
615
|
+
/**
|
|
616
|
+
* get/set clip height
|
|
617
|
+
* @name Konva.Container#clipHeight
|
|
618
|
+
* @method
|
|
619
|
+
* @param {Number} height
|
|
620
|
+
* @returns {Number}
|
|
621
|
+
* @example
|
|
622
|
+
* // get clip height
|
|
623
|
+
* var clipHeight = container.clipHeight();
|
|
624
|
+
*
|
|
625
|
+
* // set clip height
|
|
626
|
+
* container.clipHeight(100);
|
|
627
|
+
*/
|
|
628
|
+
|
|
629
|
+
Factory.addGetterSetter(Container, 'clipFunc');
|
|
630
|
+
/**
|
|
631
|
+
* get/set clip function
|
|
632
|
+
* @name Konva.Container#clipFunc
|
|
633
|
+
* @method
|
|
634
|
+
* @param {Function} function
|
|
635
|
+
* @returns {Function}
|
|
636
|
+
* @example
|
|
637
|
+
* // get clip function
|
|
638
|
+
* var clipFunction = container.clipFunc();
|
|
639
|
+
*
|
|
640
|
+
* // set clip function
|
|
641
|
+
* container.clipFunc(function(ctx) {
|
|
642
|
+
* ctx.rect(0, 0, 100, 100);
|
|
643
|
+
* });
|
|
644
|
+
*
|
|
645
|
+
* container.clipFunc(function(ctx) {
|
|
646
|
+
* // optionally return a clip Path2D and clip-rule or just the clip-rule
|
|
647
|
+
* return [new Path2D('M0 0v50h50Z'), 'evenodd']
|
|
648
|
+
* });
|
|
649
|
+
*/
|