kritzel-stencil 0.3.11 → 0.3.12

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 (46) hide show
  1. package/dist/cjs/index.cjs.js +1 -1
  2. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +214 -50
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/{schema.constants-BNMNpzvA.js → schema.constants-CzfoUWxF.js} +4 -1
  5. package/dist/cjs/stencil.cjs.js +1 -1
  6. package/dist/collection/classes/objects/shape.class.js +1 -1
  7. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +96 -7
  8. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +302 -35
  9. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +27 -6
  10. package/dist/collection/configs/default-brush-tool.config.js +1 -0
  11. package/dist/collection/configs/default-line-tool.config.js +1 -0
  12. package/dist/collection/configs/default-shape-tool.config.js +1 -0
  13. package/dist/collection/configs/default-text-tool.config.js +1 -0
  14. package/dist/collection/constants/version.js +1 -1
  15. package/dist/components/index.js +1 -1
  16. package/dist/components/kritzel-controls.js +1 -1
  17. package/dist/components/kritzel-editor.js +1 -1
  18. package/dist/components/kritzel-engine.js +1 -1
  19. package/dist/components/kritzel-settings.js +1 -1
  20. package/dist/components/kritzel-tool-config.js +1 -1
  21. package/dist/components/{p-D15NO5kE.js → p-DIiGd0LS.js} +1 -1
  22. package/dist/components/{p-DLlIaDNn.js → p-DLh8x1jK.js} +2 -2
  23. package/dist/components/p-Do4UlU4e.js +1 -0
  24. package/dist/components/{p-BFgWBbpu.js → p-Dqjil3Hm.js} +1 -1
  25. package/dist/components/{p-B0VnbmWu.js → p-EFyZdR89.js} +1 -1
  26. package/dist/esm/index.js +2 -2
  27. package/dist/esm/kritzel-active-users_42.entry.js +214 -50
  28. package/dist/esm/loader.js +1 -1
  29. package/dist/esm/{schema.constants-CqBoZbmA.js → schema.constants-BcT1vV4J.js} +4 -1
  30. package/dist/esm/stencil.js +1 -1
  31. package/dist/stencil/index.esm.js +1 -1
  32. package/dist/stencil/p-0c95e585.entry.js +9 -0
  33. package/dist/stencil/{p-CqBoZbmA.js → p-BcT1vV4J.js} +1 -1
  34. package/dist/stencil/stencil.esm.js +1 -1
  35. package/dist/types/classes/objects/base-object.class.d.ts +1 -1
  36. package/dist/types/classes/objects/shape.class.d.ts +1 -1
  37. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +3 -0
  38. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +32 -0
  39. package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +1 -0
  40. package/dist/types/components.d.ts +43 -0
  41. package/dist/types/constants/version.d.ts +1 -1
  42. package/dist/types/interfaces/object.interface.d.ts +1 -1
  43. package/dist/types/interfaces/toolbar-control.interface.d.ts +4 -0
  44. package/package.json +1 -1
  45. package/dist/components/p-CB7ynHtI.js +0 -1
  46. package/dist/stencil/p-94992a11.entry.js +0 -9
@@ -129,6 +129,11 @@ export class KritzelEngine {
129
129
  onLockDrawingScaleChange(newValue) {
130
130
  this.core.store.state.lockDrawingScale = newValue;
131
131
  }
132
+ /** When true, objects fade based on distance to the viewport center. */
133
+ isObjectDistanceFadingActive = false;
134
+ onIsObjectDistanceFadingActiveChange() {
135
+ this.core.rerender();
136
+ }
132
137
  /** The current theme to apply to the editor */
133
138
  theme = 'light';
134
139
  onThemeChange(newValue) {
@@ -563,7 +568,7 @@ export class KritzelEngine {
563
568
  this.core.deselectAllObjects();
564
569
  object.id = object.generateId();
565
570
  object._core = this.core;
566
- object.scale = this.core.store.state.scale;
571
+ object.scale = object.scale ?? this.core.store.state.scale;
567
572
  object.zIndex = this.core.store.currentZIndex;
568
573
  object.workspaceId = this.core.store.state.activeWorkspace.id;
569
574
  // Handle KritzelText: recreate the editor now that _core is available
@@ -592,7 +597,7 @@ export class KritzelEngine {
592
597
  const oldId = child.id;
593
598
  child.id = child.generateId();
594
599
  child._core = this.core;
595
- child.scale = this.core.store.state.scale;
600
+ child.scale = child.scale ?? this.core.store.state.scale;
596
601
  child.zIndex = this.core.store.currentZIndex;
597
602
  child.workspaceId = this.core.store.state.activeWorkspace.id;
598
603
  idRemapping.set(oldId, child.id);
@@ -638,6 +643,82 @@ export class KritzelEngine {
638
643
  this.emitObjectsAdded([object]);
639
644
  return object;
640
645
  }
646
+ /**
647
+ * Adds multiple objects to the canvas in a single batch operation.
648
+ * All objects are inserted within one Yjs transaction (single undo step),
649
+ * triggering only one rerender cycle. Intended for programmatic streaming
650
+ * scenarios where per-object overhead would cause stutter.
651
+ * @param objects - The object instances to add.
652
+ * @returns The added objects.
653
+ */
654
+ async addObjects(objects) {
655
+ if (objects.length === 0) {
656
+ return [];
657
+ }
658
+ this.core.store.objects.transaction(() => {
659
+ for (const object of objects) {
660
+ object.id = object.generateId();
661
+ object._core = this.core;
662
+ object.zIndex = this.core.store.currentZIndex;
663
+ object.workspaceId = this.core.store.state.activeWorkspace.id;
664
+ if (KritzelClassHelper.isInstanceOf(object, 'KritzelText')) {
665
+ const pendingContent = object.content;
666
+ object.editor = object.createEditor();
667
+ if (pendingContent) {
668
+ object.setContent(pendingContent);
669
+ }
670
+ }
671
+ if (KritzelClassHelper.isInstanceOf(object, 'KritzelGroup') && object._pendingChildren.length > 0) {
672
+ const idRemapping = new Map();
673
+ const allFlushedChildren = [];
674
+ const flushGroup = (group) => {
675
+ if (group._pendingChildren.length === 0) {
676
+ return;
677
+ }
678
+ const pending = group._pendingChildren;
679
+ group._pendingChildren = [];
680
+ group.childIds = [];
681
+ pending.forEach(child => {
682
+ const oldId = child.id;
683
+ child.id = child.generateId();
684
+ child._core = this.core;
685
+ child.zIndex = this.core.store.currentZIndex;
686
+ child.workspaceId = this.core.store.state.activeWorkspace.id;
687
+ idRemapping.set(oldId, child.id);
688
+ group.childIds.push(child.id);
689
+ allFlushedChildren.push(child);
690
+ if (KritzelClassHelper.isInstanceOf(child, 'KritzelGroup')) {
691
+ flushGroup(child);
692
+ }
693
+ });
694
+ };
695
+ flushGroup(object);
696
+ allFlushedChildren.forEach(child => {
697
+ if (KritzelClassHelper.isInstanceOf(child, 'KritzelLine')) {
698
+ if (child.startAnchor && idRemapping.has(child.startAnchor.objectId)) {
699
+ child.startAnchor = { objectId: idRemapping.get(child.startAnchor.objectId) };
700
+ }
701
+ if (child.endAnchor && idRemapping.has(child.endAnchor.objectId)) {
702
+ child.endAnchor = { objectId: idRemapping.get(child.endAnchor.objectId) };
703
+ }
704
+ }
705
+ });
706
+ allFlushedChildren.forEach(child => {
707
+ this.core.addObject(child);
708
+ });
709
+ object.finalize();
710
+ this.core.anchorManager.rebuildIndex();
711
+ }
712
+ this.core.addObject(object);
713
+ }
714
+ });
715
+ this.core.rerender();
716
+ await new Promise(resolve => {
717
+ requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
718
+ });
719
+ this.emitObjectsAdded(objects);
720
+ return objects;
721
+ }
641
722
  /**
642
723
  * Updates properties of an existing canvas object.
643
724
  * @param object - The object to update.
@@ -667,6 +748,28 @@ export class KritzelEngine {
667
748
  this.emitObjectsRemoved([object]);
668
749
  return object;
669
750
  }
751
+ /**
752
+ * Removes multiple objects from the canvas in a single batch operation.
753
+ * All removals happen within one Yjs transaction (single undo step),
754
+ * triggering only one rerender cycle. Intended for programmatic streaming
755
+ * scenarios where per-object overhead would cause stutter.
756
+ * @param objects - The objects to remove.
757
+ * @returns The removed objects.
758
+ */
759
+ async removeObjects(objects) {
760
+ const objectsMap = this.core.store.objects;
761
+ if (!objectsMap || objects.length === 0) {
762
+ return [];
763
+ }
764
+ objectsMap.transaction(() => {
765
+ for (const object of objects) {
766
+ this.core.removeObject(object);
767
+ }
768
+ });
769
+ this.core.rerender();
770
+ this.emitObjectsRemoved(objects);
771
+ return objects;
772
+ }
670
773
  /** Returns the currently selected objects. Returns an empty array if nothing is selected. */
671
774
  async getSelectedObjects() {
672
775
  const selectionGroup = this.core.store.selectionGroup;
@@ -1321,6 +1424,12 @@ export class KritzelEngine {
1321
1424
  undoStackSize: 0,
1322
1425
  redoStackSize: 0,
1323
1426
  };
1427
+ _objectDistanceFadeNearScale = 1;
1428
+ _objectDistanceFadeFarScale = 0.15;
1429
+ _objectDistanceFadeMinOpacity = 0;
1430
+ _objectDistanceFadeCloseStartScale = 2;
1431
+ _objectDistanceFadeCloseMaxScale = 4;
1432
+ _objectDistanceFadeCloseMinOpacity = 0;
1324
1433
  syncLoadingState() {
1325
1434
  this.core.store.state.isLoading = this._isWorkspaceLoading || this.isLoading;
1326
1435
  }
@@ -1629,6 +1738,54 @@ export class KritzelEngine {
1629
1738
  KritzelKeyboardHelper.forceHideKeyboard();
1630
1739
  this.core.rerender();
1631
1740
  }
1741
+ getObjectDistanceFadeMultiplier(objectScale, viewportScale) {
1742
+ if (!this.isObjectDistanceFadingActive) {
1743
+ return 1;
1744
+ }
1745
+ const safeViewportScale = Math.max(Number.isFinite(viewportScale) ? viewportScale : 1, Number.EPSILON);
1746
+ const safeObjectScale = Math.max(Number.isFinite(objectScale) ? objectScale : 1, Number.EPSILON);
1747
+ const normalizedScale = safeViewportScale / safeObjectScale;
1748
+ const farFadeMultiplier = this.getFarDistanceFadeMultiplier(normalizedScale);
1749
+ const closeFadeMultiplier = this.getCloseDistanceFadeMultiplier(normalizedScale);
1750
+ return Math.min(farFadeMultiplier, closeFadeMultiplier);
1751
+ }
1752
+ getFarDistanceFadeMultiplier(normalizedScale) {
1753
+ if (normalizedScale >= this._objectDistanceFadeNearScale) {
1754
+ return 1;
1755
+ }
1756
+ if (normalizedScale <= this._objectDistanceFadeFarScale) {
1757
+ return this._objectDistanceFadeMinOpacity;
1758
+ }
1759
+ const progress = (this._objectDistanceFadeNearScale - normalizedScale) /
1760
+ (this._objectDistanceFadeNearScale - this._objectDistanceFadeFarScale);
1761
+ const smooth = progress * progress * (3 - 2 * progress);
1762
+ return 1 - smooth * (1 - this._objectDistanceFadeMinOpacity);
1763
+ }
1764
+ getCloseDistanceFadeMultiplier(normalizedScale) {
1765
+ if (normalizedScale <= this._objectDistanceFadeCloseStartScale) {
1766
+ return 1;
1767
+ }
1768
+ if (normalizedScale >= this._objectDistanceFadeCloseMaxScale) {
1769
+ return this._objectDistanceFadeCloseMinOpacity;
1770
+ }
1771
+ const progress = (normalizedScale - this._objectDistanceFadeCloseStartScale) /
1772
+ (this._objectDistanceFadeCloseMaxScale - this._objectDistanceFadeCloseStartScale);
1773
+ const smooth = progress * progress * (3 - 2 * progress);
1774
+ return 1 - smooth * (1 - this._objectDistanceFadeCloseMinOpacity);
1775
+ }
1776
+ shouldApplyDistanceFade(object) {
1777
+ return (!KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') &&
1778
+ !KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionBox'));
1779
+ }
1780
+ getObjectEffectiveOpacity(object, viewportScale) {
1781
+ const safeObjectOpacity = Number.isFinite(object.opacity) ? object.opacity : 1;
1782
+ const distanceFadeMultiplier = this.shouldApplyDistanceFade(object)
1783
+ ? this.getObjectDistanceFadeMultiplier(object.scale, viewportScale)
1784
+ : 1;
1785
+ const multiplied = (object.markedForRemoval ? 0.5 : 1) * safeObjectOpacity * distanceFadeMultiplier;
1786
+ const overridden = ((object.markedForRemoval ? 0.5 : safeObjectOpacity) * distanceFadeMultiplier).toString();
1787
+ return { multiplied, overridden };
1788
+ }
1632
1789
  render() {
1633
1790
  if (!this.viewport) {
1634
1791
  return (h(Host, null, this.core.store.state.isLoading && (h("div", { class: "workspace-loading-overlay" }, h("span", { class: "workspace-loading-spinner" }), "Loading..."))));
@@ -1638,6 +1795,7 @@ export class KritzelEngine {
1638
1795
  const baseHandleSizePx = computedStyle.getPropertyValue('--kritzel-selection-handle-size').trim() || '6px';
1639
1796
  const baseHandleSize = parseFloat(baseHandleSizePx);
1640
1797
  const baseHandleTouchSize = baseHandleSize * 2 < 14 ? 14 : baseHandleSize;
1798
+ const viewportScale = this.core.store.state.scale;
1641
1799
  const viewportCenterX = this.core.store.state.viewportWidth / 2 + this.core.store.state.translateX;
1642
1800
  const viewportCenterY = this.core.store.state.viewportHeight / 2 + this.core.store.state.translateY;
1643
1801
  const visibleObjects = this.core.store.objectsInViewport;
@@ -1651,39 +1809,34 @@ export class KritzelEngine {
1651
1809
  return (h(Host, null, this.core.store.state.isLoading && (h("div", { class: "workspace-loading-overlay" }, h("span", { class: "workspace-loading-spinner" }), "Loading...")), this.core.store.state.debugInfo.showViewportInfo && (h("div", { class: "debug-panel" }, h("div", null, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", null, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", null, "TranslateX: ", this.core.store.state?.translateX), h("div", null, "TranslateY: ", this.core.store.state?.translateY), h("div", null, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", null, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", null, "PointerCount: ", this.core.store.state.pointers.size), h("div", null, "Scale: ", this.core.store.state?.scale), h("div", null, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", null, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", null, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", null, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", null, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", null, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", null, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", null, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", null, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", null, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", null, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", null, "PointerX: ", this.core.store.state?.pointerX), h("div", null, "PointerY: ", this.core.store.state?.pointerY), h("div", null, "TotalObjects: ", this.core.store.totalObjectCount), h("div", null, "ObjectsInViewport: ", this.core.store.objectsInViewport.length), h("div", null, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", null, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { id: "origin", class: "origin", style: {
1652
1810
  transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
1653
1811
  } }, visibleObjects?.map(object => {
1812
+ const { multiplied: effectiveOpacity, overridden: effectiveOpacityString } = this.getObjectEffectiveOpacity(object, viewportScale);
1654
1813
  return (h("div", { key: object.id, id: object.id, class: "object", style: {
1655
1814
  transform: object?.transformationMatrix,
1656
1815
  transformOrigin: 'top left',
1657
1816
  position: 'absolute',
1658
1817
  zIndex: object.zIndex.toString(),
1659
1818
  pointerEvents: this.core.store.state.isScaling ? 'none' : 'auto',
1660
- } }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (() => {
1661
- const effectiveOpacity = (object.markedForRemoval ? 0.5 : 1) * object.opacity;
1662
- return (h("svg", { ref: el => el && object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: {
1663
- height: object?.totalHeight + 'px',
1664
- width: object?.totalWidth + 'px',
1665
- left: '0',
1666
- top: '0',
1667
- position: 'absolute',
1668
- transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
1669
- transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
1670
- pointerEvents: object.markedForRemoval ? 'none' : 'auto',
1671
- overflow: 'visible',
1672
- }, viewBox: object?.viewBox }, h("path", { d: object?.d, fill: KritzelColorHelper.applyOpacity(object.fill, effectiveOpacity, currentTheme), stroke: KritzelColorHelper.applyOpacity(object?.stroke, effectiveOpacity, currentTheme), "shape-rendering": object.isLowRes() ? 'optimizeSpeed' : 'auto' })));
1673
- })(), KritzelClassHelper.isInstanceOf(object, 'KritzelLine') && (() => {
1674
- const effectiveOpacity = (object.markedForRemoval ? 0.5 : 1) * object.opacity;
1675
- return (h("svg", { ref: el => el && object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: {
1676
- height: object?.totalHeight + 'px',
1677
- width: object?.totalWidth + 'px',
1678
- left: '0',
1679
- top: '0',
1680
- position: 'absolute',
1681
- transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
1682
- transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
1683
- pointerEvents: object.markedForRemoval ? 'none' : 'auto',
1684
- overflow: 'visible',
1685
- }, viewBox: object?.viewBox }, (object.hasStartArrow || object.hasEndArrow) && (h("defs", null, object.hasStartArrow && (h("marker", { id: object.startMarkerId, markerWidth: object.getArrowSize('start'), markerHeight: object.getArrowSize('start'), refX: 0, refY: object.getArrowSize('start') / 2, orient: "auto-start-reverse", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.start?.style), fill: KritzelColorHelper.applyOpacity(object.getArrowFill('start'), effectiveOpacity), transform: `scale(${object.getArrowSize('start') / 10})` }))), object.hasEndArrow && (h("marker", { id: object.endMarkerId, markerWidth: object.getArrowSize('end'), markerHeight: object.getArrowSize('end'), refX: 0, refY: object.getArrowSize('end') / 2, orient: "auto", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.end?.style), fill: KritzelColorHelper.applyOpacity(object.getArrowFill('end'), effectiveOpacity), transform: `scale(${object.getArrowSize('end') / 10})` }))))), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: "transparent", "stroke-width": Math.max(object?.strokeWidth || 0, 10), "stroke-linecap": "round" }), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: KritzelColorHelper.applyOpacity(object?.stroke, effectiveOpacity, currentTheme), "stroke-width": object?.strokeWidth, "stroke-linecap": "round", "marker-start": object.hasStartArrow ? `url(#${object.startMarkerId})` : undefined, "marker-end": object.hasEndArrow ? `url(#${object.endMarkerId})` : undefined })));
1686
- })(), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && object.loadState === 'ready' && (h("img", { ref: el => el && object.mount(el), src: object.resolvedSrc || object.src, style: {
1819
+ } }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (h("svg", { ref: el => el && object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: {
1820
+ height: object?.totalHeight + 'px',
1821
+ width: object?.totalWidth + 'px',
1822
+ left: '0',
1823
+ top: '0',
1824
+ position: 'absolute',
1825
+ transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
1826
+ transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
1827
+ pointerEvents: object.markedForRemoval ? 'none' : 'auto',
1828
+ overflow: 'visible',
1829
+ }, viewBox: object?.viewBox }, h("path", { d: object?.d, fill: KritzelColorHelper.applyOpacity(object.fill, effectiveOpacity, currentTheme), stroke: KritzelColorHelper.applyOpacity(object?.stroke, effectiveOpacity, currentTheme), "shape-rendering": object.isLowRes() ? 'optimizeSpeed' : 'auto' }))), KritzelClassHelper.isInstanceOf(object, 'KritzelLine') && (h("svg", { ref: el => el && object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: {
1830
+ height: object?.totalHeight + 'px',
1831
+ width: object?.totalWidth + 'px',
1832
+ left: '0',
1833
+ top: '0',
1834
+ position: 'absolute',
1835
+ transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
1836
+ transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
1837
+ pointerEvents: object.markedForRemoval ? 'none' : 'auto',
1838
+ overflow: 'visible',
1839
+ }, viewBox: object?.viewBox }, (object.hasStartArrow || object.hasEndArrow) && (h("defs", null, object.hasStartArrow && (h("marker", { id: object.startMarkerId, markerWidth: object.getArrowSize('start'), markerHeight: object.getArrowSize('start'), refX: 0, refY: object.getArrowSize('start') / 2, orient: "auto-start-reverse", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.start?.style), fill: KritzelColorHelper.applyOpacity(object.getArrowFill('start'), effectiveOpacity), transform: `scale(${object.getArrowSize('start') / 10})` }))), object.hasEndArrow && (h("marker", { id: object.endMarkerId, markerWidth: object.getArrowSize('end'), markerHeight: object.getArrowSize('end'), refX: 0, refY: object.getArrowSize('end') / 2, orient: "auto", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.end?.style), fill: KritzelColorHelper.applyOpacity(object.getArrowFill('end'), effectiveOpacity), transform: `scale(${object.getArrowSize('end') / 10})` }))))), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: "transparent", "stroke-width": Math.max(object?.strokeWidth || 0, 10), "stroke-linecap": "round" }), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: KritzelColorHelper.applyOpacity(object?.stroke, effectiveOpacity, currentTheme), "stroke-width": object?.strokeWidth, "stroke-linecap": "round", "marker-start": object.hasStartArrow ? `url(#${object.startMarkerId})` : undefined, "marker-end": object.hasEndArrow ? `url(#${object.endMarkerId})` : undefined }))), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && object.loadState === 'ready' && (h("img", { ref: el => el && object.mount(el), src: object.resolvedSrc || object.src, style: {
1687
1840
  position: 'absolute',
1688
1841
  left: '0',
1689
1842
  top: '0',
@@ -1691,7 +1844,7 @@ export class KritzelEngine {
1691
1844
  height: object.totalHeight + 'px',
1692
1845
  transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
1693
1846
  transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
1694
- opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
1847
+ opacity: effectiveOpacityString,
1695
1848
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
1696
1849
  backgroundColor: KritzelColorHelper.resolveThemeColor(object.backgroundColor, currentTheme),
1697
1850
  borderColor: KritzelColorHelper.resolveThemeColor(object.borderColor, currentTheme),
@@ -1709,7 +1862,7 @@ export class KritzelEngine {
1709
1862
  height: object.totalHeight + 'px',
1710
1863
  transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
1711
1864
  transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
1712
- opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
1865
+ opacity: effectiveOpacityString,
1713
1866
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
1714
1867
  backgroundColor: KritzelColorHelper.resolveThemeColor({ light: '#e5e7eb', dark: '#2a2a2a' }, currentTheme),
1715
1868
  borderColor: object.loadState === 'error'
@@ -1733,7 +1886,7 @@ export class KritzelEngine {
1733
1886
  height: object.totalHeight + 'px',
1734
1887
  transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
1735
1888
  transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
1736
- opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
1889
+ opacity: effectiveOpacityString,
1737
1890
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
1738
1891
  backgroundColor: KritzelColorHelper.resolveThemeColor(object.backgroundColor, currentTheme),
1739
1892
  borderColor: KritzelColorHelper.resolveThemeColor(object.borderColor, currentTheme),
@@ -1774,7 +1927,7 @@ export class KritzelEngine {
1774
1927
  height: object.totalHeight + 'px',
1775
1928
  transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
1776
1929
  transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
1777
- opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
1930
+ opacity: effectiveOpacityString,
1778
1931
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
1779
1932
  } }, h("div", { id: "text-object", ref: el => el && object.mount(el), onPointerDown: e => object.handlePointerDown(e), onPointerMove: e => object.handlePointerMove(e), onPointerUp: e => object.handlePointerUp(e), style: {
1780
1933
  minWidth: object.initialWidth + 'px',
@@ -1787,7 +1940,6 @@ export class KritzelEngine {
1787
1940
  backgroundColor: KritzelColorHelper.resolveThemeColor(object.backgroundColor, currentTheme),
1788
1941
  overflow: 'visible',
1789
1942
  } }))), KritzelClassHelper.isInstanceOf(object, 'KritzelShape') && (() => {
1790
- const effectiveOpacity = (object.markedForRemoval ? 0.5 : 1) * object.opacity;
1791
1943
  const fillResolved = KritzelColorHelper.resolveThemeColor(object.fillColor, currentTheme);
1792
1944
  const strokeResolved = KritzelColorHelper.resolveThemeColor(object.strokeColor, currentTheme);
1793
1945
  const isFilled = !!fillResolved && fillResolved !== 'transparent';
@@ -1829,7 +1981,7 @@ export class KritzelEngine {
1829
1981
  left: `${object.totalWidth}px`,
1830
1982
  top: '0',
1831
1983
  zIndex: (object.zIndex + 2).toString(),
1832
- } }, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "Id: ", object.id), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "userId: ", object.userId), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "translateY: ", object.translateY), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "rotationDegrees: ", object.rotationDegrees), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "zIndex: ", object.zIndex), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (h("div", null, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "assetId: ", object.assetId), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "mimeType: ", object.mimeType))))), (this.core.displaySelectionGroupUI(object) || this.core.displaySelectionLineUI(object)) &&
1984
+ } }, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "Id: ", object.id), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "userId: ", object.userId), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "translateY: ", object.translateY), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "scale: ", object.scale), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "rotationDegrees: ", object.rotationDegrees), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "zIndex: ", object.zIndex), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (h("div", null, h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "assetId: ", object.assetId), h("div", { style: { whiteSpace: 'nowrap', fontSize: '10px' } }, "mimeType: ", object.mimeType))))), (this.core.displaySelectionGroupUI(object) || this.core.displaySelectionLineUI(object)) &&
1833
1985
  (() => {
1834
1986
  const isSelectionGroup = KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup');
1835
1987
  const localClientId = this.core.store.objects?.localClientId;
@@ -2354,6 +2506,26 @@ export class KritzelEngine {
2354
2506
  "attribute": "lock-drawing-scale",
2355
2507
  "defaultValue": "true"
2356
2508
  },
2509
+ "isObjectDistanceFadingActive": {
2510
+ "type": "boolean",
2511
+ "mutable": false,
2512
+ "complexType": {
2513
+ "original": "boolean",
2514
+ "resolved": "boolean",
2515
+ "references": {}
2516
+ },
2517
+ "required": false,
2518
+ "optional": false,
2519
+ "docs": {
2520
+ "tags": [],
2521
+ "text": "When true, objects fade based on distance to the viewport center."
2522
+ },
2523
+ "getter": false,
2524
+ "setter": false,
2525
+ "reflect": false,
2526
+ "attribute": "is-object-distance-fading-active",
2527
+ "defaultValue": "false"
2528
+ },
2357
2529
  "theme": {
2358
2530
  "type": "string",
2359
2531
  "mutable": false,
@@ -3573,6 +3745,61 @@ export class KritzelEngine {
3573
3745
  }]
3574
3746
  }
3575
3747
  },
3748
+ "addObjects": {
3749
+ "complexType": {
3750
+ "signature": "<T extends KritzelBaseObject>(objects: T[]) => Promise<T[]>",
3751
+ "parameters": [{
3752
+ "name": "objects",
3753
+ "type": "T[]",
3754
+ "docs": "- The object instances to add."
3755
+ }],
3756
+ "references": {
3757
+ "Promise": {
3758
+ "location": "global",
3759
+ "id": "global::Promise"
3760
+ },
3761
+ "T": {
3762
+ "location": "global",
3763
+ "id": "global::T"
3764
+ },
3765
+ "KritzelBaseObject": {
3766
+ "location": "import",
3767
+ "path": "../../../classes/objects/base-object.class",
3768
+ "id": "src/classes/objects/base-object.class.ts::KritzelBaseObject",
3769
+ "referenceLocation": "KritzelBaseObject"
3770
+ },
3771
+ "KritzelText": {
3772
+ "location": "import",
3773
+ "path": "../../../classes/objects/text.class",
3774
+ "id": "src/classes/objects/text.class.ts::KritzelText",
3775
+ "referenceLocation": "KritzelText"
3776
+ },
3777
+ "KritzelGroup": {
3778
+ "location": "import",
3779
+ "path": "../../../classes/objects/group.class",
3780
+ "id": "src/classes/objects/group.class.ts::KritzelGroup",
3781
+ "referenceLocation": "KritzelGroup"
3782
+ },
3783
+ "KritzelLine": {
3784
+ "location": "import",
3785
+ "path": "../../../classes/objects/line.class",
3786
+ "id": "src/classes/objects/line.class.ts::KritzelLine",
3787
+ "referenceLocation": "KritzelLine"
3788
+ }
3789
+ },
3790
+ "return": "Promise<T[]>"
3791
+ },
3792
+ "docs": {
3793
+ "text": "Adds multiple objects to the canvas in a single batch operation.\nAll objects are inserted within one Yjs transaction (single undo step),\ntriggering only one rerender cycle. Intended for programmatic streaming\nscenarios where per-object overhead would cause stutter.",
3794
+ "tags": [{
3795
+ "name": "param",
3796
+ "text": "objects - The object instances to add."
3797
+ }, {
3798
+ "name": "returns",
3799
+ "text": "The added objects."
3800
+ }]
3801
+ }
3802
+ },
3576
3803
  "updateObject": {
3577
3804
  "complexType": {
3578
3805
  "signature": "<T extends KritzelBaseObject>(object: T, updatedProperties: Partial<T>) => Promise<T | null>",
@@ -3658,6 +3885,43 @@ export class KritzelEngine {
3658
3885
  }]
3659
3886
  }
3660
3887
  },
3888
+ "removeObjects": {
3889
+ "complexType": {
3890
+ "signature": "<T extends KritzelBaseObject>(objects: T[]) => Promise<T[]>",
3891
+ "parameters": [{
3892
+ "name": "objects",
3893
+ "type": "T[]",
3894
+ "docs": "- The objects to remove."
3895
+ }],
3896
+ "references": {
3897
+ "Promise": {
3898
+ "location": "global",
3899
+ "id": "global::Promise"
3900
+ },
3901
+ "T": {
3902
+ "location": "global",
3903
+ "id": "global::T"
3904
+ },
3905
+ "KritzelBaseObject": {
3906
+ "location": "import",
3907
+ "path": "../../../classes/objects/base-object.class",
3908
+ "id": "src/classes/objects/base-object.class.ts::KritzelBaseObject",
3909
+ "referenceLocation": "KritzelBaseObject"
3910
+ }
3911
+ },
3912
+ "return": "Promise<T[]>"
3913
+ },
3914
+ "docs": {
3915
+ "text": "Removes multiple objects from the canvas in a single batch operation.\nAll removals happen within one Yjs transaction (single undo step),\ntriggering only one rerender cycle. Intended for programmatic streaming\nscenarios where per-object overhead would cause stutter.",
3916
+ "tags": [{
3917
+ "name": "param",
3918
+ "text": "objects - The objects to remove."
3919
+ }, {
3920
+ "name": "returns",
3921
+ "text": "The removed objects."
3922
+ }]
3923
+ }
3924
+ },
3661
3925
  "getSelectedObjects": {
3662
3926
  "complexType": {
3663
3927
  "signature": "() => Promise<KritzelBaseObject<any>[]>",
@@ -4724,6 +4988,9 @@ export class KritzelEngine {
4724
4988
  }, {
4725
4989
  "propName": "lockDrawingScale",
4726
4990
  "methodName": "onLockDrawingScaleChange"
4991
+ }, {
4992
+ "propName": "isObjectDistanceFadingActive",
4993
+ "methodName": "onIsObjectDistanceFadingActiveChange"
4727
4994
  }, {
4728
4995
  "propName": "theme",
4729
4996
  "methodName": "onThemeChange"
@@ -6,6 +6,7 @@ import { KritzelToolConfigHelper } from "../../../helpers/tool-config.helper";
6
6
  import { KritzelColorHelper } from "../../../helpers/color.helper";
7
7
  export class KritzelControls {
8
8
  host;
9
+ visible = true;
9
10
  controls = [];
10
11
  activeControl = null;
11
12
  isUtilityPanelVisible = true;
@@ -230,13 +231,13 @@ export class KritzelControls {
230
231
  // Separate tool controls from config control
231
232
  const toolControls = this.internalControls.filter(c => c.type === 'tool' || c.type === 'separator');
232
233
  const configControl = this.internalControls.find(c => c.type === 'config' && c.name === this.firstConfig?.name);
233
- return (h(Host, { key: 'b567aac7bca12cc5ffb0ee1eb9e6978636aa3c31', class: {
234
+ return (h(Host, { key: '0f40a136a6a9556080d922d346318045794421a8', style: { display: this.visible ? '' : 'none' }, class: {
234
235
  mobile: this.isTouchDevice,
235
- } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '88e8ae9ae7429987724df70895b02a3f59216364', style: {
236
+ } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: 'd543e7575cb30e54d9362eddf7c7221fb8cce5f5', style: {
236
237
  position: 'absolute',
237
238
  bottom: '56px',
238
239
  left: '12px',
239
- }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '658e3d7b94e49a002d5057c1fb4fc199a371c48d', class: "kritzel-controls" }, h("div", { key: 'b54bb52a43e4a94ae1148cd4e75528bcaad681ef', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), h("div", { key: '36ce760357d3228141281a45c0ac7b0024b04795', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
240
+ }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '1083380152e9d1b51c35da335533c20ca2ca8fcc', class: "kritzel-controls" }, h("div", { key: '11ef0fb76c30ffda0e30f01d43229ca2142a5854', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), h("div", { key: '269924a8859aece37ff31202307d4feaecbbde86', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
240
241
  // Check if this control has sub-options (split-button)
241
242
  if (control.subOptions?.length) {
242
243
  const selectedSubOption = this.getSelectedSubOption(control);
@@ -266,10 +267,10 @@ export class KritzelControls {
266
267
  'kritzel-control': true,
267
268
  'selected': this.activeControl?.name === control?.name,
268
269
  }, key: control.name, "data-testid": `tool-${control.name}`, onClick: _event => this.handleControlClick?.(control), "aria-label": control.name.charAt(0).toUpperCase() + control.name.slice(1) }, h("kritzel-icon", { name: control.icon })));
269
- })), h("div", { key: 'f0b1e0f74fe197f4d39e307e7dd8dd4819c4b183', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (h("div", { class: {
270
+ })), h("div", { key: '8b97a5bba3ac4992482e8f433d7ba6197918a914', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (h("div", { class: {
270
271
  'kritzel-config-container': true,
271
272
  'visible': hasConfigUI,
272
- }, key: configControl.name }, h("div", { key: '51cc3ebf13092e710048441ff64856edd4f53dfc', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), h("kritzel-tooltip", { key: 'dcace186ae3ece1d7e943f51b48ed5094d847284', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, h("kritzel-tool-config", { key: '9b16ac90f335fec3c043545fa0c5b363ab99924e', tool: this.activeControl.tool, theme: this.theme, engine: this.kritzelEngine, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), h("div", { key: '2425507968e27a01b66c1d7be79a40ebe77cd27d', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
273
+ }, key: configControl.name }, h("div", { key: 'd9adef8c2acc8d9b9d745174050ce78960b89b58', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), h("kritzel-tooltip", { key: '7605bbd2b6335c89c57aa68952293f26efad6b4b', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, h("kritzel-tool-config", { key: '27b0f41442215e78b692fa44bb665444a4993b89', tool: this.activeControl.tool, theme: this.theme, engine: this.kritzelEngine, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), h("div", { key: '1fb5979b1c531593acf5086861b22b7d78d03e8d', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
273
274
  if (el)
274
275
  this.configTriggerRef = el;
275
276
  }, onKeyDown: event => {
@@ -278,7 +279,7 @@ export class KritzelControls {
278
279
  }
279
280
  }, style: {
280
281
  cursor: 'pointer',
281
- } }, this.displayValues && (h("div", { key: 'd2499df3c0a90c101957f55664452739e0f1692b', class: "color-container" }, h("kritzel-color", { key: 'b7cfcd3a8579c63f508c2786eecace1223e88974', value: this.displayValues.color, theme: this.theme, size: 18, style: {
282
+ } }, this.displayValues && (h("div", { key: '3713ef344630f6b4d88df2e83992018859ddb18c', class: "color-container" }, h("kritzel-color", { key: 'c2679f68efae77c6daeb98be9e03d5320d51a73a', value: this.displayValues.color, theme: this.theme, size: 18, style: {
282
283
  borderRadius: '50%',
283
284
  border: 'none',
284
285
  } })))))))));
@@ -298,6 +299,26 @@ export class KritzelControls {
298
299
  static get assetsDirs() { return ["../assets"]; }
299
300
  static get properties() {
300
301
  return {
302
+ "visible": {
303
+ "type": "boolean",
304
+ "mutable": false,
305
+ "complexType": {
306
+ "original": "boolean",
307
+ "resolved": "boolean",
308
+ "references": {}
309
+ },
310
+ "required": false,
311
+ "optional": false,
312
+ "docs": {
313
+ "tags": [],
314
+ "text": ""
315
+ },
316
+ "getter": false,
317
+ "setter": false,
318
+ "reflect": false,
319
+ "attribute": "visible",
320
+ "defaultValue": "true"
321
+ },
301
322
  "controls": {
302
323
  "type": "unknown",
303
324
  "mutable": false,
@@ -4,6 +4,7 @@ export const DEFAULT_BRUSH_CONFIG = {
4
4
  type: 'pen',
5
5
  color: DEFAULT_COLOR_PALETTE[0],
6
6
  size: 16,
7
+ opacity: 1,
7
8
  palettes: {
8
9
  pen: [...DEFAULT_COLOR_PALETTE],
9
10
  },
@@ -3,6 +3,7 @@ import { DEFAULT_STROKE_SIZES } from "../constants/stroke-size.constants";
3
3
  export const DEFAULT_LINE_TOOL_CONFIG = {
4
4
  color: DEFAULT_COLOR_PALETTE[0],
5
5
  size: 4,
6
+ opacity: 1,
6
7
  palette: [...DEFAULT_COLOR_PALETTE],
7
8
  sizes: [...DEFAULT_STROKE_SIZES],
8
9
  arrows: {
@@ -6,6 +6,7 @@ export const DEFAULT_SHAPE_CONFIG = {
6
6
  fillColor: { light: 'transparent', dark: 'transparent' },
7
7
  strokeColor: DEFAULT_COLOR_PALETTE[0],
8
8
  strokeWidth: 4,
9
+ opacity: 1,
9
10
  fontColor: DEFAULT_COLOR_PALETTE[0],
10
11
  fontSize: 16,
11
12
  fontFamily: 'Arial',
@@ -3,6 +3,7 @@ import { DEFAULT_FONT_SIZES } from "../constants/stroke-size.constants";
3
3
  export const DEFAULT_TEXT_CONFIG = {
4
4
  color: DEFAULT_COLOR_PALETTE[0],
5
5
  size: 8,
6
+ opacity: 1,
6
7
  fontFamily: 'Arial',
7
8
  palette: [...DEFAULT_COLOR_PALETTE],
8
9
  sizes: [...DEFAULT_FONT_SIZES],
@@ -3,4 +3,4 @@
3
3
  * This file is auto-generated by the version bump scripts.
4
4
  * Do not modify manually.
5
5
  */
6
- export const KRITZEL_VERSION = '0.3.11';
6
+ export const KRITZEL_VERSION = '0.3.12';