@widgetic/canvas 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -0
- package/dist/canvas/Canvas.svelte +10678 -0
- package/dist/canvas/Canvas.svelte.d.ts +147 -0
- package/dist/canvas/CanvasToolbar.svelte +1422 -0
- package/dist/canvas/CanvasToolbar.svelte.d.ts +54 -0
- package/dist/canvas/ContextMenu.svelte +279 -0
- package/dist/canvas/ContextMenu.svelte.d.ts +36 -0
- package/dist/canvas/PanZoomPanel.svelte +315 -0
- package/dist/canvas/PanZoomPanel.svelte.d.ts +32 -0
- package/dist/canvas/canvasLogger.d.ts +5 -0
- package/dist/canvas/canvasLogger.js +19 -0
- package/dist/canvas/index.d.ts +13 -0
- package/dist/canvas/index.js +12 -0
- package/dist/canvas/props-panel/PropsPanel.svelte +1902 -0
- package/dist/canvas/props-panel/PropsPanel.svelte.d.ts +73 -0
- package/dist/canvas/props-panel/TextPropsICSection.svelte +238 -0
- package/dist/canvas/props-panel/TextPropsICSection.svelte.d.ts +36 -0
- package/dist/canvas/shapes/FrameShape.d.ts +97 -0
- package/dist/canvas/shapes/FrameShape.js +951 -0
- package/dist/canvas/shapes/ImageShape.d.ts +38 -0
- package/dist/canvas/shapes/ImageShape.js +245 -0
- package/dist/canvas/shapes/ShapeLibrary.d.ts +64 -0
- package/dist/canvas/shapes/ShapeLibrary.js +526 -0
- package/dist/canvas/shapes/WidgetShape.d.ts +21 -0
- package/dist/canvas/shapes/WidgetShape.js +132 -0
- package/dist/canvas/types.d.ts +26 -0
- package/dist/canvas/types.js +5 -0
- package/dist/components/Tooltip.svelte +179 -0
- package/dist/components/Tooltip.svelte.d.ts +21 -0
- package/dist/components/index.d.ts +11 -0
- package/dist/components/index.js +13 -0
- package/dist/components/input-controls/ColorIC.svelte +388 -0
- package/dist/components/input-controls/ColorIC.svelte.d.ts +22 -0
- package/dist/components/input-controls/FontSelectorIC.svelte +69 -0
- package/dist/components/input-controls/FontSelectorIC.svelte.d.ts +17 -0
- package/dist/components/input-controls/SliderUnitIC.svelte +217 -0
- package/dist/components/input-controls/SliderUnitIC.svelte.d.ts +24 -0
- package/dist/components/input-controls/TextAlignIC.svelte +84 -0
- package/dist/components/input-controls/TextAlignIC.svelte.d.ts +17 -0
- package/dist/components/input-controls/TextStyleIC.svelte +85 -0
- package/dist/components/input-controls/TextStyleIC.svelte.d.ts +21 -0
- package/dist/icons/arrow.svg +3 -0
- package/dist/icons/checkmark.svg +3 -0
- package/dist/icons/draw.svg +22 -0
- package/dist/icons/eraser.svg +23 -0
- package/dist/icons/hand.svg +6 -0
- package/dist/icons/select.svg +3 -0
- package/dist/icons/text.svg +5 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +12 -0
- package/package.json +101 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
class?: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
selectedObject?: any;
|
|
7
|
+
wireframeMode?: boolean;
|
|
8
|
+
onFillChange?: (color: string) => void;
|
|
9
|
+
onStrokeChange?: (color: string) => void;
|
|
10
|
+
onStrokeWidthChange?: (width: number) => void;
|
|
11
|
+
onRoundnessChange?: (roundness: number) => void;
|
|
12
|
+
onStrokeTypeChange?: (type: "solid" | "dashed" | "dotted") => void;
|
|
13
|
+
onOpacityChange?: (opacity: number) => void;
|
|
14
|
+
onFillOpacityChange?: (opacity: number) => void;
|
|
15
|
+
onBackgroundColorChange?: (color: string) => void;
|
|
16
|
+
onBackgroundOpacityChange?: (opacity: number) => void;
|
|
17
|
+
onFontSizeChange?: (size: number) => void;
|
|
18
|
+
onFontFamilyChange?: (family: string) => void;
|
|
19
|
+
onFontWeightChange?: (weight: "normal" | "bold") => void;
|
|
20
|
+
onFontStyleChange?: (style: "normal" | "italic") => void;
|
|
21
|
+
onUnderlineChange?: (underline: boolean) => void;
|
|
22
|
+
onTextAlignChange?: (align: "left" | "center" | "right") => void;
|
|
23
|
+
onTextPaddingChange?: (padding: number) => void;
|
|
24
|
+
onTextColorChange?: (color: string) => void;
|
|
25
|
+
onFrameLabelChange?: (label: string) => void;
|
|
26
|
+
onFrameLabelFontSizeChange?: (size: number) => void;
|
|
27
|
+
onFrameLabelFontFamilyChange?: (family: string) => void;
|
|
28
|
+
onFrameLabelTextAlignChange?: (align: "left" | "center" | "right") => void;
|
|
29
|
+
onFrameLabelTextColorChange?: (color: string) => void;
|
|
30
|
+
onFrameLabelFontWeightChange?: (weight: "normal" | "bold") => void;
|
|
31
|
+
onFrameLabelFontStyleChange?: (style: "normal" | "italic") => void;
|
|
32
|
+
onFrameLabelUnderlineChange?: (underline: boolean) => void;
|
|
33
|
+
onFrameLabelBackgroundColorChange?: (color: string) => void;
|
|
34
|
+
onTextboxBoxFillChange?: (color: string) => void;
|
|
35
|
+
onTextboxBoxStrokeChange?: (color: string) => void;
|
|
36
|
+
onTextboxBoxStrokeWidthChange?: (width: number) => void;
|
|
37
|
+
onTextboxBoxStrokeTypeChange?: (type: "solid" | "dashed" | "dotted") => void;
|
|
38
|
+
onTextStrokeColorChange?: (color: string) => void;
|
|
39
|
+
onTextStrokeWidthChange?: (width: number) => void;
|
|
40
|
+
onImageUrlLoad?: (url: string) => void;
|
|
41
|
+
onImageSourceChange?: () => void;
|
|
42
|
+
onCapture?: (() => void) | null;
|
|
43
|
+
onConvertToWidget?: (() => void) | null;
|
|
44
|
+
onWidgetClick?: ((widgetId: string) => void) | null;
|
|
45
|
+
onWidgetRename?: ((widgetId: string, newName: string) => void) | null;
|
|
46
|
+
onRefreshScreenshot?: ((widgetId: string) => void) | null;
|
|
47
|
+
getWidgetName?: ((widgetId: string) => string | null) | null;
|
|
48
|
+
/** Returns false when the linked widget was deleted or moved off this canvas. */ isWidgetKnown?: ((widgetId: string) => boolean) | null;
|
|
49
|
+
/** Remove the selected orphaned widget shape from the canvas. */ onRemoveOrphanedShape?: (() => void) | null;
|
|
50
|
+
onBringToFront?: () => void;
|
|
51
|
+
onBringForward?: () => void;
|
|
52
|
+
onSendBackward?: () => void;
|
|
53
|
+
onSendToBack?: () => void;
|
|
54
|
+
onAlignLeft?: () => void;
|
|
55
|
+
onAlignCenterH?: () => void;
|
|
56
|
+
onAlignRight?: () => void;
|
|
57
|
+
onAlignTop?: () => void;
|
|
58
|
+
onAlignMiddleV?: () => void;
|
|
59
|
+
onAlignBottom?: () => void;
|
|
60
|
+
onWidthChange?: (width: number) => void;
|
|
61
|
+
onHeightChange?: (height: number) => void;
|
|
62
|
+
};
|
|
63
|
+
events: {
|
|
64
|
+
[evt: string]: CustomEvent<any>;
|
|
65
|
+
};
|
|
66
|
+
slots: {};
|
|
67
|
+
};
|
|
68
|
+
export type PropsPanelProps = typeof __propDef.props;
|
|
69
|
+
export type PropsPanelEvents = typeof __propDef.events;
|
|
70
|
+
export type PropsPanelSlots = typeof __propDef.slots;
|
|
71
|
+
export default class PropsPanel extends SvelteComponentTyped<PropsPanelProps, PropsPanelEvents, PropsPanelSlots> {
|
|
72
|
+
}
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ColorIC from '../../components/input-controls/ColorIC.svelte';
|
|
3
|
+
import SliderUnitIC from '../../components/input-controls/SliderUnitIC.svelte';
|
|
4
|
+
|
|
5
|
+
let className = '';
|
|
6
|
+
export { className as class };
|
|
7
|
+
export let style = '';
|
|
8
|
+
|
|
9
|
+
// Current values
|
|
10
|
+
export let fontSize: number = 28;
|
|
11
|
+
export let fontFamily: string = 'Arial';
|
|
12
|
+
export let fontWeight: 'normal' | 'bold' = 'normal';
|
|
13
|
+
export let fontStyle: 'normal' | 'italic' = 'normal';
|
|
14
|
+
export let underline: boolean = false;
|
|
15
|
+
export let textAlign: 'left' | 'center' | 'right' = 'left';
|
|
16
|
+
export let textColor: string = '#000000';
|
|
17
|
+
|
|
18
|
+
// Callbacks
|
|
19
|
+
export let onFontSizeChange: (size: number) => void = () => {};
|
|
20
|
+
export let onFontFamilyChange: (family: string) => void = () => {};
|
|
21
|
+
export let onFontWeightChange: (weight: 'normal' | 'bold') => void = () => {};
|
|
22
|
+
export let onFontStyleChange: (style: 'normal' | 'italic') => void = () => {};
|
|
23
|
+
export let onUnderlineChange: (underline: boolean) => void = () => {};
|
|
24
|
+
export let onTextAlignChange: (align: 'left' | 'center' | 'right') => void = () => {};
|
|
25
|
+
export let onTextColorChange: (color: string) => void = () => {};
|
|
26
|
+
|
|
27
|
+
// Show/hide certain controls
|
|
28
|
+
export let showFontSize: boolean = true;
|
|
29
|
+
export let showFontFamily: boolean = true;
|
|
30
|
+
export let showTextStyle: boolean = true;
|
|
31
|
+
export let showTextAlign: boolean = true;
|
|
32
|
+
export let showTextColor: boolean = true;
|
|
33
|
+
|
|
34
|
+
// Font presets
|
|
35
|
+
const fontFamilies = [
|
|
36
|
+
'Arial',
|
|
37
|
+
'Helvetica',
|
|
38
|
+
'Times New Roman',
|
|
39
|
+
'Georgia',
|
|
40
|
+
'Verdana',
|
|
41
|
+
'Courier New',
|
|
42
|
+
'Impact',
|
|
43
|
+
'Comic Sans MS'
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
function handleFontFamilyChange(e: Event) {
|
|
47
|
+
const select = e.target as HTMLSelectElement;
|
|
48
|
+
onFontFamilyChange(select.value);
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<div class="{className ? className + ' ' : ''}text-props-component" style={style}>
|
|
53
|
+
|
|
54
|
+
{#if showFontSize}
|
|
55
|
+
<SliderUnitIC
|
|
56
|
+
label="Font Size"
|
|
57
|
+
value={fontSize}
|
|
58
|
+
min={8}
|
|
59
|
+
max={120}
|
|
60
|
+
step={1}
|
|
61
|
+
unit="px"
|
|
62
|
+
onChange={onFontSizeChange}
|
|
63
|
+
/>
|
|
64
|
+
{/if}
|
|
65
|
+
|
|
66
|
+
{#if showFontFamily}
|
|
67
|
+
<div class="prop-section">
|
|
68
|
+
<span class="prop-label">Font Family</span>
|
|
69
|
+
<select
|
|
70
|
+
value={fontFamily}
|
|
71
|
+
onchange={handleFontFamilyChange}
|
|
72
|
+
class="font-select"
|
|
73
|
+
>
|
|
74
|
+
{#each fontFamilies as font}
|
|
75
|
+
<option value={font} style="font-family: {font}">{font}</option>
|
|
76
|
+
{/each}
|
|
77
|
+
</select>
|
|
78
|
+
</div>
|
|
79
|
+
{/if}
|
|
80
|
+
|
|
81
|
+
{#if showTextStyle}
|
|
82
|
+
<div class="prop-section">
|
|
83
|
+
<span class="prop-label">Text Style</span>
|
|
84
|
+
<div class="text-style-buttons">
|
|
85
|
+
<button
|
|
86
|
+
class="style-btn {fontWeight === 'bold' ? 'active' : ''}"
|
|
87
|
+
onclick={() => onFontWeightChange(fontWeight === 'bold' ? 'normal' : 'bold')}
|
|
88
|
+
title="Bold"
|
|
89
|
+
>
|
|
90
|
+
<strong>B</strong>
|
|
91
|
+
</button>
|
|
92
|
+
<button
|
|
93
|
+
class="style-btn {fontStyle === 'italic' ? 'active' : ''}"
|
|
94
|
+
onclick={() => onFontStyleChange(fontStyle === 'italic' ? 'normal' : 'italic')}
|
|
95
|
+
title="Italic"
|
|
96
|
+
>
|
|
97
|
+
<em>I</em>
|
|
98
|
+
</button>
|
|
99
|
+
<button
|
|
100
|
+
class="style-btn {underline ? 'active' : ''}"
|
|
101
|
+
onclick={() => onUnderlineChange(!underline)}
|
|
102
|
+
title="Underline"
|
|
103
|
+
>
|
|
104
|
+
<span style="text-decoration: underline">U</span>
|
|
105
|
+
</button>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
{/if}
|
|
109
|
+
|
|
110
|
+
{#if showTextAlign}
|
|
111
|
+
<div class="prop-section">
|
|
112
|
+
<span class="prop-label">Text Align</span>
|
|
113
|
+
<div class="align-buttons">
|
|
114
|
+
<button
|
|
115
|
+
class="align-btn {textAlign === 'left' ? 'active' : ''}"
|
|
116
|
+
onclick={() => onTextAlignChange('left')}
|
|
117
|
+
title="Align Left"
|
|
118
|
+
>⫷</button>
|
|
119
|
+
<button
|
|
120
|
+
class="align-btn {textAlign === 'center' ? 'active' : ''}"
|
|
121
|
+
onclick={() => onTextAlignChange('center')}
|
|
122
|
+
title="Center"
|
|
123
|
+
>☰</button>
|
|
124
|
+
<button
|
|
125
|
+
class="align-btn {textAlign === 'right' ? 'active' : ''}"
|
|
126
|
+
onclick={() => onTextAlignChange('right')}
|
|
127
|
+
title="Align Right"
|
|
128
|
+
>⫸</button>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
{/if}
|
|
132
|
+
|
|
133
|
+
{#if showTextColor}
|
|
134
|
+
<ColorIC
|
|
135
|
+
label="Text Color"
|
|
136
|
+
value={textColor}
|
|
137
|
+
onChange={onTextColorChange}
|
|
138
|
+
/>
|
|
139
|
+
{/if}
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<style>
|
|
143
|
+
.text-props-component {
|
|
144
|
+
display: flex;
|
|
145
|
+
flex-direction: column;
|
|
146
|
+
gap: 10px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.prop-section {
|
|
150
|
+
display: flex;
|
|
151
|
+
flex-direction: column;
|
|
152
|
+
gap: 6px;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.prop-label {
|
|
156
|
+
font-size: 11px;
|
|
157
|
+
font-weight: 600;
|
|
158
|
+
color: #6b7280;
|
|
159
|
+
text-transform: uppercase;
|
|
160
|
+
letter-spacing: 0.5px;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* Font select */
|
|
164
|
+
.font-select {
|
|
165
|
+
width: 100%;
|
|
166
|
+
padding: 6px 8px;
|
|
167
|
+
border: 1px solid #d1d5db;
|
|
168
|
+
border-radius: 4px;
|
|
169
|
+
font-size: 12px;
|
|
170
|
+
cursor: pointer;
|
|
171
|
+
background: white;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.font-select:focus {
|
|
175
|
+
outline: none;
|
|
176
|
+
border-color: var(--accent, #314F2F);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Text style buttons */
|
|
180
|
+
.text-style-buttons {
|
|
181
|
+
display: flex;
|
|
182
|
+
gap: 4px;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.style-btn {
|
|
186
|
+
width: 32px;
|
|
187
|
+
height: 32px;
|
|
188
|
+
display: flex;
|
|
189
|
+
align-items: center;
|
|
190
|
+
justify-content: center;
|
|
191
|
+
border: 1px solid #d1d5db;
|
|
192
|
+
border-radius: 4px;
|
|
193
|
+
background: white;
|
|
194
|
+
font-size: 14px;
|
|
195
|
+
cursor: pointer;
|
|
196
|
+
transition: all 0.15s ease;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.style-btn:hover {
|
|
200
|
+
background: #f3f4f6;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.style-btn.active {
|
|
204
|
+
background: var(--accent, #314F2F);
|
|
205
|
+
color: white;
|
|
206
|
+
border-color: var(--accent, #314F2F);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* Align buttons */
|
|
210
|
+
.align-buttons {
|
|
211
|
+
display: flex;
|
|
212
|
+
gap: 4px;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.align-btn {
|
|
216
|
+
flex: 1;
|
|
217
|
+
height: 32px;
|
|
218
|
+
display: flex;
|
|
219
|
+
align-items: center;
|
|
220
|
+
justify-content: center;
|
|
221
|
+
border: 1px solid #d1d5db;
|
|
222
|
+
border-radius: 4px;
|
|
223
|
+
background: white;
|
|
224
|
+
font-size: 14px;
|
|
225
|
+
cursor: pointer;
|
|
226
|
+
transition: all 0.15s ease;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.align-btn:hover {
|
|
230
|
+
background: #f3f4f6;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.align-btn.active {
|
|
234
|
+
background: var(--accent, #314F2F);
|
|
235
|
+
color: white;
|
|
236
|
+
border-color: var(--accent, #314F2F);
|
|
237
|
+
}
|
|
238
|
+
</style>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
class?: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
fontSize?: number;
|
|
7
|
+
fontFamily?: string;
|
|
8
|
+
fontWeight?: "normal" | "bold";
|
|
9
|
+
fontStyle?: "normal" | "italic";
|
|
10
|
+
underline?: boolean;
|
|
11
|
+
textAlign?: "left" | "center" | "right";
|
|
12
|
+
textColor?: string;
|
|
13
|
+
onFontSizeChange?: (size: number) => void;
|
|
14
|
+
onFontFamilyChange?: (family: string) => void;
|
|
15
|
+
onFontWeightChange?: (weight: "normal" | "bold") => void;
|
|
16
|
+
onFontStyleChange?: (style: "normal" | "italic") => void;
|
|
17
|
+
onUnderlineChange?: (underline: boolean) => void;
|
|
18
|
+
onTextAlignChange?: (align: "left" | "center" | "right") => void;
|
|
19
|
+
onTextColorChange?: (color: string) => void;
|
|
20
|
+
showFontSize?: boolean;
|
|
21
|
+
showFontFamily?: boolean;
|
|
22
|
+
showTextStyle?: boolean;
|
|
23
|
+
showTextAlign?: boolean;
|
|
24
|
+
showTextColor?: boolean;
|
|
25
|
+
};
|
|
26
|
+
events: {
|
|
27
|
+
[evt: string]: CustomEvent<any>;
|
|
28
|
+
};
|
|
29
|
+
slots: {};
|
|
30
|
+
};
|
|
31
|
+
export type TextPropsICSectionProps = typeof __propDef.props;
|
|
32
|
+
export type TextPropsICSectionEvents = typeof __propDef.events;
|
|
33
|
+
export type TextPropsICSectionSlots = typeof __propDef.slots;
|
|
34
|
+
export default class TextPropsICSection extends SvelteComponentTyped<TextPropsICSectionProps, TextPropsICSectionEvents, TextPropsICSectionSlots> {
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FrameShape - A container shape extending Fabric.js Group
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Extends fabric.Group to act as a container for child objects
|
|
6
|
+
* - interactive: true — children can be selected/edited directly (tldraw-like)
|
|
7
|
+
* - Click on a child → selects that child for individual editing
|
|
8
|
+
* - Click on frame background → selects the frame itself
|
|
9
|
+
* - ClipPath for bounding/clipping content inside frame boundaries
|
|
10
|
+
* - Customizable label drawn above the frame (with text wrapping, rotation support)
|
|
11
|
+
* - Custom controls: corner resize only, no rotation handle
|
|
12
|
+
* - Minimum size enforcement
|
|
13
|
+
* - Serialization support with custom properties
|
|
14
|
+
* - addObjectToFrame / removeObjectFromFrame with automatic coordinate conversion
|
|
15
|
+
* (Fabric's native _enterGroup/_exitGroup handles absolute ↔ group-relative transforms)
|
|
16
|
+
*
|
|
17
|
+
* Containment detection (drag in/out) is handled by Canvas.svelte's
|
|
18
|
+
* object:modified handler since it requires canvas-level access.
|
|
19
|
+
*/
|
|
20
|
+
import { Group, Rect, type FabricObject, type Canvas as FabricCanvas } from 'fabric';
|
|
21
|
+
export declare const MIN_FRAME_WIDTH = 50;
|
|
22
|
+
export declare const MIN_FRAME_HEIGHT = 30;
|
|
23
|
+
export declare const DEFAULT_STROKE = "#2563eb";
|
|
24
|
+
export declare const FRAME_HOVER_STROKE = "#1d4ed8";
|
|
25
|
+
export interface FrameShapeOptions {
|
|
26
|
+
left?: number;
|
|
27
|
+
top?: number;
|
|
28
|
+
width?: number;
|
|
29
|
+
height?: number;
|
|
30
|
+
fill?: string;
|
|
31
|
+
stroke?: string;
|
|
32
|
+
strokeWidth?: number;
|
|
33
|
+
labelText?: string;
|
|
34
|
+
labelFontSize?: number;
|
|
35
|
+
labelFontFamily?: string;
|
|
36
|
+
labelColor?: string;
|
|
37
|
+
labelBackgroundColor?: string;
|
|
38
|
+
labelTextAlign?: 'left' | 'center' | 'right';
|
|
39
|
+
labelFontWeight?: string;
|
|
40
|
+
labelFontStyle?: string;
|
|
41
|
+
labelUnderline?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare class FrameShape extends Group {
|
|
44
|
+
static type: string;
|
|
45
|
+
/**
|
|
46
|
+
* Serialise the frame with type = 'FrameShape' plus all custom label/style
|
|
47
|
+
* props so they survive a canvas.toJSON() → loadFromJSON() round-trip.
|
|
48
|
+
* FRAME_CUSTOM_PROPS and _objectId are always included regardless of what
|
|
49
|
+
* the canvas passes as propertiesToInclude.
|
|
50
|
+
*/
|
|
51
|
+
toObject(propertiesToInclude?: any[]): any;
|
|
52
|
+
/**
|
|
53
|
+
* Deserialise a saved FrameShape.
|
|
54
|
+
* Delegates to Group.fromObject (handles enlivenObjects, FixedLayout setup,
|
|
55
|
+
* and subscribeTargets) then upgrades the plain Group to a proper FrameShape
|
|
56
|
+
* instance via Object.setPrototypeOf before re-applying the custom render.
|
|
57
|
+
*
|
|
58
|
+
* WHY setPrototypeOf:
|
|
59
|
+
* Group.fromObject always returns `new Group(...)` whose prototype is Group.prototype.
|
|
60
|
+
* After setPrototypeOf → FrameShape.prototype, the instance:
|
|
61
|
+
* • reports type === 'FrameShape' (via FrameShape.prototype.type)
|
|
62
|
+
* • calls FrameShape.prototype.toObject() on save → emits type:'FrameShape' + custom props
|
|
63
|
+
* • classRegistry dispatches FrameShape.fromObject on next reload
|
|
64
|
+
*/
|
|
65
|
+
static fromObject(object: any, options?: any): Promise<FrameShape>;
|
|
66
|
+
}
|
|
67
|
+
export declare function createFrameShape(options?: FrameShapeOptions): Group;
|
|
68
|
+
export declare function setupClipPath(frame: Group): void;
|
|
69
|
+
export declare function updateClipPath(frame: Group): void;
|
|
70
|
+
export declare function updateFrameCornerRadius(frame: Group, radiusPixels: number): void;
|
|
71
|
+
export declare function addObjectToFrame(frame: Group, object: FabricObject, canvas: FabricCanvas): void;
|
|
72
|
+
export declare function removeObjectFromFrame(frame: Group, object: FabricObject, canvas: FabricCanvas): void;
|
|
73
|
+
export declare function isPointInFrameLabel(frame: Group, point: {
|
|
74
|
+
x: number;
|
|
75
|
+
y: number;
|
|
76
|
+
}): boolean;
|
|
77
|
+
export declare function isPointInsideFrame(frame: Group, point: {
|
|
78
|
+
x: number;
|
|
79
|
+
y: number;
|
|
80
|
+
}): boolean;
|
|
81
|
+
export declare function isPointOnFrameBorder(frame: Group, point: {
|
|
82
|
+
x: number;
|
|
83
|
+
y: number;
|
|
84
|
+
}): boolean;
|
|
85
|
+
export declare function applyFrameHitTest(frame: Group): void;
|
|
86
|
+
export declare function getFrameChildren(frame: Group): FabricObject[];
|
|
87
|
+
export declare function getFrameBackground(frame: Group): Rect | null;
|
|
88
|
+
export declare function updateFrameBackground(frame: Group, props: {
|
|
89
|
+
fill?: string;
|
|
90
|
+
stroke?: string;
|
|
91
|
+
strokeWidth?: number;
|
|
92
|
+
}): void;
|
|
93
|
+
export declare function normalizeFrameAfterScaling(frame: Group, preserveChildren?: boolean): void;
|
|
94
|
+
export declare function enforceFrameMinSize(frame: Group): void;
|
|
95
|
+
export declare const FRAME_CUSTOM_PROPS: string[];
|
|
96
|
+
export declare function isFrameShape(obj: any): boolean;
|
|
97
|
+
export declare function reapplyFrameRender(frame: Group): void;
|