@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.
Files changed (148) hide show
  1. package/debug/konva-master/CHANGELOG.md +1475 -0
  2. package/debug/konva-master/LICENSE +22 -0
  3. package/debug/konva-master/README.md +209 -0
  4. package/debug/konva-master/gulpfile.mjs +110 -0
  5. package/debug/konva-master/package.json +139 -0
  6. package/debug/konva-master/release.sh +62 -0
  7. package/debug/konva-master/resources/doc-includes/ContainerParams.txt +6 -0
  8. package/debug/konva-master/resources/doc-includes/NodeParams.txt +20 -0
  9. package/debug/konva-master/resources/doc-includes/ShapeParams.txt +53 -0
  10. package/debug/konva-master/resources/jsdoc.conf.json +28 -0
  11. package/debug/konva-master/rollup.config.mjs +32 -0
  12. package/debug/konva-master/src/Animation.ts +237 -0
  13. package/debug/konva-master/src/BezierFunctions.ts +826 -0
  14. package/debug/konva-master/src/Canvas.ts +230 -0
  15. package/debug/konva-master/src/Container.ts +649 -0
  16. package/debug/konva-master/src/Context.ts +1017 -0
  17. package/debug/konva-master/src/Core.ts +5 -0
  18. package/debug/konva-master/src/DragAndDrop.ts +173 -0
  19. package/debug/konva-master/src/Factory.ts +246 -0
  20. package/debug/konva-master/src/FastLayer.ts +29 -0
  21. package/debug/konva-master/src/Global.ts +210 -0
  22. package/debug/konva-master/src/Group.ts +31 -0
  23. package/debug/konva-master/src/Layer.ts +546 -0
  24. package/debug/konva-master/src/Node.ts +3477 -0
  25. package/debug/konva-master/src/PointerEvents.ts +67 -0
  26. package/debug/konva-master/src/Shape.ts +2081 -0
  27. package/debug/konva-master/src/Stage.ts +1000 -0
  28. package/debug/konva-master/src/Tween.ts +811 -0
  29. package/debug/konva-master/src/Util.ts +1123 -0
  30. package/debug/konva-master/src/Validators.ts +210 -0
  31. package/debug/konva-master/src/_CoreInternals.ts +85 -0
  32. package/debug/konva-master/src/_FullInternals.ts +171 -0
  33. package/debug/konva-master/src/canvas-backend.ts +36 -0
  34. package/debug/konva-master/src/filters/Blur.ts +388 -0
  35. package/debug/konva-master/src/filters/Brighten.ts +48 -0
  36. package/debug/konva-master/src/filters/Brightness.ts +30 -0
  37. package/debug/konva-master/src/filters/Contrast.ts +75 -0
  38. package/debug/konva-master/src/filters/Emboss.ts +207 -0
  39. package/debug/konva-master/src/filters/Enhance.ts +154 -0
  40. package/debug/konva-master/src/filters/Grayscale.ts +25 -0
  41. package/debug/konva-master/src/filters/HSL.ts +108 -0
  42. package/debug/konva-master/src/filters/HSV.ts +106 -0
  43. package/debug/konva-master/src/filters/Invert.ts +23 -0
  44. package/debug/konva-master/src/filters/Kaleidoscope.ts +274 -0
  45. package/debug/konva-master/src/filters/Mask.ts +220 -0
  46. package/debug/konva-master/src/filters/Noise.ts +44 -0
  47. package/debug/konva-master/src/filters/Pixelate.ts +107 -0
  48. package/debug/konva-master/src/filters/Posterize.ts +46 -0
  49. package/debug/konva-master/src/filters/RGB.ts +82 -0
  50. package/debug/konva-master/src/filters/RGBA.ts +103 -0
  51. package/debug/konva-master/src/filters/Sepia.ts +27 -0
  52. package/debug/konva-master/src/filters/Solarize.ts +29 -0
  53. package/debug/konva-master/src/filters/Threshold.ts +44 -0
  54. package/debug/konva-master/src/index.ts +3 -0
  55. package/debug/konva-master/src/shapes/Arc.ts +176 -0
  56. package/debug/konva-master/src/shapes/Arrow.ts +231 -0
  57. package/debug/konva-master/src/shapes/Circle.ts +76 -0
  58. package/debug/konva-master/src/shapes/Ellipse.ts +121 -0
  59. package/debug/konva-master/src/shapes/Image.ts +319 -0
  60. package/debug/konva-master/src/shapes/Label.ts +386 -0
  61. package/debug/konva-master/src/shapes/Line.ts +364 -0
  62. package/debug/konva-master/src/shapes/Path.ts +1013 -0
  63. package/debug/konva-master/src/shapes/Rect.ts +79 -0
  64. package/debug/konva-master/src/shapes/RegularPolygon.ts +167 -0
  65. package/debug/konva-master/src/shapes/Ring.ts +94 -0
  66. package/debug/konva-master/src/shapes/Sprite.ts +370 -0
  67. package/debug/konva-master/src/shapes/Star.ts +125 -0
  68. package/debug/konva-master/src/shapes/Text.ts +1065 -0
  69. package/debug/konva-master/src/shapes/TextPath.ts +583 -0
  70. package/debug/konva-master/src/shapes/Transformer.ts +1889 -0
  71. package/debug/konva-master/src/shapes/Wedge.ts +129 -0
  72. package/debug/konva-master/src/skia-backend.ts +35 -0
  73. package/debug/konva-master/src/types.ts +84 -0
  74. package/debug/konva-master/tsconfig.json +31 -0
  75. package/debug/konva-master/tsconfig.test.json +7 -0
  76. package/dist/index.js +977 -29
  77. package/dist/index.js.map +1 -1
  78. package/dist/index.min.js +1 -1
  79. package/dist/index.min.js.map +1 -1
  80. package/dist/index.min.mjs +1 -1
  81. package/dist/index.min.mjs.map +1 -1
  82. package/dist/index.mjs +977 -29
  83. package/dist/index.mjs.map +1 -1
  84. package/dist/index.node.cjs +977 -29
  85. package/dist/index.node.cjs.map +1 -1
  86. package/dist/index.node.mjs +977 -29
  87. package/dist/index.node.mjs.map +1 -1
  88. package/dist/package.json.min.mjs +1 -1
  89. package/dist/package.json.mjs +1 -1
  90. package/dist/src/shapes/Line.d.ts +1 -0
  91. package/dist/src/shapes/Line.d.ts.map +1 -1
  92. package/dist/src/shapes/Line.min.mjs +1 -1
  93. package/dist/src/shapes/Line.min.mjs.map +1 -1
  94. package/dist/src/shapes/Line.mjs +63 -6
  95. package/dist/src/shapes/Line.mjs.map +1 -1
  96. package/dist/src/shapes/Text/Text.d.ts +19 -0
  97. package/dist/src/shapes/Text/Text.d.ts.map +1 -1
  98. package/dist/src/shapes/Text/Text.min.mjs +1 -1
  99. package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
  100. package/dist/src/shapes/Text/Text.mjs +238 -4
  101. package/dist/src/shapes/Text/Text.mjs.map +1 -1
  102. package/dist/src/shapes/Textbox.d.ts +38 -1
  103. package/dist/src/shapes/Textbox.d.ts.map +1 -1
  104. package/dist/src/shapes/Textbox.min.mjs +1 -1
  105. package/dist/src/shapes/Textbox.min.mjs.map +1 -1
  106. package/dist/src/shapes/Textbox.mjs +497 -15
  107. package/dist/src/shapes/Textbox.mjs.map +1 -1
  108. package/dist/src/text/examples/arabicTextExample.d.ts +60 -0
  109. package/dist/src/text/examples/arabicTextExample.d.ts.map +1 -0
  110. package/dist/src/text/measure.d.ts +9 -0
  111. package/dist/src/text/measure.d.ts.map +1 -1
  112. package/dist/src/text/measure.min.mjs +1 -1
  113. package/dist/src/text/measure.min.mjs.map +1 -1
  114. package/dist/src/text/measure.mjs +175 -4
  115. package/dist/src/text/measure.mjs.map +1 -1
  116. package/dist/src/text/overlayEditor.d.ts.map +1 -1
  117. package/dist/src/text/overlayEditor.min.mjs +1 -1
  118. package/dist/src/text/overlayEditor.min.mjs.map +1 -1
  119. package/dist/src/text/overlayEditor.mjs +7 -0
  120. package/dist/src/text/overlayEditor.mjs.map +1 -1
  121. package/dist/src/text/scriptUtils.d.ts +142 -0
  122. package/dist/src/text/scriptUtils.d.ts.map +1 -0
  123. package/dist/src/text/scriptUtils.min.mjs +2 -0
  124. package/dist/src/text/scriptUtils.min.mjs.map +1 -0
  125. package/dist/src/text/scriptUtils.mjs +212 -0
  126. package/dist/src/text/scriptUtils.mjs.map +1 -0
  127. package/dist-extensions/src/shapes/Line.d.ts +1 -0
  128. package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
  129. package/dist-extensions/src/shapes/Text/Text.d.ts +19 -0
  130. package/dist-extensions/src/shapes/Text/Text.d.ts.map +1 -1
  131. package/dist-extensions/src/shapes/Textbox.d.ts +38 -1
  132. package/dist-extensions/src/shapes/Textbox.d.ts.map +1 -1
  133. package/dist-extensions/src/text/measure.d.ts +9 -0
  134. package/dist-extensions/src/text/measure.d.ts.map +1 -1
  135. package/dist-extensions/src/text/overlayEditor.d.ts.map +1 -1
  136. package/dist-extensions/src/text/scriptUtils.d.ts +142 -0
  137. package/dist-extensions/src/text/scriptUtils.d.ts.map +1 -0
  138. package/fabric-test-editor.html +2401 -46
  139. package/fabric-test2.html +43 -0
  140. package/fonts/STV Bold.ttf +0 -0
  141. package/fonts/STV Light.ttf +0 -0
  142. package/fonts/STV Regular.ttf +0 -0
  143. package/package.json +1 -1
  144. package/src/shapes/Line.ts +132 -46
  145. package/src/shapes/Text/Text.ts +238 -5
  146. package/src/shapes/Textbox.ts +521 -11
  147. package/src/text/measure.ts +200 -50
  148. 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
+ */