kritzel-stencil 0.3.13 → 0.3.14

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 (40) hide show
  1. package/dist/cjs/index.cjs.js +1 -1
  2. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +151 -25
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/{schema.constants-CMFOYyBj.js → schema.constants-DJQTjcy7.js} +62 -0
  5. package/dist/cjs/stencil.cjs.js +1 -1
  6. package/dist/collection/classes/core/viewport.class.js +81 -0
  7. package/dist/collection/classes/objects/image.class.js +62 -0
  8. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +86 -18
  9. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +164 -17
  10. package/dist/collection/constants/version.js +1 -1
  11. package/dist/components/index.js +1 -1
  12. package/dist/components/kritzel-controls.js +1 -1
  13. package/dist/components/kritzel-editor.js +1 -1
  14. package/dist/components/kritzel-engine.js +1 -1
  15. package/dist/components/kritzel-settings.js +1 -1
  16. package/dist/components/kritzel-tool-config.js +1 -1
  17. package/dist/components/p-BTEV1WwT.js +1 -0
  18. package/dist/components/p-CLLbE_z8.js +9 -0
  19. package/dist/components/{p-B9hLySCl.js → p-CUPYGT8c.js} +1 -1
  20. package/dist/components/{p-ijIqLY9g.js → p-DkaiWg1V.js} +1 -1
  21. package/dist/components/{p-CVzH1Oil.js → p-J9_SwObO.js} +1 -1
  22. package/dist/esm/index.js +2 -2
  23. package/dist/esm/kritzel-active-users_42.entry.js +151 -25
  24. package/dist/esm/loader.js +1 -1
  25. package/dist/esm/{schema.constants-NrtFvKER.js → schema.constants-DiCnmIYK.js} +62 -0
  26. package/dist/esm/stencil.js +1 -1
  27. package/dist/stencil/index.esm.js +1 -1
  28. package/dist/stencil/{p-NrtFvKER.js → p-DiCnmIYK.js} +1 -1
  29. package/dist/stencil/p-ea76b21f.entry.js +9 -0
  30. package/dist/stencil/stencil.esm.js +1 -1
  31. package/dist/types/classes/core/viewport.class.d.ts +30 -0
  32. package/dist/types/classes/objects/image.class.d.ts +15 -0
  33. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +11 -3
  34. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +33 -5
  35. package/dist/types/components.d.ts +28 -6
  36. package/dist/types/constants/version.d.ts +1 -1
  37. package/package.json +1 -1
  38. package/dist/components/p-C-aFOO5p.js +0 -1
  39. package/dist/components/p-DplAQ6jk.js +0 -9
  40. package/dist/stencil/p-9adee165.entry.js +0 -9
@@ -1 +1 @@
1
- import{p as e,H as t,c as s,h as i,d as o,t as n}from"./p-B43upypT.js";import{a,C as l}from"./p-CW-VyJgK.js";import{d as r}from"./p-CHrSFOSI.js";import{d as c}from"./p-Df3BwVGy.js";import{d as h}from"./p-DbB730vO.js";import{d}from"./p-D-sRVAbQ.js";import{d as g}from"./p-B5xxfwKF.js";import{d as p}from"./p-x6doYeiI.js";const u=-1/0,m=1/0,b=-1/0,f=1/0,v={showViewportInfo:!1,showObjectInfo:!1,showSyncProviderInfo:!0,showMigrationInfo:!0},w=[{id:"general",label:"General",icon:"settings"},{id:"viewport",label:"Viewport",icon:"viewport"},{id:"shortcuts",label:"Keyboard Shortcuts",icon:"command"},{id:"developer",label:"Developer Options",icon:"braces"},{id:"about",label:"About",icon:"info"}],y=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.settingsChange=s(this,"settingsChange")}get host(){return this}availableThemes=["light","dark"];shortcuts=[];settings;onSettingsPropChange(e){e&&this.applySettings(e)}isDialogOpen=!1;selectedCategoryId=w[0].id;scaleMin=1e-4;scaleMax=1e3;lockDrawingScale=!0;theme="light";viewportBoundaryLeft=u;viewportBoundaryRight=m;viewportBoundaryTop=b;viewportBoundaryBottom=f;debugInfo={...v};settingsChange;componentWillLoad(){this.settings&&this.applySettings(this.settings)}applySettings(e){"number"==typeof e.scaleMin&&(this.scaleMin=e.scaleMin),"number"==typeof e.scaleMax&&(this.scaleMax=e.scaleMax),"boolean"==typeof e.lockDrawingScale&&(this.lockDrawingScale=e.lockDrawingScale),"string"==typeof e.theme&&(this.theme=e.theme),"number"==typeof e.viewportBoundaryLeft&&(this.viewportBoundaryLeft=e.viewportBoundaryLeft),"number"==typeof e.viewportBoundaryRight&&(this.viewportBoundaryRight=e.viewportBoundaryRight),"number"==typeof e.viewportBoundaryTop&&(this.viewportBoundaryTop=e.viewportBoundaryTop),"number"==typeof e.viewportBoundaryBottom&&(this.viewportBoundaryBottom=e.viewportBoundaryBottom),e.debugInfo&&(this.debugInfo={...v,...e.debugInfo})}emitSettings(){this.settingsChange.emit({scaleMin:this.scaleMin,scaleMax:this.scaleMax,lockDrawingScale:this.lockDrawingScale,theme:this.theme,viewportBoundaryLeft:this.viewportBoundaryLeft,viewportBoundaryRight:this.viewportBoundaryRight,viewportBoundaryTop:this.viewportBoundaryTop,viewportBoundaryBottom:this.viewportBoundaryBottom,debugInfo:this.debugInfo})}handleScaleMinChange=e=>{this.scaleMin=e.detail,this.emitSettings()};handleScaleMaxChange=e=>{this.scaleMax=e.detail,this.emitSettings()};handleLockDrawingScaleChange=e=>{this.lockDrawingScale=e.detail,this.emitSettings()};handleThemeChange=e=>{this.theme=e.detail,this.emitSettings()};handleViewportBoundaryLeftChange=e=>{this.viewportBoundaryLeft=e.detail??u,this.emitSettings()};handleViewportBoundaryRightChange=e=>{this.viewportBoundaryRight=e.detail??m,this.emitSettings()};handleViewportBoundaryTopChange=e=>{this.viewportBoundaryTop=e.detail??b,this.emitSettings()};handleViewportBoundaryBottomChange=e=>{this.viewportBoundaryBottom=e.detail??f,this.emitSettings()};handleDebugInfoChange=e=>t=>{this.debugInfo={...this.debugInfo,[e]:t.detail},this.emitSettings()};async open(){this.isDialogOpen=!0}closeDialog=()=>{this.isDialogOpen=!1};handleCategorySelect=e=>{this.selectedCategoryId=e.detail.item.id};formatKeyCombo(e){const t=[];return e.ctrl&&t.push("Ctrl"),e.shift&&t.push("Shift"),t.push(this.formatKey(e.key)),t.join("+")}formatKey(e){return{Escape:"Esc",Delete:"Del"," ":"Space"}[e]??e.toUpperCase()}groupShortcutsByCategory(){const e=new Map;for(const t of this.shortcuts){const s=e.get(t.category)||[];s.push(t),e.set(t.category,s)}return e}renderCategoryContent(){switch(this.selectedCategoryId){case"general":return i("div",{class:"settings-content"},i("h3",null,"General Settings"),i("div",{class:"settings-group"},i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Theme"),i("p",{class:"settings-description"},"Select a registered color theme for the editor interface."),i("kritzel-dropdown",{options:this.availableThemes.map((e=>({value:e,label:e}))),value:this.theme,onValueChanged:this.handleThemeChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Lock Drawing Scale"),i("p",{class:"settings-description"},"When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level."),i("kritzel-slide-toggle",{checked:this.lockDrawingScale,label:"Lock Drawing Scale",onCheckedChange:this.handleLockDrawingScaleChange}))));case"viewport":return i("div",{class:"settings-content"},i("h3",null,"Viewport Settings"),i("div",{class:"settings-group"},i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Minimum Zoom Level"),i("p",{class:"settings-description"},"Sets the minimum zoom level. Lower values allow zooming out further to see more of the canvas."),i("kritzel-numeric-input",{value:this.scaleMin,min:1e-4,max:1,step:1e-4,onValueChange:this.handleScaleMinChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Maximum Zoom Level"),i("p",{class:"settings-description"},"Sets the maximum zoom level. Higher values allow zooming in closer for detailed work."),i("kritzel-numeric-input",{value:this.scaleMax,min:1,max:1e3,step:1,onValueChange:this.handleScaleMaxChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Viewport Boundary Left"),i("p",{class:"settings-description"},"Left boundary in world coordinates. Set to limit how far left the viewport can pan."),i("kritzel-numeric-input",{value:this.viewportBoundaryLeft,step:100,placeholder:"Infinite",onValueChange:this.handleViewportBoundaryLeftChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Viewport Boundary Right"),i("p",{class:"settings-description"},"Right boundary in world coordinates. Set to limit how far right the viewport can pan."),i("kritzel-numeric-input",{value:this.viewportBoundaryRight,step:100,placeholder:"Infinite",onValueChange:this.handleViewportBoundaryRightChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Viewport Boundary Top"),i("p",{class:"settings-description"},"Top boundary in world coordinates. Set to limit how far up the viewport can pan."),i("kritzel-numeric-input",{value:this.viewportBoundaryTop,step:100,placeholder:"Infinite",onValueChange:this.handleViewportBoundaryTopChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Viewport Boundary Bottom"),i("p",{class:"settings-description"},"Bottom boundary in world coordinates. Set to limit how far down the viewport can pan."),i("kritzel-numeric-input",{value:this.viewportBoundaryBottom,step:100,placeholder:"Infinite",onValueChange:this.handleViewportBoundaryBottomChange}))));case"shortcuts":return i("div",{class:"settings-content"},i("h3",null,"Keyboard Shortcuts"),i("div",{class:"shortcuts-list"},Array.from(this.groupShortcutsByCategory()).map((([e,t])=>i("div",{class:"shortcuts-category",key:e},i("h4",{class:"shortcuts-category-title"},e),i("div",{class:"shortcuts-group"},t.map((e=>i("div",{class:"shortcut-item",key:e.key+e.label},i("span",{class:"shortcut-label"},e.label),i("kbd",{class:"shortcut-key"},this.formatKeyCombo(e)))))))))));case"developer":return i("div",{class:"settings-content"},i("h3",null,"Developer Options"),i("div",{class:"settings-group"},i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Show Viewport Info"),i("p",{class:"settings-description"},"Display viewport debug information such as position, zoom level, and boundaries."),i("kritzel-slide-toggle",{checked:this.debugInfo.showViewportInfo,label:"Show Viewport Info",onCheckedChange:this.handleDebugInfoChange("showViewportInfo")})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Show Object Info"),i("p",{class:"settings-description"},"Display debug information about objects on the canvas."),i("kritzel-slide-toggle",{checked:this.debugInfo.showObjectInfo,label:"Show Object Info",onCheckedChange:this.handleDebugInfoChange("showObjectInfo")})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Show Sync Provider Info"),i("p",{class:"settings-description"},"Display debug information about the sync provider connection status."),i("kritzel-slide-toggle",{checked:this.debugInfo.showSyncProviderInfo,label:"Show Sync Provider Info",onCheckedChange:this.handleDebugInfoChange("showSyncProviderInfo")})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Show Migration Info"),i("p",{class:"settings-description"},"Display debug information about data migrations."),i("kritzel-slide-toggle",{checked:this.debugInfo.showMigrationInfo,label:"Show Migration Info",onCheckedChange:this.handleDebugInfoChange("showMigrationInfo")}))));case"about":return i("div",{class:"settings-content"},i("h3",null,"About"),i("p",null,"Kritzel - A drawing application"),i("p",{class:"version-info"},"Version ","0.3.13"),i("p",{class:"version-info"},"App-State Schema v",l),i("p",{class:"version-info"},"Workspace Schema v",a));default:return null}}render(){return i(o,{key:"46c6792ae9cdd932d3dc71526862c9281c0cefc1"},i("kritzel-dialog",{key:"1cd288cdf8b26bea378665c54bfc14577597fe49",isOpen:this.isDialogOpen,dialogTitle:"Settings",size:"large",contained:!0,onDialogClose:this.closeDialog},i("kritzel-master-detail",{key:"4d07e94ebb09035807356bab4bc7eaca57c36c6c",items:w,selectedItemId:this.selectedCategoryId,onItemSelect:this.handleCategorySelect},this.renderCategoryContent())))}static get watchers(){return{settings:[{onSettingsPropChange:0}]}}static get style(){return":host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}.shortcuts-list{display:flex;flex-direction:column;gap:24px}.shortcuts-category{display:flex;flex-direction:column;gap:8px}.shortcuts-category-title{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.shortcuts-group{display:flex;flex-direction:column;gap:4px}.shortcut-item{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-item-bg, rgba(0, 0, 0, 0.02))}.shortcut-label{font-size:14px;color:var(--kritzel-settings-content-text-color, #666666)}.shortcut-key{font-family:monospace;font-size:12px;padding:2px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-key-bg, #f0f0f0);color:var(--kritzel-settings-shortcut-key-color, #333333);border:1px solid var(--kritzel-settings-shortcut-key-border, #ddd)}"}},[513,"kritzel-settings",{availableThemes:[16],shortcuts:[16],settings:[16],isDialogOpen:[32],selectedCategoryId:[32],scaleMin:[32],scaleMax:[32],lockDrawingScale:[32],theme:[32],viewportBoundaryLeft:[32],viewportBoundaryRight:[32],viewportBoundaryTop:[32],viewportBoundaryBottom:[32],debugInfo:[32],open:[64]},void 0,{settings:[{onSettingsPropChange:0}]}]);function k(){"undefined"!=typeof customElements&&["kritzel-settings","kritzel-dialog","kritzel-dropdown","kritzel-icon","kritzel-master-detail","kritzel-numeric-input","kritzel-slide-toggle"].forEach((e=>{switch(e){case"kritzel-settings":customElements.get(n(e))||customElements.define(n(e),y);break;case"kritzel-dialog":customElements.get(n(e))||r();break;case"kritzel-dropdown":customElements.get(n(e))||c();break;case"kritzel-icon":customElements.get(n(e))||h();break;case"kritzel-master-detail":customElements.get(n(e))||d();break;case"kritzel-numeric-input":customElements.get(n(e))||g();break;case"kritzel-slide-toggle":customElements.get(n(e))||p()}}))}export{y as K,k as d}
1
+ import{p as e,H as t,c as s,h as i,d as o,t as n}from"./p-B43upypT.js";import{a,C as l}from"./p-CW-VyJgK.js";import{d as r}from"./p-CHrSFOSI.js";import{d as c}from"./p-Df3BwVGy.js";import{d as h}from"./p-DbB730vO.js";import{d}from"./p-D-sRVAbQ.js";import{d as g}from"./p-B5xxfwKF.js";import{d as p}from"./p-x6doYeiI.js";const u=-1/0,m=1/0,b=-1/0,f=1/0,v={showViewportInfo:!1,showObjectInfo:!1,showSyncProviderInfo:!0,showMigrationInfo:!0},w=[{id:"general",label:"General",icon:"settings"},{id:"viewport",label:"Viewport",icon:"viewport"},{id:"shortcuts",label:"Keyboard Shortcuts",icon:"command"},{id:"developer",label:"Developer Options",icon:"braces"},{id:"about",label:"About",icon:"info"}],y=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.settingsChange=s(this,"settingsChange")}get host(){return this}availableThemes=["light","dark"];shortcuts=[];settings;onSettingsPropChange(e){e&&this.applySettings(e)}isDialogOpen=!1;selectedCategoryId=w[0].id;scaleMin=1e-4;scaleMax=1e3;lockDrawingScale=!0;theme="light";viewportBoundaryLeft=u;viewportBoundaryRight=m;viewportBoundaryTop=b;viewportBoundaryBottom=f;debugInfo={...v};settingsChange;componentWillLoad(){this.settings&&this.applySettings(this.settings)}applySettings(e){"number"==typeof e.scaleMin&&(this.scaleMin=e.scaleMin),"number"==typeof e.scaleMax&&(this.scaleMax=e.scaleMax),"boolean"==typeof e.lockDrawingScale&&(this.lockDrawingScale=e.lockDrawingScale),"string"==typeof e.theme&&(this.theme=e.theme),"number"==typeof e.viewportBoundaryLeft&&(this.viewportBoundaryLeft=e.viewportBoundaryLeft),"number"==typeof e.viewportBoundaryRight&&(this.viewportBoundaryRight=e.viewportBoundaryRight),"number"==typeof e.viewportBoundaryTop&&(this.viewportBoundaryTop=e.viewportBoundaryTop),"number"==typeof e.viewportBoundaryBottom&&(this.viewportBoundaryBottom=e.viewportBoundaryBottom),e.debugInfo&&(this.debugInfo={...v,...e.debugInfo})}emitSettings(){this.settingsChange.emit({scaleMin:this.scaleMin,scaleMax:this.scaleMax,lockDrawingScale:this.lockDrawingScale,theme:this.theme,viewportBoundaryLeft:this.viewportBoundaryLeft,viewportBoundaryRight:this.viewportBoundaryRight,viewportBoundaryTop:this.viewportBoundaryTop,viewportBoundaryBottom:this.viewportBoundaryBottom,debugInfo:this.debugInfo})}handleScaleMinChange=e=>{this.scaleMin=e.detail,this.emitSettings()};handleScaleMaxChange=e=>{this.scaleMax=e.detail,this.emitSettings()};handleLockDrawingScaleChange=e=>{this.lockDrawingScale=e.detail,this.emitSettings()};handleThemeChange=e=>{this.theme=e.detail,this.emitSettings()};handleViewportBoundaryLeftChange=e=>{this.viewportBoundaryLeft=e.detail??u,this.emitSettings()};handleViewportBoundaryRightChange=e=>{this.viewportBoundaryRight=e.detail??m,this.emitSettings()};handleViewportBoundaryTopChange=e=>{this.viewportBoundaryTop=e.detail??b,this.emitSettings()};handleViewportBoundaryBottomChange=e=>{this.viewportBoundaryBottom=e.detail??f,this.emitSettings()};handleDebugInfoChange=e=>t=>{this.debugInfo={...this.debugInfo,[e]:t.detail},this.emitSettings()};async open(){this.isDialogOpen=!0}closeDialog=()=>{this.isDialogOpen=!1};handleCategorySelect=e=>{this.selectedCategoryId=e.detail.item.id};formatKeyCombo(e){const t=[];return e.ctrl&&t.push("Ctrl"),e.shift&&t.push("Shift"),t.push(this.formatKey(e.key)),t.join("+")}formatKey(e){return{Escape:"Esc",Delete:"Del"," ":"Space"}[e]??e.toUpperCase()}groupShortcutsByCategory(){const e=new Map;for(const t of this.shortcuts){const s=e.get(t.category)||[];s.push(t),e.set(t.category,s)}return e}renderCategoryContent(){switch(this.selectedCategoryId){case"general":return i("div",{class:"settings-content"},i("h3",null,"General Settings"),i("div",{class:"settings-group"},i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Theme"),i("p",{class:"settings-description"},"Select a registered color theme for the editor interface."),i("kritzel-dropdown",{options:this.availableThemes.map((e=>({value:e,label:e}))),value:this.theme,onValueChanged:this.handleThemeChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Lock Drawing Scale"),i("p",{class:"settings-description"},"When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level."),i("kritzel-slide-toggle",{checked:this.lockDrawingScale,label:"Lock Drawing Scale",onCheckedChange:this.handleLockDrawingScaleChange}))));case"viewport":return i("div",{class:"settings-content"},i("h3",null,"Viewport Settings"),i("div",{class:"settings-group"},i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Minimum Zoom Level"),i("p",{class:"settings-description"},"Sets the minimum zoom level. Lower values allow zooming out further to see more of the canvas."),i("kritzel-numeric-input",{value:this.scaleMin,min:1e-4,max:1,step:1e-4,onValueChange:this.handleScaleMinChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Maximum Zoom Level"),i("p",{class:"settings-description"},"Sets the maximum zoom level. Higher values allow zooming in closer for detailed work."),i("kritzel-numeric-input",{value:this.scaleMax,min:1,max:1e3,step:1,onValueChange:this.handleScaleMaxChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Viewport Boundary Left"),i("p",{class:"settings-description"},"Left boundary in world coordinates. Set to limit how far left the viewport can pan."),i("kritzel-numeric-input",{value:this.viewportBoundaryLeft,step:100,placeholder:"Infinite",onValueChange:this.handleViewportBoundaryLeftChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Viewport Boundary Right"),i("p",{class:"settings-description"},"Right boundary in world coordinates. Set to limit how far right the viewport can pan."),i("kritzel-numeric-input",{value:this.viewportBoundaryRight,step:100,placeholder:"Infinite",onValueChange:this.handleViewportBoundaryRightChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Viewport Boundary Top"),i("p",{class:"settings-description"},"Top boundary in world coordinates. Set to limit how far up the viewport can pan."),i("kritzel-numeric-input",{value:this.viewportBoundaryTop,step:100,placeholder:"Infinite",onValueChange:this.handleViewportBoundaryTopChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Viewport Boundary Bottom"),i("p",{class:"settings-description"},"Bottom boundary in world coordinates. Set to limit how far down the viewport can pan."),i("kritzel-numeric-input",{value:this.viewportBoundaryBottom,step:100,placeholder:"Infinite",onValueChange:this.handleViewportBoundaryBottomChange}))));case"shortcuts":return i("div",{class:"settings-content"},i("h3",null,"Keyboard Shortcuts"),i("div",{class:"shortcuts-list"},Array.from(this.groupShortcutsByCategory()).map((([e,t])=>i("div",{class:"shortcuts-category",key:e},i("h4",{class:"shortcuts-category-title"},e),i("div",{class:"shortcuts-group"},t.map((e=>i("div",{class:"shortcut-item",key:e.key+e.label},i("span",{class:"shortcut-label"},e.label),i("kbd",{class:"shortcut-key"},this.formatKeyCombo(e)))))))))));case"developer":return i("div",{class:"settings-content"},i("h3",null,"Developer Options"),i("div",{class:"settings-group"},i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Show Viewport Info"),i("p",{class:"settings-description"},"Display viewport debug information such as position, zoom level, and boundaries."),i("kritzel-slide-toggle",{checked:this.debugInfo.showViewportInfo,label:"Show Viewport Info",onCheckedChange:this.handleDebugInfoChange("showViewportInfo")})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Show Object Info"),i("p",{class:"settings-description"},"Display debug information about objects on the canvas."),i("kritzel-slide-toggle",{checked:this.debugInfo.showObjectInfo,label:"Show Object Info",onCheckedChange:this.handleDebugInfoChange("showObjectInfo")})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Show Sync Provider Info"),i("p",{class:"settings-description"},"Display debug information about the sync provider connection status."),i("kritzel-slide-toggle",{checked:this.debugInfo.showSyncProviderInfo,label:"Show Sync Provider Info",onCheckedChange:this.handleDebugInfoChange("showSyncProviderInfo")})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Show Migration Info"),i("p",{class:"settings-description"},"Display debug information about data migrations."),i("kritzel-slide-toggle",{checked:this.debugInfo.showMigrationInfo,label:"Show Migration Info",onCheckedChange:this.handleDebugInfoChange("showMigrationInfo")}))));case"about":return i("div",{class:"settings-content"},i("h3",null,"About"),i("p",null,"Kritzel - A drawing application"),i("p",{class:"version-info"},"Version ","0.3.14"),i("p",{class:"version-info"},"App-State Schema v",l),i("p",{class:"version-info"},"Workspace Schema v",a));default:return null}}render(){return i(o,{key:"46c6792ae9cdd932d3dc71526862c9281c0cefc1"},i("kritzel-dialog",{key:"1cd288cdf8b26bea378665c54bfc14577597fe49",isOpen:this.isDialogOpen,dialogTitle:"Settings",size:"large",contained:!0,onDialogClose:this.closeDialog},i("kritzel-master-detail",{key:"4d07e94ebb09035807356bab4bc7eaca57c36c6c",items:w,selectedItemId:this.selectedCategoryId,onItemSelect:this.handleCategorySelect},this.renderCategoryContent())))}static get watchers(){return{settings:[{onSettingsPropChange:0}]}}static get style(){return":host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}.shortcuts-list{display:flex;flex-direction:column;gap:24px}.shortcuts-category{display:flex;flex-direction:column;gap:8px}.shortcuts-category-title{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.shortcuts-group{display:flex;flex-direction:column;gap:4px}.shortcut-item{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-item-bg, rgba(0, 0, 0, 0.02))}.shortcut-label{font-size:14px;color:var(--kritzel-settings-content-text-color, #666666)}.shortcut-key{font-family:monospace;font-size:12px;padding:2px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-key-bg, #f0f0f0);color:var(--kritzel-settings-shortcut-key-color, #333333);border:1px solid var(--kritzel-settings-shortcut-key-border, #ddd)}"}},[513,"kritzel-settings",{availableThemes:[16],shortcuts:[16],settings:[16],isDialogOpen:[32],selectedCategoryId:[32],scaleMin:[32],scaleMax:[32],lockDrawingScale:[32],theme:[32],viewportBoundaryLeft:[32],viewportBoundaryRight:[32],viewportBoundaryTop:[32],viewportBoundaryBottom:[32],debugInfo:[32],open:[64]},void 0,{settings:[{onSettingsPropChange:0}]}]);function k(){"undefined"!=typeof customElements&&["kritzel-settings","kritzel-dialog","kritzel-dropdown","kritzel-icon","kritzel-master-detail","kritzel-numeric-input","kritzel-slide-toggle"].forEach((e=>{switch(e){case"kritzel-settings":customElements.get(n(e))||customElements.define(n(e),y);break;case"kritzel-dialog":customElements.get(n(e))||r();break;case"kritzel-dropdown":customElements.get(n(e))||c();break;case"kritzel-icon":customElements.get(n(e))||h();break;case"kritzel-master-detail":customElements.get(n(e))||d();break;case"kritzel-numeric-input":customElements.get(n(e))||g();break;case"kritzel-slide-toggle":customElements.get(n(e))||p()}}))}export{y as K,k as d}
@@ -1 +1 @@
1
- import{p as t,H as o,c as e,h as r,d as i,t as l}from"./p-B43upypT.js";import{e as n,d as s}from"./p-B9hLySCl.js";import{K as a}from"./p-jGOpkGDl.js";import{K as c,d}from"./p-C-aFOO5p.js";import{a as h}from"./p-2xYAGd0I.js";import{d as p}from"./p-skWUIStn.js";import{d as k}from"./p-BFoK4W--.js";import{d as b}from"./p-Df3BwVGy.js";import{d as u}from"./p-CmuNn1Tc.js";import{d as f}from"./p-JhOYwUOj.js";import{d as g}from"./p-FK7b3BGt.js";import{d as z}from"./p-DbB730vO.js";import{d as m}from"./p-CXpv9Rxe.js";import{d as v}from"./p-DEy7zJCe.js";import{d as y}from"./p-BFYtCsZu.js";import{d as x}from"./p-B2Os1ya_.js";import{d as w}from"./p-dcAernE1.js";import{d as C}from"./p-CcyIAi9S.js";const j=t(class extends o{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.isControlsReady=e(this,"isControlsReady")}get host(){return this}visible=!0;controls=[];activeControl=null;isUtilityPanelVisible=!0;undoState=null;theme="light";isControlsReady;firstConfig=null;isTouchDevice=a.isTouchDevice();selectedSubOptions=new Map;canScrollLeft=!1;canScrollRight=!1;needsScrolling=!1;displayValues=null;internalControls=[];handleActiveToolChangeBound=this.handleActiveToolChange.bind(this);handleSelectionChangeBound=this.handleSelectionChange.bind(this);handleKeyDown(t){"Escape"===t.key&&(t.preventDefault(),this.closeTooltip(),this.kritzelEngine?.enable())}async handleActiveToolChange(t){this.activeControl=this.internalControls.find((o=>o.tool===t.detail))||null,this.activeControl?.tool&&this.updateDisplayValues(this.activeControl.tool),this.closeTooltip()}handleSelectionChange(){this.activeControl?.tool instanceof n&&this.updateDisplayValues(this.activeControl.tool)}async onControlsChange(){this.kritzelEngine&&await this.initializeTools()}onThemeChange(){this.activeControl?.tool&&this.updateDisplayValues(this.activeControl.tool)}async closeTooltip(){document.dispatchEvent(new CustomEvent("kritzelTooltipCloseAll"))}kritzelEngine=null;toolsScrollRef=null;configTriggerRef=null;get activeToolAsTextTool(){return this.activeControl?.tool}get activeToolAsBrushTool(){return this.activeControl?.tool}get activeToolAsLineTool(){return this.activeControl?.tool}get activeToolAsShapeTool(){return this.activeControl?.tool}handleDisplayValuesChange=t=>{const o=t.detail;this.displayValues&&this.displayValues.color===o.color&&this.displayValues.size===o.size&&this.displayValues.fontFamily===o.fontFamily||(this.displayValues=o)};updateDisplayValues(t){const o=c.getToolConfig(t);if(!o)return void(this.displayValues=null);const e=t[o.sizeProperty],r={color:h.applyOpacity(t[o.colorProperty],t[o.opacityProperty]??1,this.theme),size:e};t instanceof s&&(r.fontFamily=t.fontFamily),this.displayValues&&this.displayValues.color===r.color&&this.displayValues.size===r.size&&this.displayValues.fontFamily===r.fontFamily||(this.displayValues=r)}async componentWillLoad(){await this.initializeEngine(),await this.initializeTools(),this.isControlsReady.emit()}componentDidLoad(){this.updateScrollIndicators()}componentDidRender(){this.updateScrollIndicators()}disconnectedCallback(){this.kritzelEngine&&(this.kritzelEngine.removeEventListener("activeToolChange",this.handleActiveToolChangeBound),this.kritzelEngine.removeEventListener("objectsSelectionChange",this.handleSelectionChangeBound))}updateScrollIndicators(){if(!this.toolsScrollRef)return;const{scrollLeft:t,scrollWidth:o,clientWidth:e}=this.toolsScrollRef,r=t>2,i=t+e<o-2,l=o>e;this.canScrollLeft!==r&&(this.canScrollLeft=r),this.canScrollRight!==i&&(this.canScrollRight=i),this.needsScrolling!==l&&(this.needsScrolling=l)}handleToolsScroll=()=>{this.updateScrollIndicators()};async initializeEngine(){if(await customElements.whenDefined("kritzel-engine"),this.kritzelEngine=this.host.parentElement.querySelector("kritzel-engine"),!this.kritzelEngine)throw new Error("kritzel-engine not found in parent element.");this.kritzelEngine.addEventListener("activeToolChange",this.handleActiveToolChangeBound),this.kritzelEngine.addEventListener("objectsSelectionChange",this.handleSelectionChangeBound)}async initializeTools(){let t=!1;const o=this.controls.map((t=>({...t})));for(const e of o){if("tool"===e.type&&e.tool){let t=e.tool;"function"!=typeof t&&(t=t.constructor);const o=await this.kritzelEngine.registerTool(e.name,t,e.config);o&&(e.tool=o)}"tool"===e.type&&e.isDefault&&e.tool&&(await this.kritzelEngine.changeActiveTool(e.tool),this.activeControl=e,this.updateDisplayValues(e.tool),t=!0),"config"===e.type&&(null===this.firstConfig?this.firstConfig=e:console.warn("Only one config control is allowed. The first one will be used."))}if(this.internalControls=o,!t){const t=this.internalControls.find((t=>"tool"===t.type&&t.tool));t&&(await this.kritzelEngine.changeActiveTool(t.tool),this.activeControl=t,this.updateDisplayValues(t.tool))}}async handleControlClick(t){this.activeControl=t,"tool"===this.activeControl.type&&(this.updateDisplayValues(this.activeControl.tool),await this.kritzelEngine.changeActiveTool(this.activeControl.tool))}async handleToolChange(t){this.activeControl={...this.activeControl,tool:t.detail},await this.kritzelEngine.changeActiveTool(this.activeControl.tool)}getSelectedSubOption(t){if(t.subOptions?.length)return this.selectedSubOptions.get(t.name)||t.subOptions[0]}async selectSubOption(t,o){const e=new Map(this.selectedSubOptions);e.set(t.name,o),this.selectedSubOptions=e,t.tool&&"function"!=typeof t.tool&&(t.tool[o.toolProperty]=o.value),this.closeTooltip(),await this.handleControlClick(t)}render(){const t=null!==(this.activeControl?.tool?c.getToolConfig(this.activeControl.tool):null),o=this.internalControls.filter((t=>"tool"===t.type||"separator"===t.type)),e=this.internalControls.find((t=>"config"===t.type&&t.name===this.firstConfig?.name));return r(i,{key:"0f40a136a6a9556080d922d346318045794421a8",style:{display:this.visible?"":"none"},class:{mobile:this.isTouchDevice}},this.isUtilityPanelVisible&&r("kritzel-utility-panel",{key:"d543e7575cb30e54d9362eddf7c7221fb8cce5f5",style:{position:"absolute",bottom:"56px",left:"12px"},undoState:this.undoState,onUndo:()=>this.kritzelEngine?.undo(),onRedo:()=>this.kritzelEngine?.redo(),onDelete:()=>this.kritzelEngine?.delete()}),r("div",{key:"1083380152e9d1b51c35da335533c20ca2ca8fcc",class:"kritzel-controls"},r("div",{key:"11ef0fb76c30ffda0e30f01d43229ca2142a5854",class:{"scroll-indicator-left":!0,visible:this.canScrollLeft}}),r("div",{key:"269924a8859aece37ff31202307d4feaecbbde86",class:"kritzel-tools-scroll",ref:t=>this.toolsScrollRef=t,onScroll:this.handleToolsScroll},o.map((t=>{if(t.subOptions?.length){const o=this.getSelectedSubOption(t),e=this.activeControl?.name===t.name;return r("div",{class:{"kritzel-control-split":!0,selected:e},key:t.name,"data-testid":`tool-${t.name}`,ref:o=>{o&&(t._anchorRef=o)}},r("button",{class:"kritzel-control-main",onClick:()=>this.handleControlClick(t),"aria-label":o?.label,"data-testid":`tool-${t.name}-main`},r("kritzel-icon",{name:o?.icon||t.icon})),r("button",{class:{"kritzel-control-dropdown":!0,visible:e},ref:o=>{o&&(t._triggerRef=o)},"aria-label":`Select ${t.name} options`,"data-testid":`tool-${t.name}-dropdown`,tabIndex:e?0:-1},r("kritzel-icon",{name:"chevron-down",size:12})),r("kritzel-tooltip",{anchorElement:t._anchorRef,triggerElement:t._triggerRef},r("div",{class:"kritzel-submenu-content"},t.subOptions.map((e=>r("button",{class:{"kritzel-submenu-item":!0,active:e.id===o?.id},key:e.id,"data-testid":`suboption-${e.id}`,onClick:()=>this.selectSubOption(t,e)},r("kritzel-icon",{name:e.icon,size:20}),r("span",null,e.label)))))))}return"separator"===t.type?r("div",{class:"kritzel-control-separator",key:t.name}):r("button",{class:{"kritzel-control":!0,selected:this.activeControl?.name===t?.name},key:t.name,"data-testid":`tool-${t.name}`,onClick:()=>this.handleControlClick?.(t),"aria-label":t.name.charAt(0).toUpperCase()+t.name.slice(1)},r("kritzel-icon",{name:t.icon}))}))),r("div",{key:"8b97a5bba3ac4992482e8f433d7ba6197918a914",class:{"scroll-indicator-right":!0,visible:this.canScrollRight&&!(e&&this.activeControl&&t)}}),e&&this.activeControl&&r("div",{class:{"kritzel-config-container":!0,visible:t},key:e.name},r("div",{key:"d9adef8c2acc8d9b9d745174050ce78960b89b58",class:{"config-gradient-left":!0,visible:this.needsScrolling}}),r("kritzel-tooltip",{key:"7605bbd2b6335c89c57aa68952293f26efad6b4b",anchorElement:this.host.shadowRoot?.querySelector(".kritzel-config-container"),triggerElement:this.configTriggerRef},r("kritzel-tool-config",{key:"27b0f41442215e78b692fa44bb665444a4993b89",tool:this.activeControl.tool,theme:this.theme,engine:this.kritzelEngine,onToolChange:t=>this.handleToolChange?.(t),onDisplayValuesChange:this.handleDisplayValuesChange,style:{width:"100%",height:"100%"}})),r("div",{key:"1fb5979b1c531593acf5086861b22b7d78d03e8d",tabIndex:t?0:-1,class:"kritzel-config","data-testid":"tool-config",ref:t=>{t&&(this.configTriggerRef=t)},onKeyDown:t=>{"Enter"===t.key&&t.target.click()},style:{cursor:"pointer"}},this.displayValues&&r("div",{key:"3713ef344630f6b4d88df2e83992018859ddb18c",class:"color-container"},r("kritzel-color",{key:"c2679f68efae77c6daeb98be9e03d5320d51a73a",value:this.displayValues.color,theme:this.theme,size:18,style:{borderRadius:"50%",border:"none"}}))))))}static get assetsDirs(){return["../assets"]}static get watchers(){return{controls:[{onControlsChange:0}],theme:[{onThemeChange:0}]}}static get style(){return":host{display:flex;flex-direction:column;user-select:none;max-width:100%;z-index:1}:host(.mobile){--kritzel-controls-control-hover-background-color:transparent;--kritzel-controls-control-active-background-color:transparent}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap, 8px);height:100%;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 16px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #ebebeb);z-index:1;position:relative;max-width:100%;overflow:hidden}.kritzel-tools-scroll{display:flex;flex-direction:row;align-items:center;gap:var(--kritzel-controls-gap, 8px);overflow-x:auto;overflow-y:hidden;flex:1 1 auto;min-width:0;padding:4px;margin:-4px;scrollbar-width:none;-ms-overflow-style:none}.kritzel-tools-scroll::-webkit-scrollbar{display:none}.scroll-indicator-left,.scroll-indicator-right{position:absolute;top:0;bottom:0;width:32px;pointer-events:none;opacity:0;transition:opacity 0.2s ease-out;z-index:1}.scroll-indicator-left{left:0;background:linear-gradient(to right, var(--kritzel-controls-background-color, #ffffff), transparent);border-radius:var(--kritzel-controls-border-radius, 16px) 0 0 var(--kritzel-controls-border-radius, 16px)}.scroll-indicator-right{right:0;background:linear-gradient(to left, var(--kritzel-controls-background-color, #ffffff), transparent);border-radius:0 var(--kritzel-controls-border-radius, 16px) var(--kritzel-controls-border-radius, 16px) 0}.scroll-indicator-left.visible,.scroll-indicator-right.visible{opacity:1}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color, #000000);border-radius:var(--kritzel-controls-control-border-radius, 12px);padding:var(--kritzel-controls-control-padding, 8px);border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:focus,.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control.selected:focus{background-color:var(--kritzel-controls-control-selected-background-color, #007bffe3) !important}.kritzel-control-separator{width:1px;height:24px;background-color:var(--kritzel-controls-separator-color, #ebebeb);margin:0 4px}.kritzel-control-split{position:relative;display:flex;align-items:center;border-radius:var(--kritzel-controls-control-border-radius, 12px);color:var(--kritzel-controls-control-color, #000000)}.kritzel-control-split .kritzel-control-main{display:flex;justify-content:center;align-items:center;padding:var(--kritzel-controls-control-padding, 8px);border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;border-radius:var(--kritzel-controls-control-border-radius, 12px);color:inherit}.kritzel-control-split.selected .kritzel-control-main{border-radius:var(--kritzel-controls-control-border-radius, 12px) 0 0 var(--kritzel-controls-control-border-radius, 12px)}.kritzel-control-split .kritzel-control-dropdown{display:flex;justify-content:center;align-items:center;align-self:stretch;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;border-radius:0 var(--kritzel-controls-control-border-radius, 12px) var(--kritzel-controls-control-border-radius, 12px) 0;color:inherit;width:0;padding:0;opacity:0;overflow:hidden;pointer-events:none;transition:width 0.15s ease-out, padding 0.15s ease-out, opacity 0.15s ease-out}.kritzel-control-split .kritzel-control-dropdown.visible{width:auto;padding:0 6px;opacity:1;pointer-events:auto}.kritzel-control-split .kritzel-control-main:focus,.kritzel-control-split .kritzel-control-main:hover,.kritzel-control-split .kritzel-control-dropdown:focus,.kritzel-control-split .kritzel-control-dropdown:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control-split .kritzel-control-main:active,.kritzel-control-split .kritzel-control-dropdown:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control-split.selected{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control-split.selected .kritzel-control-main:hover,.kritzel-control-split.selected .kritzel-control-dropdown:hover{background-color:rgba(255, 255, 255, 0.15)}.kritzel-submenu-content{display:flex;flex-direction:column;gap:var(--kritzel-submenu-gap, 4px);min-width:140px}.kritzel-submenu-item{display:flex;align-items:center;gap:10px;padding:10px 12px;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);border-radius:8px;color:var(--kritzel-controls-control-color, #000000);font-size:14px;text-align:left;white-space:nowrap;-webkit-tap-highlight-color:transparent}.kritzel-submenu-item:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-submenu-item.active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF);color:var(--kritzel-controls-control-selected-color, #ffffff)}.kritzel-submenu-item.active:hover{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF)}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent;flex-shrink:0;width:0;opacity:0;overflow:hidden;pointer-events:none;margin-left:calc(-1 * var(--kritzel-controls-gap, 8px));transition:width 0.2s ease-out, opacity 0.2s ease-out, margin-left 0.2s ease-out}.kritzel-config-container.visible{width:40px;opacity:1;pointer-events:auto;margin-left:0;overflow:visible}.config-gradient-left{position:absolute;top:0;bottom:0;left:-32px;width:32px;background:linear-gradient(to right, transparent, var(--kritzel-controls-background-color, #ffffff));pointer-events:none;z-index:1;opacity:0;transition:opacity 0.2s ease-out}.config-gradient-left.visible{opacity:1}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:var(--kritzel-global-pointer-cursor, pointer);border-radius:50%}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.font-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{z-index:10001}"}},[513,"kritzel-controls",{visible:[4],controls:[16],activeControl:[1040],isUtilityPanelVisible:[4,"is-utility-panel-visible"],undoState:[16],theme:[1],firstConfig:[32],isTouchDevice:[32],selectedSubOptions:[32],canScrollLeft:[32],canScrollRight:[32],needsScrolling:[32],displayValues:[32],internalControls:[32],closeTooltip:[64]},[[8,"keydown","handleKeyDown"]],{controls:[{onControlsChange:0}],theme:[{onThemeChange:0}]}]);function E(){"undefined"!=typeof customElements&&["kritzel-controls","kritzel-color","kritzel-color-palette","kritzel-dropdown","kritzel-font","kritzel-font-family","kritzel-font-size","kritzel-icon","kritzel-line-endings","kritzel-opacity-slider","kritzel-shape-fill","kritzel-stroke-size","kritzel-tool-config","kritzel-tooltip","kritzel-utility-panel"].forEach((t=>{switch(t){case"kritzel-controls":customElements.get(l(t))||customElements.define(l(t),j);break;case"kritzel-color":customElements.get(l(t))||p();break;case"kritzel-color-palette":customElements.get(l(t))||k();break;case"kritzel-dropdown":customElements.get(l(t))||b();break;case"kritzel-font":customElements.get(l(t))||u();break;case"kritzel-font-family":customElements.get(l(t))||f();break;case"kritzel-font-size":customElements.get(l(t))||g();break;case"kritzel-icon":customElements.get(l(t))||z();break;case"kritzel-line-endings":customElements.get(l(t))||m();break;case"kritzel-opacity-slider":customElements.get(l(t))||v();break;case"kritzel-shape-fill":customElements.get(l(t))||y();break;case"kritzel-stroke-size":customElements.get(l(t))||x();break;case"kritzel-tool-config":customElements.get(l(t))||d();break;case"kritzel-tooltip":customElements.get(l(t))||w();break;case"kritzel-utility-panel":customElements.get(l(t))||C()}}))}export{j as K,E as d}
1
+ import{p as t,H as o,c as e,h as r,d as i,t as l}from"./p-B43upypT.js";import{e as n,d as s}from"./p-CUPYGT8c.js";import{K as a}from"./p-jGOpkGDl.js";import{K as c,d}from"./p-BTEV1WwT.js";import{a as h}from"./p-2xYAGd0I.js";import{d as p}from"./p-skWUIStn.js";import{d as k}from"./p-BFoK4W--.js";import{d as b}from"./p-Df3BwVGy.js";import{d as u}from"./p-CmuNn1Tc.js";import{d as f}from"./p-JhOYwUOj.js";import{d as g}from"./p-FK7b3BGt.js";import{d as z}from"./p-DbB730vO.js";import{d as m}from"./p-CXpv9Rxe.js";import{d as v}from"./p-DEy7zJCe.js";import{d as y}from"./p-BFYtCsZu.js";import{d as x}from"./p-B2Os1ya_.js";import{d as w}from"./p-dcAernE1.js";import{d as C}from"./p-CcyIAi9S.js";const T=t(class extends o{constructor(t){super(),!1!==t&&this.__registerHost(),this.__attachShadow(),this.isControlsReady=e(this,"isControlsReady")}get host(){return this}visible=!0;controls=[];activeControl=null;isUtilityPanelVisible=!0;undoState=null;theme="light";isControlsReady;firstConfig=null;isTouchDevice=a.isTouchDevice();selectedSubOptions=new Map;canScrollLeft=!1;canScrollRight=!1;needsScrolling=!1;displayValues=null;internalControls=[];handleActiveToolChangeBound=this.handleActiveToolChange.bind(this);handleSelectionChangeBound=this.handleSelectionChange.bind(this);handleKeyDown(t){"Escape"===t.key&&(t.preventDefault(),this.closeTooltip(),this.kritzelEngine?.enable())}async handleActiveToolChange(t){this.activeControl=this.internalControls.find((o=>o.tool===t.detail))||null,this.activeControl?.tool&&this.updateDisplayValues(this.activeControl.tool),this.closeTooltip()}handleSelectionChange(){this.activeControl?.tool instanceof n&&this.updateDisplayValues(this.activeControl.tool)}async onControlsChange(){this.kritzelEngine&&await this.initializeTools()}onThemeChange(){this.activeControl?.tool&&this.updateDisplayValues(this.activeControl.tool)}async closeTooltip(){document.dispatchEvent(new CustomEvent("kritzelTooltipCloseAll"))}kritzelEngine=null;toolsScrollRef=null;configTriggerRef=null;get activeToolAsTextTool(){return this.activeControl?.tool}get activeToolAsBrushTool(){return this.activeControl?.tool}get activeToolAsLineTool(){return this.activeControl?.tool}get activeToolAsShapeTool(){return this.activeControl?.tool}handleDisplayValuesChange=t=>{const o=t.detail;this.displayValues&&this.displayValues.color===o.color&&this.displayValues.size===o.size&&this.displayValues.fontFamily===o.fontFamily||(this.displayValues=o)};updateDisplayValues(t){const o=c.getToolConfig(t);if(!o)return void(this.displayValues=null);const e=t[o.sizeProperty],r={color:h.applyOpacity(t[o.colorProperty],t[o.opacityProperty]??1,this.theme),size:e};t instanceof s&&(r.fontFamily=t.fontFamily),this.displayValues&&this.displayValues.color===r.color&&this.displayValues.size===r.size&&this.displayValues.fontFamily===r.fontFamily||(this.displayValues=r)}async componentWillLoad(){await this.initializeEngine(),await this.initializeTools(),this.isControlsReady.emit()}componentDidLoad(){this.updateScrollIndicators()}componentDidRender(){this.updateScrollIndicators()}disconnectedCallback(){this.kritzelEngine&&(this.kritzelEngine.removeEventListener("activeToolChange",this.handleActiveToolChangeBound),this.kritzelEngine.removeEventListener("objectsSelectionChange",this.handleSelectionChangeBound))}updateScrollIndicators(){if(!this.toolsScrollRef)return;const{scrollLeft:t,scrollWidth:o,clientWidth:e}=this.toolsScrollRef,r=t>2,i=t+e<o-2,l=o>e;this.canScrollLeft!==r&&(this.canScrollLeft=r),this.canScrollRight!==i&&(this.canScrollRight=i),this.needsScrolling!==l&&(this.needsScrolling=l)}handleToolsScroll=()=>{this.updateScrollIndicators()};async initializeEngine(){if(await customElements.whenDefined("kritzel-engine"),this.kritzelEngine=this.host.parentElement.querySelector("kritzel-engine"),!this.kritzelEngine)throw new Error("kritzel-engine not found in parent element.");this.kritzelEngine.addEventListener("activeToolChange",this.handleActiveToolChangeBound),this.kritzelEngine.addEventListener("objectsSelectionChange",this.handleSelectionChangeBound)}async initializeTools(){let t=!1;const o=this.controls.map((t=>({...t})));for(const e of o){if("tool"===e.type&&e.tool){let t=e.tool;"function"!=typeof t&&(t=t.constructor);const o=await this.kritzelEngine.registerTool(e.name,t,e.config);o&&(e.tool=o)}"tool"===e.type&&e.isDefault&&e.tool&&(await this.kritzelEngine.changeActiveTool(e.tool),this.activeControl=e,this.updateDisplayValues(e.tool),t=!0),"config"===e.type&&(null===this.firstConfig?this.firstConfig=e:console.warn("Only one config control is allowed. The first one will be used."))}if(this.internalControls=o,!t){const t=this.internalControls.find((t=>"tool"===t.type&&t.tool));t&&(await this.kritzelEngine.changeActiveTool(t.tool),this.activeControl=t,this.updateDisplayValues(t.tool))}}async handleControlClick(t){this.activeControl=t,"tool"===this.activeControl.type&&(this.updateDisplayValues(this.activeControl.tool),await this.kritzelEngine.changeActiveTool(this.activeControl.tool))}async handleToolChange(t){this.activeControl={...this.activeControl,tool:t.detail},await this.kritzelEngine.changeActiveTool(this.activeControl.tool)}getSelectedSubOption(t){if(t.subOptions?.length)return this.selectedSubOptions.get(t.name)||t.subOptions[0]}async selectSubOption(t,o){const e=new Map(this.selectedSubOptions);e.set(t.name,o),this.selectedSubOptions=e,t.tool&&"function"!=typeof t.tool&&(t.tool[o.toolProperty]=o.value),this.closeTooltip(),await this.handleControlClick(t)}render(){const t=null!==(this.activeControl?.tool?c.getToolConfig(this.activeControl.tool):null),o=this.internalControls.filter((t=>"tool"===t.type||"separator"===t.type)),e=this.internalControls.find((t=>"config"===t.type&&t.name===this.firstConfig?.name));return r(i,{key:"0f40a136a6a9556080d922d346318045794421a8",style:{display:this.visible?"":"none"},class:{mobile:this.isTouchDevice}},this.isUtilityPanelVisible&&r("kritzel-utility-panel",{key:"d543e7575cb30e54d9362eddf7c7221fb8cce5f5",style:{position:"absolute",bottom:"56px",left:"12px"},undoState:this.undoState,onUndo:()=>this.kritzelEngine?.undo(),onRedo:()=>this.kritzelEngine?.redo(),onDelete:()=>this.kritzelEngine?.delete()}),r("div",{key:"1083380152e9d1b51c35da335533c20ca2ca8fcc",class:"kritzel-controls"},r("div",{key:"11ef0fb76c30ffda0e30f01d43229ca2142a5854",class:{"scroll-indicator-left":!0,visible:this.canScrollLeft}}),r("div",{key:"269924a8859aece37ff31202307d4feaecbbde86",class:"kritzel-tools-scroll",ref:t=>this.toolsScrollRef=t,onScroll:this.handleToolsScroll},o.map((t=>{if(t.subOptions?.length){const o=this.getSelectedSubOption(t),e=this.activeControl?.name===t.name;return r("div",{class:{"kritzel-control-split":!0,selected:e},key:t.name,"data-testid":`tool-${t.name}`,ref:o=>{o&&(t._anchorRef=o)}},r("button",{class:"kritzel-control-main",onClick:()=>this.handleControlClick(t),"aria-label":o?.label,"data-testid":`tool-${t.name}-main`},r("kritzel-icon",{name:o?.icon||t.icon})),r("button",{class:{"kritzel-control-dropdown":!0,visible:e},ref:o=>{o&&(t._triggerRef=o)},"aria-label":`Select ${t.name} options`,"data-testid":`tool-${t.name}-dropdown`,tabIndex:e?0:-1},r("kritzel-icon",{name:"chevron-down",size:12})),r("kritzel-tooltip",{anchorElement:t._anchorRef,triggerElement:t._triggerRef},r("div",{class:"kritzel-submenu-content"},t.subOptions.map((e=>r("button",{class:{"kritzel-submenu-item":!0,active:e.id===o?.id},key:e.id,"data-testid":`suboption-${e.id}`,onClick:()=>this.selectSubOption(t,e)},r("kritzel-icon",{name:e.icon,size:20}),r("span",null,e.label)))))))}return"separator"===t.type?r("div",{class:"kritzel-control-separator",key:t.name}):r("button",{class:{"kritzel-control":!0,selected:this.activeControl?.name===t?.name},key:t.name,"data-testid":`tool-${t.name}`,onClick:()=>this.handleControlClick?.(t),"aria-label":t.name.charAt(0).toUpperCase()+t.name.slice(1)},r("kritzel-icon",{name:t.icon}))}))),r("div",{key:"8b97a5bba3ac4992482e8f433d7ba6197918a914",class:{"scroll-indicator-right":!0,visible:this.canScrollRight&&!(e&&this.activeControl&&t)}}),e&&this.activeControl&&r("div",{class:{"kritzel-config-container":!0,visible:t},key:e.name},r("div",{key:"d9adef8c2acc8d9b9d745174050ce78960b89b58",class:{"config-gradient-left":!0,visible:this.needsScrolling}}),r("kritzel-tooltip",{key:"7605bbd2b6335c89c57aa68952293f26efad6b4b",anchorElement:this.host.shadowRoot?.querySelector(".kritzel-config-container"),triggerElement:this.configTriggerRef},r("kritzel-tool-config",{key:"27b0f41442215e78b692fa44bb665444a4993b89",tool:this.activeControl.tool,theme:this.theme,engine:this.kritzelEngine,onToolChange:t=>this.handleToolChange?.(t),onDisplayValuesChange:this.handleDisplayValuesChange,style:{width:"100%",height:"100%"}})),r("div",{key:"1fb5979b1c531593acf5086861b22b7d78d03e8d",tabIndex:t?0:-1,class:"kritzel-config","data-testid":"tool-config",ref:t=>{t&&(this.configTriggerRef=t)},onKeyDown:t=>{"Enter"===t.key&&t.target.click()},style:{cursor:"pointer"}},this.displayValues&&r("div",{key:"3713ef344630f6b4d88df2e83992018859ddb18c",class:"color-container"},r("kritzel-color",{key:"c2679f68efae77c6daeb98be9e03d5320d51a73a",value:this.displayValues.color,theme:this.theme,size:18,style:{borderRadius:"50%",border:"none"}}))))))}static get assetsDirs(){return["../assets"]}static get watchers(){return{controls:[{onControlsChange:0}],theme:[{onThemeChange:0}]}}static get style(){return":host{display:flex;flex-direction:column;user-select:none;max-width:100%;z-index:1}:host(.mobile){--kritzel-controls-control-hover-background-color:transparent;--kritzel-controls-control-active-background-color:transparent}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap, 8px);height:100%;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 16px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #ebebeb);z-index:1;position:relative;max-width:100%;overflow:hidden}.kritzel-tools-scroll{display:flex;flex-direction:row;align-items:center;gap:var(--kritzel-controls-gap, 8px);overflow-x:auto;overflow-y:hidden;flex:1 1 auto;min-width:0;padding:4px;margin:-4px;scrollbar-width:none;-ms-overflow-style:none}.kritzel-tools-scroll::-webkit-scrollbar{display:none}.scroll-indicator-left,.scroll-indicator-right{position:absolute;top:0;bottom:0;width:32px;pointer-events:none;opacity:0;transition:opacity 0.2s ease-out;z-index:1}.scroll-indicator-left{left:0;background:linear-gradient(to right, var(--kritzel-controls-background-color, #ffffff), transparent);border-radius:var(--kritzel-controls-border-radius, 16px) 0 0 var(--kritzel-controls-border-radius, 16px)}.scroll-indicator-right{right:0;background:linear-gradient(to left, var(--kritzel-controls-background-color, #ffffff), transparent);border-radius:0 var(--kritzel-controls-border-radius, 16px) var(--kritzel-controls-border-radius, 16px) 0}.scroll-indicator-left.visible,.scroll-indicator-right.visible{opacity:1}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color, #000000);border-radius:var(--kritzel-controls-control-border-radius, 12px);padding:var(--kritzel-controls-control-padding, 8px);border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:focus,.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control.selected:focus{background-color:var(--kritzel-controls-control-selected-background-color, #007bffe3) !important}.kritzel-control-separator{width:1px;height:24px;background-color:var(--kritzel-controls-separator-color, #ebebeb);margin:0 4px}.kritzel-control-split{position:relative;display:flex;align-items:center;border-radius:var(--kritzel-controls-control-border-radius, 12px);color:var(--kritzel-controls-control-color, #000000)}.kritzel-control-split .kritzel-control-main{display:flex;justify-content:center;align-items:center;padding:var(--kritzel-controls-control-padding, 8px);border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;border-radius:var(--kritzel-controls-control-border-radius, 12px);color:inherit}.kritzel-control-split.selected .kritzel-control-main{border-radius:var(--kritzel-controls-control-border-radius, 12px) 0 0 var(--kritzel-controls-control-border-radius, 12px)}.kritzel-control-split .kritzel-control-dropdown{display:flex;justify-content:center;align-items:center;align-self:stretch;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);-webkit-tap-highlight-color:transparent;border-radius:0 var(--kritzel-controls-control-border-radius, 12px) var(--kritzel-controls-control-border-radius, 12px) 0;color:inherit;width:0;padding:0;opacity:0;overflow:hidden;pointer-events:none;transition:width 0.15s ease-out, padding 0.15s ease-out, opacity 0.15s ease-out}.kritzel-control-split .kritzel-control-dropdown.visible{width:auto;padding:0 6px;opacity:1;pointer-events:auto}.kritzel-control-split .kritzel-control-main:focus,.kritzel-control-split .kritzel-control-main:hover,.kritzel-control-split .kritzel-control-dropdown:focus,.kritzel-control-split .kritzel-control-dropdown:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-control-split .kritzel-control-main:active,.kritzel-control-split .kritzel-control-dropdown:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}.kritzel-control-split.selected{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-control-split.selected .kritzel-control-main:hover,.kritzel-control-split.selected .kritzel-control-dropdown:hover{background-color:rgba(255, 255, 255, 0.15)}.kritzel-submenu-content{display:flex;flex-direction:column;gap:var(--kritzel-submenu-gap, 4px);min-width:140px}.kritzel-submenu-item{display:flex;align-items:center;gap:10px;padding:10px 12px;border:none;background:none;cursor:var(--kritzel-global-pointer-cursor, pointer);border-radius:8px;color:var(--kritzel-controls-control-color, #000000);font-size:14px;text-align:left;white-space:nowrap;-webkit-tap-highlight-color:transparent}.kritzel-submenu-item:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-submenu-item.active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF);color:var(--kritzel-controls-control-selected-color, #ffffff)}.kritzel-submenu-item.active:hover{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF)}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent;flex-shrink:0;width:0;opacity:0;overflow:hidden;pointer-events:none;margin-left:calc(-1 * var(--kritzel-controls-gap, 8px));transition:width 0.2s ease-out, opacity 0.2s ease-out, margin-left 0.2s ease-out}.kritzel-config-container.visible{width:40px;opacity:1;pointer-events:auto;margin-left:0;overflow:visible}.config-gradient-left{position:absolute;top:0;bottom:0;left:-32px;width:32px;background:linear-gradient(to right, transparent, var(--kritzel-controls-background-color, #ffffff));pointer-events:none;z-index:1;opacity:0;transition:opacity 0.2s ease-out}.config-gradient-left.visible{opacity:1}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:var(--kritzel-global-pointer-cursor, pointer);border-radius:50%}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.font-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:var(--kritzel-global-pointer-cursor, pointer);border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{z-index:10001}"}},[513,"kritzel-controls",{visible:[4],controls:[16],activeControl:[1040],isUtilityPanelVisible:[4,"is-utility-panel-visible"],undoState:[16],theme:[1],firstConfig:[32],isTouchDevice:[32],selectedSubOptions:[32],canScrollLeft:[32],canScrollRight:[32],needsScrolling:[32],displayValues:[32],internalControls:[32],closeTooltip:[64]},[[8,"keydown","handleKeyDown"]],{controls:[{onControlsChange:0}],theme:[{onThemeChange:0}]}]);function E(){"undefined"!=typeof customElements&&["kritzel-controls","kritzel-color","kritzel-color-palette","kritzel-dropdown","kritzel-font","kritzel-font-family","kritzel-font-size","kritzel-icon","kritzel-line-endings","kritzel-opacity-slider","kritzel-shape-fill","kritzel-stroke-size","kritzel-tool-config","kritzel-tooltip","kritzel-utility-panel"].forEach((t=>{switch(t){case"kritzel-controls":customElements.get(l(t))||customElements.define(l(t),T);break;case"kritzel-color":customElements.get(l(t))||p();break;case"kritzel-color-palette":customElements.get(l(t))||k();break;case"kritzel-dropdown":customElements.get(l(t))||b();break;case"kritzel-font":customElements.get(l(t))||u();break;case"kritzel-font-family":customElements.get(l(t))||f();break;case"kritzel-font-size":customElements.get(l(t))||g();break;case"kritzel-icon":customElements.get(l(t))||z();break;case"kritzel-line-endings":customElements.get(l(t))||m();break;case"kritzel-opacity-slider":customElements.get(l(t))||v();break;case"kritzel-shape-fill":customElements.get(l(t))||y();break;case"kritzel-stroke-size":customElements.get(l(t))||x();break;case"kritzel-tool-config":customElements.get(l(t))||d();break;case"kritzel-tooltip":customElements.get(l(t))||w();break;case"kritzel-utility-panel":customElements.get(l(t))||C()}}))}export{T as K,E as d}
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { H as HocuspocusProvider, a as HocuspocusProviderWebsocket } from './schema.constants-NrtFvKER.js';
2
- export { B as APP_STATE_MIGRATIONS, A as AssetNotFoundError, E as CURRENT_APP_STATE_SCHEMA_VERSION, F as CURRENT_WORKSPACE_SCHEMA_VERSION, v as DEFAULT_ASSET_STORAGE_CONFIG, D as DEFAULT_BRUSH_CONFIG, u as DEFAULT_LINE_TOOL_CONFIG, t as DEFAULT_TEXT_CONFIG, I as IndexedDBAssetProvider, y as KritzelAlignment, r as KritzelAnchorManager, p as KritzelAssetResolver, K as KritzelBaseObject, h as KritzelBrushTool, n as KritzelCursorHelper, j as KritzelEraserTool, f as KritzelGroup, d as KritzelImage, k as KritzelImageTool, e as KritzelLine, i as KritzelLineTool, c as KritzelPath, o as KritzelSelectionTool, g as KritzelShape, m as KritzelShapeTool, b as KritzelText, l as KritzelTextTool, s as KritzelThemeManager, q as KritzelWorkspace, S as ShapeType, W as WORKSPACE_EXPORT_VERSION, C as WORKSPACE_MIGRATIONS, x as darkTheme, w as lightTheme, z as runMigrations } from './schema.constants-NrtFvKER.js';
1
+ import { H as HocuspocusProvider, a as HocuspocusProviderWebsocket } from './schema.constants-DiCnmIYK.js';
2
+ export { B as APP_STATE_MIGRATIONS, A as AssetNotFoundError, E as CURRENT_APP_STATE_SCHEMA_VERSION, F as CURRENT_WORKSPACE_SCHEMA_VERSION, v as DEFAULT_ASSET_STORAGE_CONFIG, D as DEFAULT_BRUSH_CONFIG, u as DEFAULT_LINE_TOOL_CONFIG, t as DEFAULT_TEXT_CONFIG, I as IndexedDBAssetProvider, y as KritzelAlignment, r as KritzelAnchorManager, p as KritzelAssetResolver, K as KritzelBaseObject, h as KritzelBrushTool, n as KritzelCursorHelper, j as KritzelEraserTool, f as KritzelGroup, d as KritzelImage, k as KritzelImageTool, e as KritzelLine, i as KritzelLineTool, c as KritzelPath, o as KritzelSelectionTool, g as KritzelShape, m as KritzelShapeTool, b as KritzelText, l as KritzelTextTool, s as KritzelThemeManager, q as KritzelWorkspace, S as ShapeType, W as WORKSPACE_EXPORT_VERSION, C as WORKSPACE_MIGRATIONS, x as darkTheme, w as lightTheme, z as runMigrations } from './schema.constants-DiCnmIYK.js';
3
3
  import * as Y from 'yjs';
4
4
  import { IndexeddbPersistence } from 'y-indexeddb';
5
5
  import { WebsocketProvider } from 'y-websocket';
@@ -1,5 +1,5 @@
1
1
  import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-Dhio9uis.js';
2
- import { c as KritzelPath, e as KritzelLine, G as KritzelColorHelper, J as KritzelDevicesHelper, o as KritzelSelectionTool, l as KritzelTextTool, L as KritzelMouseButton, M as DEFAULT_STROKE_SIZES, N as DEFAULT_COLOR_PALETTE, S as ShapeType, D as DEFAULT_BRUSH_CONFIG, h as KritzelBrushTool, j as KritzelEraserTool, u as DEFAULT_LINE_TOOL_CONFIG, i as KritzelLineTool, m as KritzelShapeTool, t as DEFAULT_TEXT_CONFIG, k as KritzelImageTool, y as KritzelAlignment, v as DEFAULT_ASSET_STORAGE_CONFIG, T as ThemeHelper, x as darkTheme, w as lightTheme, O as KritzelSelectionGroup, P as KritzelSelectionBox, Q as KritzelIconRegistry, R as KritzelKeyboardHelper, U as KritzelBaseHandler, K as KritzelBaseObject, q as KritzelWorkspace, f as KritzelGroup, d as KritzelImage, g as KritzelShape, b as KritzelText, z as runMigrations, F as CURRENT_WORKSPACE_SCHEMA_VERSION, C as WORKSPACE_MIGRATIONS, E as CURRENT_APP_STATE_SCHEMA_VERSION, B as APP_STATE_MIGRATIONS, V as ObjectHelper, n as KritzelCursorHelper, r as KritzelAnchorManager, s as KritzelThemeManager, p as KritzelAssetResolver, X as KritzelClassHelper, Y as KritzelEventHelper, W as WORKSPACE_EXPORT_VERSION } from './schema.constants-NrtFvKER.js';
2
+ import { c as KritzelPath, e as KritzelLine, G as KritzelColorHelper, J as KritzelDevicesHelper, o as KritzelSelectionTool, l as KritzelTextTool, L as KritzelMouseButton, M as DEFAULT_STROKE_SIZES, N as DEFAULT_COLOR_PALETTE, S as ShapeType, D as DEFAULT_BRUSH_CONFIG, h as KritzelBrushTool, j as KritzelEraserTool, u as DEFAULT_LINE_TOOL_CONFIG, i as KritzelLineTool, m as KritzelShapeTool, t as DEFAULT_TEXT_CONFIG, k as KritzelImageTool, y as KritzelAlignment, v as DEFAULT_ASSET_STORAGE_CONFIG, T as ThemeHelper, x as darkTheme, w as lightTheme, O as KritzelSelectionGroup, P as KritzelSelectionBox, Q as KritzelIconRegistry, R as KritzelKeyboardHelper, U as KritzelBaseHandler, K as KritzelBaseObject, q as KritzelWorkspace, f as KritzelGroup, d as KritzelImage, g as KritzelShape, b as KritzelText, z as runMigrations, F as CURRENT_WORKSPACE_SCHEMA_VERSION, C as WORKSPACE_MIGRATIONS, E as CURRENT_APP_STATE_SCHEMA_VERSION, B as APP_STATE_MIGRATIONS, V as ObjectHelper, n as KritzelCursorHelper, r as KritzelAnchorManager, s as KritzelThemeManager, p as KritzelAssetResolver, X as KritzelClassHelper, Y as KritzelEventHelper, W as WORKSPACE_EXPORT_VERSION } from './schema.constants-DiCnmIYK.js';
3
3
  import * as Y from 'yjs';
4
4
  import 'y-indexeddb';
5
5
  import 'y-websocket';
@@ -2502,6 +2502,12 @@ const KritzelEditor = class {
2502
2502
  async zoomTo(scale, worldX, worldY) {
2503
2503
  return this.engineRef.zoomTo(scale, worldX, worldY);
2504
2504
  }
2505
+ async zoomIn(factor = 1.6, duration = 200) {
2506
+ return this.engineRef.zoomIn(factor, duration);
2507
+ }
2508
+ async zoomOut(factor = 1.6, duration = 200) {
2509
+ return this.engineRef.zoomOut(factor, duration);
2510
+ }
2505
2511
  async getViewport() {
2506
2512
  return this.engineRef.getViewport();
2507
2513
  }
@@ -2587,14 +2593,14 @@ const KritzelEditor = class {
2587
2593
  async redo() {
2588
2594
  return this.engineRef.redo();
2589
2595
  }
2590
- async getScreenshot(format = 'png') {
2591
- return this.engineRef.getScreenshot(format);
2596
+ async getScreenshot(format = 'png', options) {
2597
+ return this.engineRef.getScreenshot(format, options);
2592
2598
  }
2593
- async exportViewportAsPng() {
2594
- return this.engineRef.exportViewportAsPng();
2599
+ async exportViewportAsPng(options) {
2600
+ return this.engineRef.exportViewportAsPng(options);
2595
2601
  }
2596
- async exportViewportAsSvg() {
2597
- return this.engineRef.exportViewportAsSvg();
2602
+ async exportViewportAsSvg(options) {
2603
+ return this.engineRef.exportViewportAsSvg(options);
2598
2604
  }
2599
2605
  async exportSelectedObjectsAsPng() {
2600
2606
  return this.engineRef.exportSelectedObjectsAsPng();
@@ -2946,31 +2952,31 @@ const KritzelEditor = class {
2946
2952
  const isLoggedIn = this.isLoggedIn;
2947
2953
  const shouldShowCurrentUser = isLoggedIn;
2948
2954
  const shouldShowLoginButton = this.isReady && !!this.loginConfig && !isLoggedIn;
2949
- return (h(Host, { key: '673bfb4d2d5224c3c3a11bada8afb1c3b90aa03d', style: {
2955
+ return (h(Host, { key: 'ffacaea5d3df12a3a8b448d31db3c5949053156c', style: {
2950
2956
  opacity: this.isEditorVisible ? '1' : '0',
2951
2957
  visibility: this.isEditorVisible ? 'visible' : 'hidden',
2952
2958
  transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out',
2953
- } }, h("div", { key: 'cee9075de7a44953b3d017c334b19151ab7bb926', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'a7a6c246dabe3ddbab3d807a9f0c275bc621363f', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'b5452a22f7fd434b8816bdaa117d457b2f1879f3', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: 'a08648ec91f678724171238735b1073ffb53ca73', ref: el => {
2959
+ } }, h("div", { key: '669eafee25b4f84c39469738a1337c21ab03e388', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'd6feb4a71c3286830fbe53a533f283c8af9a0385', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: '5bd0e6263d51119b197292b69879c1ae437f92fc', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: '468f17137c51c90fd61c9179d13c449b1ac8feb9', ref: el => {
2954
2960
  if (el) {
2955
2961
  this.engineRef = el;
2956
2962
  }
2957
- }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, isObjectDistanceFadingActive: this.isObjectDistanceFadingActive, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.theme, themes: this.themes, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event) }), h("kritzel-controls", { key: 'a7b78a31bda3fe2fe1def6be339894b83ea3ee38', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
2963
+ }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, isObjectDistanceFadingActive: this.isObjectDistanceFadingActive, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.theme, themes: this.themes, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event) }), h("kritzel-controls", { key: '848c30b27fb916c8480b41745bd6ec844e0b23a2', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
2958
2964
  if (el) {
2959
2965
  this.controlsRef = el;
2960
2966
  }
2961
- }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: '0b3f4879c44864661a5bf5f126da3a869fa808f5', class: "top-right-buttons" }, h("kritzel-settings", { key: '7da7fb709f2e4a31a6df1f7382a91f4d78dc6e35', ref: el => {
2967
+ }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'e998d60679c767d15617bd7ecde5ee77e781a92f', class: "top-right-buttons" }, h("kritzel-settings", { key: '43b9cdb2d10de789cc03d2a9ef5df870b8ca7bfe', ref: el => {
2962
2968
  if (el) {
2963
2969
  this.settingsRef = el;
2964
2970
  }
2965
- }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], settings: this.currentSettingsConfig, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: 'f362b0181231da30efc927cbebd818a9a64991b0', ref: el => {
2971
+ }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], settings: this.currentSettingsConfig, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '74669624a1e5177125ef00e1667c880ce47cbce4', ref: el => {
2966
2972
  if (el) {
2967
2973
  this.exportRef = el;
2968
2974
  }
2969
- }, workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '1cf065fed9b27ffb19a3695425c797a3bc29fa51', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '7d6e8e227f36164daed7303645bdd490b362b4d0', user: this.user }), shouldShowLoginButton && (h("kritzel-button", { key: '1dcf1f5ae547f4c2c5b7ec88b34bcad0a2a4da28', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in")), h("kritzel-more-menu", { key: 'cb80dea4bb9861b6d627399c9aad64075cb8944b', items: this.moreMenuItems, visible: this.isMoreMenuVisible }), h("kritzel-share-dialog", { key: 'd12bc96d7af23941e4e054dadfddcf6429de6208', ref: el => {
2975
+ }, workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '18d925f32d021ff6713accb22d0594d259d70f2e', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: 'bddd5c29c5f17cced47276c237c04cfdb711da38', user: this.user }), shouldShowLoginButton && (h("kritzel-button", { key: '4eb6c85459f59863d6e644ecf21c2295da71bafc', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in")), h("kritzel-more-menu", { key: 'a5a323ec248bebc7bc07898f344e0926fac8db17', items: this.moreMenuItems, visible: this.isMoreMenuVisible }), h("kritzel-share-dialog", { key: '8cb3ddad95d36f5b7ad59d8c4f057df93cb2bfe3', ref: el => {
2970
2976
  if (el) {
2971
2977
  this.shareDialogRef = el;
2972
2978
  }
2973
- }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '6c29a13069cd74972e94bbc245f26375fa95f4cc', ref: el => {
2979
+ }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '35395d0faadcfeb021fba685aa46e180e47d2be2', ref: el => {
2974
2980
  if (el) {
2975
2981
  this.loginDialogRef = el;
2976
2982
  }
@@ -20657,6 +20663,87 @@ class KritzelViewport {
20657
20663
  this.setViewport(centerWorldX, centerWorldY, scale);
20658
20664
  }
20659
20665
  }
20666
+ /**
20667
+ * Zooms in by a fixed step, centered on the current viewport center,
20668
+ * with a smooth animation. The resulting scale is clamped to the allowed range.
20669
+ * @param factor - Multiplicative zoom-in step
20670
+ * @param duration - Animation duration in milliseconds
20671
+ */
20672
+ zoomIn(factor, duration) {
20673
+ this.animateZoomAroundViewportCenter(factor, duration);
20674
+ }
20675
+ /**
20676
+ * Zooms out by a fixed step, centered on the current viewport center,
20677
+ * with a smooth animation. The resulting scale is clamped to the allowed range.
20678
+ * @param factor - Multiplicative zoom-out step
20679
+ * @param duration - Animation duration in milliseconds
20680
+ */
20681
+ zoomOut(factor, duration) {
20682
+ this.animateZoomAroundViewportCenter(1 / factor, duration);
20683
+ }
20684
+ /**
20685
+ * Smoothly zooms around the viewport center, keeping the center world point
20686
+ * fixed for the entire animation. The translation is recomputed from the fixed
20687
+ * center point on every frame (rather than interpolated independently), which
20688
+ * guarantees the center never drifts and the viewport does not jump.
20689
+ * The resulting scale is clamped to the allowed range and the translation is
20690
+ * clamped to the viewport boundaries.
20691
+ * @param scaleFactor - Multiplicative scale factor (>1 zooms in, <1 zooms out)
20692
+ * @param duration - Animation duration in milliseconds
20693
+ */
20694
+ animateZoomAroundViewportCenter(scaleFactor, duration) {
20695
+ this.cancelViewportAnimation();
20696
+ const state = this._core.store.state;
20697
+ const startScale = state.scale;
20698
+ const effectiveMinScale = this.getEffectiveMinScale();
20699
+ const targetScale = Math.min(state.scaleMax, Math.max(effectiveMinScale, startScale * scaleFactor));
20700
+ // The world point currently under the viewport center stays fixed.
20701
+ const centerScreenX = state.viewportWidth / 2;
20702
+ const centerScreenY = state.viewportHeight / 2;
20703
+ const centerWorldX = (centerScreenX - state.translateX) / startScale;
20704
+ const centerWorldY = (centerScreenY - state.translateY) / startScale;
20705
+ if (targetScale === startScale || duration <= 0) {
20706
+ this.applyZoomAroundCenter(targetScale, centerScreenX, centerScreenY, centerWorldX, centerWorldY);
20707
+ state.isScaling = true;
20708
+ this._core.rerender();
20709
+ this._debounceUpdate();
20710
+ this._debounceEndScaling();
20711
+ return;
20712
+ }
20713
+ const startTime = performance.now();
20714
+ state.isScaling = true;
20715
+ const animate = (currentTime) => {
20716
+ const elapsed = currentTime - startTime;
20717
+ const progress = Math.min(elapsed / duration, 1);
20718
+ // easeInOutCubic for a smooth ramp in and out
20719
+ const eased = progress < 0.5 ? 4 * progress * progress * progress : 1 - Math.pow(-2 * progress + 2, 3) / 2;
20720
+ const frameScale = startScale + (targetScale - startScale) * eased;
20721
+ this.applyZoomAroundCenter(frameScale, centerScreenX, centerScreenY, centerWorldX, centerWorldY);
20722
+ this._core.rerender();
20723
+ if (progress < 1) {
20724
+ this._animationFrameId = requestAnimationFrame(animate);
20725
+ }
20726
+ else {
20727
+ this._animationFrameId = null;
20728
+ state.isScaling = false;
20729
+ this._core.rerender();
20730
+ this._debounceUpdate();
20731
+ }
20732
+ };
20733
+ this._animationFrameId = requestAnimationFrame(animate);
20734
+ }
20735
+ /**
20736
+ * Applies a single zoom step that keeps the given world point anchored to the
20737
+ * given screen point at the specified scale, clamped to the viewport boundaries.
20738
+ */
20739
+ applyZoomAroundCenter(scale, screenX, screenY, worldX, worldY) {
20740
+ const state = this._core.store.state;
20741
+ state.scale = scale;
20742
+ const clamped = this.clampTranslate(screenX - worldX * scale, screenY - worldY * scale);
20743
+ state.translateX = clamped.translateX;
20744
+ state.translateY = clamped.translateY;
20745
+ state.hasViewportChanged = true;
20746
+ }
20660
20747
  /**
20661
20748
  * Centers a given object in the viewport without changing the scale.
20662
20749
  * The object's center point will be positioned at the viewport center.
@@ -26971,6 +27058,9 @@ const KritzelEngine = class {
26971
27058
  object.scale = object.scale ?? this.core.store.state.scale;
26972
27059
  object.zIndex = this.core.store.currentZIndex;
26973
27060
  object.workspaceId = this.core.store.state.activeWorkspace.id;
27061
+ if (KritzelClassHelper.isInstanceOf(object, 'KritzelImage')) {
27062
+ await object.prepareForInsert();
27063
+ }
26974
27064
  // Handle KritzelText: recreate the editor now that _core is available
26975
27065
  // The editor's dispatchTransaction callback needs _core for persisting changes
26976
27066
  if (KritzelClassHelper.isInstanceOf(object, 'KritzelText')) {
@@ -27055,6 +27145,12 @@ const KritzelEngine = class {
27055
27145
  if (objects.length === 0) {
27056
27146
  return [];
27057
27147
  }
27148
+ for (const object of objects) {
27149
+ object._core = this.core;
27150
+ if (KritzelClassHelper.isInstanceOf(object, 'KritzelImage')) {
27151
+ await object.prepareForInsert();
27152
+ }
27153
+ }
27058
27154
  this.core.store.objects.transaction(() => {
27059
27155
  for (const object of objects) {
27060
27156
  object.id = object.generateId();
@@ -27281,6 +27377,22 @@ const KritzelEngine = class {
27281
27377
  async zoomTo(scale, worldX, worldY) {
27282
27378
  this.viewport.zoomTo(scale, worldX, worldY);
27283
27379
  }
27380
+ /**
27381
+ * Zooms in by a fixed step, centered on the current viewport center, with a smooth animation.
27382
+ * @param factor - Multiplicative zoom-in step.
27383
+ * @param duration - Animation duration in milliseconds.
27384
+ */
27385
+ async zoomIn(factor, duration) {
27386
+ this.viewport.zoomIn(factor, duration);
27387
+ }
27388
+ /**
27389
+ * Zooms out by a fixed step, centered on the current viewport center, with a smooth animation.
27390
+ * @param factor - Multiplicative zoom-out step.
27391
+ * @param duration - Animation duration in milliseconds.
27392
+ */
27393
+ async zoomOut(factor, duration) {
27394
+ this.viewport.zoomOut(factor, duration);
27395
+ }
27284
27396
  /**
27285
27397
  * Returns the current viewport state including position, scale, and dimensions.
27286
27398
  * @returns The current viewport state.
@@ -27317,11 +27429,14 @@ const KritzelEngine = class {
27317
27429
  /**
27318
27430
  * Captures a screenshot of the current viewport as a data URL.
27319
27431
  * @param format - The image format: `'png'` (default) or `'svg'`.
27432
+ * @param options - Optional screenshot settings.
27433
+ * @param options.includeBackground - Whether to include the canvas background in the export. Defaults to `true`. Set to `false` for a transparent background.
27320
27434
  * @returns A data URL string of the captured image.
27321
27435
  */
27322
- async getScreenshot(format = 'png') {
27436
+ async getScreenshot(format = 'png', options) {
27323
27437
  if (!this.host)
27324
27438
  return null;
27439
+ const includeBackground = options?.includeBackground ?? true;
27325
27440
  // Save critical state before screenshot to restore after
27326
27441
  const savedState = {
27327
27442
  objects: this.core.store.objects,
@@ -27333,7 +27448,7 @@ const KritzelEngine = class {
27333
27448
  translateY: this.core.store.state.translateY,
27334
27449
  scale: this.core.store.state.scale,
27335
27450
  };
27336
- const options = {
27451
+ const screenshotOptions = {
27337
27452
  filter: (node) => {
27338
27453
  // Exclude the context menu, debug panel, and awareness cursors from the screenshot
27339
27454
  if (node.tagName === 'KRITZEL-CONTEXT-MENU') {
@@ -27348,13 +27463,16 @@ const KritzelEngine = class {
27348
27463
  return true;
27349
27464
  },
27350
27465
  };
27466
+ if (!includeBackground) {
27467
+ screenshotOptions.backgroundColor = 'transparent';
27468
+ }
27351
27469
  let result;
27352
27470
  try {
27353
27471
  if (format === 'svg') {
27354
- result = await toSvg(this.host, options);
27472
+ result = await toSvg(this.host, screenshotOptions);
27355
27473
  }
27356
27474
  else {
27357
- result = await toPng(this.host, options);
27475
+ result = await toPng(this.host, screenshotOptions);
27358
27476
  }
27359
27477
  }
27360
27478
  finally {
@@ -27371,14 +27489,18 @@ const KritzelEngine = class {
27371
27489
  }
27372
27490
  return result;
27373
27491
  }
27374
- /** Exports the current viewport as a PNG file and triggers a browser download. */
27375
- async exportViewportAsPng() {
27492
+ /**
27493
+ * Exports the current viewport as a PNG file and triggers a browser download.
27494
+ * @param options - Optional export settings.
27495
+ * @param options.includeBackground - Whether to include the canvas background. Defaults to `true`.
27496
+ */
27497
+ async exportViewportAsPng(options) {
27376
27498
  try {
27377
27499
  const activeWorkspaceName = this.core.store.state?.activeWorkspace?.name || 'workspace';
27378
27500
  // timestamp format: YYYY-MM-DDTHH-mm-ss-sssZ, clearing colons/dots for safe filename
27379
27501
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
27380
27502
  const filename = `${activeWorkspaceName}-${timestamp}.png`;
27381
- const dataUrl = await this.getScreenshot('png');
27503
+ const dataUrl = await this.getScreenshot('png', options);
27382
27504
  if (!dataUrl) {
27383
27505
  console.error('Failed to export viewport as PNG: screenshot could not be generated');
27384
27506
  return;
@@ -27392,14 +27514,18 @@ const KritzelEngine = class {
27392
27514
  console.error('Failed to export viewport as PNG:', error);
27393
27515
  }
27394
27516
  }
27395
- /** Exports the current viewport as an SVG file and triggers a browser download. */
27396
- async exportViewportAsSvg() {
27517
+ /**
27518
+ * Exports the current viewport as an SVG file and triggers a browser download.
27519
+ * @param options - Optional export settings.
27520
+ * @param options.includeBackground - Whether to include the canvas background. Defaults to `true`.
27521
+ */
27522
+ async exportViewportAsSvg(options) {
27397
27523
  try {
27398
27524
  const activeWorkspaceName = this.core.store.state?.activeWorkspace?.name || 'workspace';
27399
27525
  // timestamp format: YYYY-MM-DDTHH-mm-ss-sssZ, clearing colons/dots for safe filename
27400
27526
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
27401
27527
  const filename = `${activeWorkspaceName}-${timestamp}.svg`;
27402
- const dataUrl = await this.getScreenshot('svg');
27528
+ const dataUrl = await this.getScreenshot('svg', options);
27403
27529
  if (!dataUrl) {
27404
27530
  console.error('Failed to export viewport as SVG: screenshot could not be generated');
27405
27531
  return;
@@ -29969,7 +30095,7 @@ const KritzelPortal = class {
29969
30095
  * This file is auto-generated by the version bump scripts.
29970
30096
  * Do not modify manually.
29971
30097
  */
29972
- const KRITZEL_VERSION = '0.3.13';
30098
+ const KRITZEL_VERSION = '0.3.14';
29973
30099
 
29974
30100
  const kritzelSettingsCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}.shortcuts-list{display:flex;flex-direction:column;gap:24px}.shortcuts-category{display:flex;flex-direction:column;gap:8px}.shortcuts-category-title{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.shortcuts-group{display:flex;flex-direction:column;gap:4px}.shortcut-item{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-item-bg, rgba(0, 0, 0, 0.02))}.shortcut-label{font-size:14px;color:var(--kritzel-settings-content-text-color, #666666)}.shortcut-key{font-family:monospace;font-size:12px;padding:2px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-key-bg, #f0f0f0);color:var(--kritzel-settings-shortcut-key-color, #333333);border:1px solid var(--kritzel-settings-shortcut-key-border, #ddd)}`;
29975
30101