polotno 4.0.2 → 4.1.0
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/blueprint/side-panel/select-video.d.ts +2 -0
- package/canvas/audio.js +1 -1
- package/canvas/context-menu/context-menu.js +1 -1
- package/canvas/page.js +1 -1
- package/canvas/use-mediabunny-video.js +1 -1
- package/canvas/use-transformer-snap.js +1 -1
- package/canvas/video-element.js +1 -1
- package/model/audio-model.d.ts +2 -0
- package/model/audio-model.js +1 -1
- package/model/group-model.d.ts +1 -0
- package/model/page-model.d.ts +1 -0
- package/model/schema.d.ts +20 -253
- package/model/store.d.ts +12 -0
- package/model/store.js +1 -1
- package/model/video-model.d.ts +1 -0
- package/model/video-model.js +1 -1
- package/package.json +11 -10
- package/pages-timeline/audio-track.js +1 -1
- package/pages-timeline/pages-timeline.js +1 -1
- package/polotno.bundle.js +118 -118
- package/primitives/dropdown-menu.d.ts +1 -0
- package/primitives/dropdown-menu.js +1 -1
- package/primitives/floating-control.d.ts +1 -0
- package/primitives/floating-control.js +2 -0
- package/primitives/overflow-list.d.ts +2 -1
- package/primitives/overflow-list.js +1 -1
- package/primitives/separator.js +1 -1
- package/primitives/speed-control.d.ts +7 -0
- package/primitives/speed-control.js +1 -0
- package/side-panel/select-video.d.ts +2 -0
- package/side-panel/side-panel.js +1 -1
- package/side-panel/size-panel.js +1 -1
- package/side-panel/tab-button.js +1 -1
- package/toolbar/element-container.js +1 -1
- package/toolbar/figure-toolbar.js +1 -1
- package/toolbar/html-toolbar.js +2 -2
- package/toolbar/line-toolbar.js +1 -1
- package/toolbar/sketch.js +1 -1
- package/toolbar/svg-toolbar.js +1 -1
- package/toolbar/table-toolbar.js +1 -1
- package/toolbar/text-toolbar.js +1 -1
- package/toolbar/video-toolbar.js +1 -1
- package/toolbar/zoom-buttons.js +1 -1
- package/ui.css +1 -1
- package/utils/l10n.d.ts +2 -0
- package/utils/l10n.js +1 -1
- package/utils/text-format-state.d.ts +1 -0
- package/utils/text-format-state.js +1 -1
- package/utils/timeline.d.ts +11 -0
- package/utils/timeline.js +1 -0
- package/utils/validate-key.js +1 -1
package/model/schema.d.ts
CHANGED
|
@@ -1,253 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
export interface Audio {
|
|
23
|
-
id: string;
|
|
24
|
-
src: string;
|
|
25
|
-
duration: number;
|
|
26
|
-
startTime: number;
|
|
27
|
-
endTime: number;
|
|
28
|
-
volume: number;
|
|
29
|
-
delay: number;
|
|
30
|
-
}
|
|
31
|
-
export interface Page {
|
|
32
|
-
id: string;
|
|
33
|
-
width: number | 'auto';
|
|
34
|
-
height: number | 'auto';
|
|
35
|
-
background: string;
|
|
36
|
-
bleed: number;
|
|
37
|
-
custom?: unknown;
|
|
38
|
-
duration: number;
|
|
39
|
-
children: Element[];
|
|
40
|
-
}
|
|
41
|
-
export type Element = TextElement | ImageElement | SVGElement | LineElement | VideoElement | FigureElement | GifElement | GroupElement | TableElement;
|
|
42
|
-
export interface Animation {
|
|
43
|
-
delay: number;
|
|
44
|
-
duration: number;
|
|
45
|
-
enabled: boolean;
|
|
46
|
-
type: 'enter' | 'exit' | 'loop';
|
|
47
|
-
name: string;
|
|
48
|
-
data: unknown;
|
|
49
|
-
}
|
|
50
|
-
interface ShapeAttributes {
|
|
51
|
-
id: string;
|
|
52
|
-
type: string;
|
|
53
|
-
name?: string;
|
|
54
|
-
custom?: unknown;
|
|
55
|
-
x: number;
|
|
56
|
-
y: number;
|
|
57
|
-
width: number;
|
|
58
|
-
height: number;
|
|
59
|
-
rotation: number;
|
|
60
|
-
opacity: number;
|
|
61
|
-
animations: Animation[];
|
|
62
|
-
blurEnabled: boolean;
|
|
63
|
-
blurRadius: number;
|
|
64
|
-
brightnessEnabled: boolean;
|
|
65
|
-
brightness: number;
|
|
66
|
-
sepiaEnabled: boolean;
|
|
67
|
-
grayscaleEnabled: boolean;
|
|
68
|
-
filters: Record<string, {
|
|
69
|
-
intensity: number;
|
|
70
|
-
}>;
|
|
71
|
-
shadowEnabled: boolean;
|
|
72
|
-
shadowBlur: number;
|
|
73
|
-
shadowOffsetX: number;
|
|
74
|
-
shadowOffsetY: number;
|
|
75
|
-
shadowColor: string;
|
|
76
|
-
shadowOpacity: number;
|
|
77
|
-
visible: boolean;
|
|
78
|
-
draggable: boolean;
|
|
79
|
-
resizable: boolean;
|
|
80
|
-
selectable: boolean;
|
|
81
|
-
contentEditable: boolean;
|
|
82
|
-
styleEditable: boolean;
|
|
83
|
-
alwaysOnTop: boolean;
|
|
84
|
-
showInExport: boolean;
|
|
85
|
-
}
|
|
86
|
-
export interface GroupElement {
|
|
87
|
-
id: string;
|
|
88
|
-
type: 'group';
|
|
89
|
-
name?: string;
|
|
90
|
-
custom?: unknown;
|
|
91
|
-
opacity?: number;
|
|
92
|
-
visible?: boolean;
|
|
93
|
-
selectable?: boolean;
|
|
94
|
-
removable?: boolean;
|
|
95
|
-
alwaysOnTop?: boolean;
|
|
96
|
-
showInExport?: boolean;
|
|
97
|
-
animations?: Animation[];
|
|
98
|
-
children: Element[];
|
|
99
|
-
}
|
|
100
|
-
export interface TextElement extends ShapeAttributes {
|
|
101
|
-
type: 'text';
|
|
102
|
-
text: string;
|
|
103
|
-
placeholder: string;
|
|
104
|
-
fontSize: number;
|
|
105
|
-
fontFamily: string;
|
|
106
|
-
fontStyle: string;
|
|
107
|
-
fontWeight: string;
|
|
108
|
-
textDecoration: string;
|
|
109
|
-
textTransform: string;
|
|
110
|
-
fill: string;
|
|
111
|
-
align: 'left' | 'center' | 'right' | 'justify';
|
|
112
|
-
height: number;
|
|
113
|
-
verticalAlign: string;
|
|
114
|
-
strokeWidth: number;
|
|
115
|
-
stroke: string;
|
|
116
|
-
lineHeight: number | string;
|
|
117
|
-
letterSpacing: number;
|
|
118
|
-
backgroundEnabled: boolean;
|
|
119
|
-
backgroundColor: string;
|
|
120
|
-
backgroundOpacity: number;
|
|
121
|
-
backgroundCornerRadius: number;
|
|
122
|
-
backgroundPadding: number;
|
|
123
|
-
curveEnabled: boolean;
|
|
124
|
-
curvePower: number;
|
|
125
|
-
}
|
|
126
|
-
interface BaseImageProps {
|
|
127
|
-
src: string;
|
|
128
|
-
cropX: number;
|
|
129
|
-
cropY: number;
|
|
130
|
-
cropWidth: number;
|
|
131
|
-
cropHeight: number;
|
|
132
|
-
cornerRadius: number;
|
|
133
|
-
flipX: boolean;
|
|
134
|
-
flipY: boolean;
|
|
135
|
-
clipSrc: string;
|
|
136
|
-
borderColor: string;
|
|
137
|
-
borderSize: number;
|
|
138
|
-
keepRatio: boolean;
|
|
139
|
-
stretchEnabled: boolean;
|
|
140
|
-
}
|
|
141
|
-
export interface ImageElement extends ShapeAttributes, BaseImageProps {
|
|
142
|
-
type: 'image';
|
|
143
|
-
}
|
|
144
|
-
export interface SVGElement extends ShapeAttributes {
|
|
145
|
-
type: 'svg';
|
|
146
|
-
src: string;
|
|
147
|
-
maskSrc: string;
|
|
148
|
-
cropX: number;
|
|
149
|
-
cropY: number;
|
|
150
|
-
cropWidth: number;
|
|
151
|
-
cropHeight: number;
|
|
152
|
-
keepRatio: boolean;
|
|
153
|
-
stretchEnabled: boolean;
|
|
154
|
-
flipX: boolean;
|
|
155
|
-
flipY: boolean;
|
|
156
|
-
borderColor: string;
|
|
157
|
-
borderSize: number;
|
|
158
|
-
cornerRadius: number;
|
|
159
|
-
colorsReplace: Record<string, string>;
|
|
160
|
-
}
|
|
161
|
-
export interface LineElement extends ShapeAttributes {
|
|
162
|
-
type: 'line';
|
|
163
|
-
color: string;
|
|
164
|
-
dash: number[];
|
|
165
|
-
startHead: string;
|
|
166
|
-
endHead: string;
|
|
167
|
-
}
|
|
168
|
-
export interface FigureElement extends ShapeAttributes {
|
|
169
|
-
type: 'figure';
|
|
170
|
-
subType: string;
|
|
171
|
-
fill: string;
|
|
172
|
-
dash: number[];
|
|
173
|
-
strokeWidth: number;
|
|
174
|
-
stroke: string;
|
|
175
|
-
cornerRadius: number;
|
|
176
|
-
}
|
|
177
|
-
export interface GifElement extends ShapeAttributes, BaseImageProps {
|
|
178
|
-
type: 'gif';
|
|
179
|
-
duration: number;
|
|
180
|
-
keepRatio: boolean;
|
|
181
|
-
}
|
|
182
|
-
export interface VideoElement extends ShapeAttributes, BaseImageProps {
|
|
183
|
-
type: 'video';
|
|
184
|
-
duration: number;
|
|
185
|
-
startTime: number;
|
|
186
|
-
endTime: number;
|
|
187
|
-
volume: number;
|
|
188
|
-
}
|
|
189
|
-
export interface BorderSide {
|
|
190
|
-
color?: string;
|
|
191
|
-
width?: number;
|
|
192
|
-
style?: 'solid' | 'dashed' | 'dotted' | 'none';
|
|
193
|
-
}
|
|
194
|
-
export interface CellBorders {
|
|
195
|
-
top?: BorderSide;
|
|
196
|
-
right?: BorderSide;
|
|
197
|
-
bottom?: BorderSide;
|
|
198
|
-
left?: BorderSide;
|
|
199
|
-
}
|
|
200
|
-
export interface TableCell {
|
|
201
|
-
id: string;
|
|
202
|
-
type: 'tablecell';
|
|
203
|
-
text?: string;
|
|
204
|
-
opacity?: number;
|
|
205
|
-
rowSpan?: number;
|
|
206
|
-
colSpan?: number;
|
|
207
|
-
mergedInto?: string;
|
|
208
|
-
name?: string;
|
|
209
|
-
custom?: unknown;
|
|
210
|
-
borders?: CellBorders;
|
|
211
|
-
fontSize?: number;
|
|
212
|
-
fontFamily?: string;
|
|
213
|
-
fontWeight?: string;
|
|
214
|
-
fontStyle?: string;
|
|
215
|
-
textDecoration?: string;
|
|
216
|
-
textTransform?: string;
|
|
217
|
-
fill?: string;
|
|
218
|
-
align?: string;
|
|
219
|
-
verticalAlign?: string;
|
|
220
|
-
lineHeight?: number | string;
|
|
221
|
-
letterSpacing?: number;
|
|
222
|
-
strokeWidth?: number;
|
|
223
|
-
stroke?: string;
|
|
224
|
-
cellBackground?: string;
|
|
225
|
-
cellPadding?: number;
|
|
226
|
-
}
|
|
227
|
-
export interface TableElement extends Omit<ShapeAttributes, 'blurEnabled' | 'blurRadius' | 'brightnessEnabled' | 'brightness' | 'sepiaEnabled' | 'grayscaleEnabled' | 'filters' | 'shadowEnabled' | 'shadowBlur' | 'shadowOffsetX' | 'shadowOffsetY' | 'shadowColor' | 'shadowOpacity'> {
|
|
228
|
-
type: 'table';
|
|
229
|
-
rows: number;
|
|
230
|
-
cols: number;
|
|
231
|
-
colWidths: number[];
|
|
232
|
-
rowHeights: number[];
|
|
233
|
-
cells: TableCell[];
|
|
234
|
-
borderColor: string;
|
|
235
|
-
borderWidth: number;
|
|
236
|
-
borderStyle: 'solid' | 'dashed' | 'dotted' | 'none';
|
|
237
|
-
fontSize: number;
|
|
238
|
-
fontFamily: string;
|
|
239
|
-
fontWeight: string;
|
|
240
|
-
fontStyle: string;
|
|
241
|
-
textDecoration: string;
|
|
242
|
-
textTransform: string;
|
|
243
|
-
fill: string;
|
|
244
|
-
align: string;
|
|
245
|
-
verticalAlign: string;
|
|
246
|
-
lineHeight: number | string;
|
|
247
|
-
letterSpacing: number;
|
|
248
|
-
strokeWidth: number;
|
|
249
|
-
stroke: string;
|
|
250
|
-
cellBackground: string;
|
|
251
|
-
cellPadding: number;
|
|
252
|
-
}
|
|
253
|
-
export {};
|
|
1
|
+
import type * as Schema from '@polotno/schema';
|
|
2
|
+
export type Store = Schema.Design;
|
|
3
|
+
export type FontStyleVariant = Schema.FontStyleVariant;
|
|
4
|
+
export type Font = Schema.Font;
|
|
5
|
+
export type Audio = Schema.Audio;
|
|
6
|
+
export type Page = Schema.Page;
|
|
7
|
+
export type Element = Schema.Element;
|
|
8
|
+
export type Animation = Schema.Animation;
|
|
9
|
+
export type GroupElement = Schema.GroupElement;
|
|
10
|
+
export type TextElement = Schema.TextElement;
|
|
11
|
+
export type ImageElement = Schema.ImageElement;
|
|
12
|
+
export type SVGElement = Schema.SVGElement;
|
|
13
|
+
export type LineElement = Schema.LineElement;
|
|
14
|
+
export type FigureElement = Schema.FigureElement;
|
|
15
|
+
export type GifElement = Schema.GifElement;
|
|
16
|
+
export type VideoElement = Schema.VideoElement;
|
|
17
|
+
export type BorderSide = Schema.BorderSide;
|
|
18
|
+
export type CellBorders = Schema.CellBorders;
|
|
19
|
+
export type TableCell = Schema.TableCell;
|
|
20
|
+
export type TableElement = Schema.TableElement;
|
package/model/store.d.ts
CHANGED
|
@@ -801,6 +801,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
801
801
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
802
802
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
803
803
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
804
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
804
805
|
}, {
|
|
805
806
|
readonly page: any;
|
|
806
807
|
readonly store: any;
|
|
@@ -1969,6 +1970,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
1969
1970
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
1970
1971
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
1971
1972
|
delay: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
1973
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
1972
1974
|
custom: import("mobx-state-tree").IType<any, any, any>;
|
|
1973
1975
|
}, {
|
|
1974
1976
|
readonly visibleDuration: number;
|
|
@@ -1981,6 +1983,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
1981
1983
|
endTime: number;
|
|
1982
1984
|
volume: number;
|
|
1983
1985
|
delay: number;
|
|
1986
|
+
speed: number;
|
|
1984
1987
|
custom: any;
|
|
1985
1988
|
};
|
|
1986
1989
|
} & {
|
|
@@ -2792,6 +2795,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
2792
2795
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
2793
2796
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
2794
2797
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
2798
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
2795
2799
|
}, {
|
|
2796
2800
|
readonly page: any;
|
|
2797
2801
|
readonly store: any;
|
|
@@ -4697,6 +4701,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
4697
4701
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
4698
4702
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
4699
4703
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
4704
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
4700
4705
|
}, {
|
|
4701
4706
|
readonly page: any;
|
|
4702
4707
|
readonly store: any;
|
|
@@ -6890,6 +6895,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
6890
6895
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
6891
6896
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
6892
6897
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
6898
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
6893
6899
|
}, {
|
|
6894
6900
|
readonly page: any;
|
|
6895
6901
|
readonly store: any;
|
|
@@ -8795,6 +8801,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
8795
8801
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
8796
8802
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
8797
8803
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
8804
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
8798
8805
|
}, {
|
|
8799
8806
|
readonly page: any;
|
|
8800
8807
|
readonly store: any;
|
|
@@ -10701,6 +10708,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
10701
10708
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
10702
10709
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
10703
10710
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
10711
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
10704
10712
|
}, {
|
|
10705
10713
|
readonly page: any;
|
|
10706
10714
|
readonly store: any;
|
|
@@ -12606,6 +12614,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
12606
12614
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
12607
12615
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
12608
12616
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
12617
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
12609
12618
|
}, {
|
|
12610
12619
|
readonly page: any;
|
|
12611
12620
|
readonly store: any;
|
|
@@ -14544,6 +14553,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
14544
14553
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
14545
14554
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
14546
14555
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
14556
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
14547
14557
|
}, {
|
|
14548
14558
|
readonly page: any;
|
|
14549
14559
|
readonly store: any;
|
|
@@ -16449,6 +16459,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
16449
16459
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
16450
16460
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
16451
16461
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
16462
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
16452
16463
|
}, {
|
|
16453
16464
|
readonly page: any;
|
|
16454
16465
|
readonly store: any;
|
|
@@ -17675,6 +17686,7 @@ export declare const Store: import("mobx-state-tree").IModelType<{
|
|
|
17675
17686
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
17676
17687
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
17677
17688
|
delay: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
17689
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
17678
17690
|
custom: import("mobx-state-tree").IType<any, any, any>;
|
|
17679
17691
|
}>[];
|
|
17680
17692
|
unit: UnitType;
|
package/model/store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__rest||function(e,t){var i={};for(var o in e){Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(i[o]=e[o])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++){t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(i[o[n]]=e[o[n]])}}return i};import{applySnapshot as t,cast as i,destroy as o,detach as n,getSnapshot as a,onSnapshot as s,setLivelinessChecking as r,types as l}from"mobx-state-tree";import{UndoManager as d}from"./history.js";import{nanoid as c}from"nanoid";import p from"konva";import{computed as g}from"mobx";import{downloadFile as m}from"../utils/download.js";import{getJsPDF as u}from"../utils/pdf.js";import{createGIF as f}from"../utils/gif-lib.js";import{validateKey as h,setKey as b}from"../utils/validate-key.js";import*as y from"../utils/fonts.js";import{flags as v}from"../utils/flags.js";import{addDpiMetadataToImage as P}from"../utils/image-dpi.js";import{nodeToCanvas as w}from"../utils/canvas.js";import{whenLoaded as E}from"../utils/loader.js";import{pxToUnit as x}from"../utils/unit.js";import{deepEqual as I}from"../utils/deep-equal.js";import{waitTillAvailable as _}from"../utils/wait.js";import{jsonToHTML as k}from"../utils/to-html.js";import{jsonToSVG as S}from"../utils/to-svg.js";import{Page as T}from"./page-model.js";import{forEveryChild as O,forEveryNode as j}from"./group-model.js";import{Audio as R}from"./audio-model.js";r("ignore");export const Font=l.model("Font",{fontFamily:l.string,url:l.optional(l.string,""),styles:l.frozen()}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}));export const ROLES={ADMIN:"admin",VIEWER:"viewer"};export const Store=l.model("Store",{role:"",pages:l.array(T),fonts:l.array(Font),audios:l.array(R),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:l.optional(l.enumeration("UnitType",["pt","mm","cm","in","px"]),"px"),dpi:72,schemaVersion:3,bleedVisible:!1,rulesVisible:!1,distanceGuidesVisible:!1,openedSidePanel:"",previousOpenedSidePanel:"",custom:l.frozen(),tool:l.optional(l.enumeration("Tool",["selection","draw","pan","text","eraser"]),"selection"),toolOptions:l.optional(l.model({brushType:l.optional(l.enumeration("BrushType",["brush","highlighter"]),"brush"),strokeWidth:l.optional(l.number,5),stroke:l.optional(l.string,"#000000"),opacity:l.optional(l.number,1)}),{}),selectedElementsIds:l.array(l.string),animatedElementsIds:l.array(l.string),history:l.optional(d,{targetPath:"../pages"}),_elementsPixelRatio:Math.min(2,"undefined"!=typeof window&&window.devicePixelRatio||1),_activePageId:"",_selectedPagesIds:l.array(l.string),_forceShowCredit:!1,_validated:!1}).views(e=>{const t=g(()=>{const t={};return j({children:e.pages},e=>(t[e.id]=e,!1)),t},{keepAlive:!0});return{get _idsMap(){return t.get()}}}).views(e=>({get _bleedVisible(){return console.warn("store._bleedVisible is deprecated. Please use store.bleedVisible instead."),e.bleedVisible},get selectedElements(){return e.selectedElementsIds.map(t=>e._idsMap[t]).filter(e=>!!e)},get children(){return e.pages},get selectedShapes(){const e=[];return O({children:this.selectedElements},t=>{"group"!==t.type&&e.push(t)}),e},get activePage(){return e.pages.slice().find(t=>t.id===e._activePageId)||(e.pages.length?e.pages[0]:null)},get selectedPages(){return e._selectedPagesIds.map(t=>e.pages.find(e=>e.id===t))},get duration(){let t=0;return e.pages.forEach(e=>{t+=e.duration}),t},get _hasCroppedImages(){return this.find(e=>"image"===e.type&&e._cropModeEnabled)},find(t){let i;return j({children:e.pages},e=>{if(!i&&t(e)){return i=e,!0}}),i},getElementById:t=>e._idsMap[t]})).actions(r=>{let l=0,d=null,g=!1;const b={afterCreate(){r.history.canUndo},setCurrentTime(e){r.currentTime=e},_togglePlaying(e=!r.isPlaying){r.isPlaying=e},play({animatedElementsIds:e=[],startTime:t=0,currentTime:o=0,endTime:n=r.duration,repeat:a=!1}={}){o&&(console.warn("currentTime property of store.play() is deprecated. Please use startTime instead."),t=o),r.animatedElementsIds=i(e),r.currentTime=t,r.isPlaying=!0,l=Date.now(),d=n,g=a,requestAnimationFrame(()=>b.seek())},checkActivePage(){let e=0;for(const t of r.pages){if(r.currentTime>=t.startTime&&r.currentTime<t.startTime+t.duration){b.selectPage(t.id);break}e+=t.duration}},seek(){if(!r.isPlaying){return}const e=Date.now(),t=e-l;l=e,r.currentTime+=t,b.checkActivePage();const i=d||r.duration;r.isPlaying&&r.currentTime<i?requestAnimationFrame(()=>b.seek()):r.isPlaying&&g?(r.currentTime=0,requestAnimationFrame(()=>b.seek())):b.stop()},stop(){r.isPlaying=!1,r.currentTime=0,r.animatedElementsIds=i([]),b.checkActivePage()},__(){r._validated||(h(r._forceShowCredit),r._validated=!0)},set(e){Object.assign(r,e)},setUnit({unit:e,dpi:t}){r.unit=e||r.unit,r.dpi=t||r.dpi},setRole(e){r.role=e},setTool(e){r.tool=e},setToolOptions(e){Object.assign(r.toolOptions,e)},addPage(e){const t=T.create(Object.assign({id:c(10)},e));return r.pages.push(t),r._activePageId=t.id,t},selectPage(e){r._activePageId=e,1===r._selectedPagesIds.length&&(r._selectedPagesIds=i([e]))},selectPages(e){r._selectedPagesIds=i(e),1===r._selectedPagesIds.length&&(r._activePageId=r._selectedPagesIds[0])},selectElements(e){const t=e.map(e=>r.getElementById(e)).filter(e=>!!e);t.sort((e,t)=>{var i,o,n,a;return(null!==(o=null===(i=e.parent)||void 0===i?void 0:i.children.indexOf(e))&&void 0!==o?o:0)-(null!==(a=null===(n=t.parent)||void 0===n?void 0:n.children.indexOf(t))&&void 0!==a?a:0)}),r.selectedElementsIds=i(t.map(e=>e.id))},toggleBleed(e){r.bleedVisible=null!=e?e:!r.bleedVisible},toggleRulers(e){r.rulesVisible=null!=e?e:!r.rulesVisible},toggleDistanceGuides(e){r.distanceGuidesVisible=null!=e?e:!r.distanceGuidesVisible},openSidePanel(e){r.openedSidePanel!==e&&(r.previousOpenedSidePanel=r.openedSidePanel,r.openedSidePanel=e)},restoreSidePanel(){const e=r.previousOpenedSidePanel;e&&e!==r.openedSidePanel?r.openedSidePanel=e:r.openedSidePanel="photos"},setScale(e){r.scale=e},_setScaleToFit(e){r.scaleToFit=e},setElementsPixelRatio(e){r._elementsPixelRatio=e},setSize(e,t,i){r.pages.forEach(o=>{o.setSize({width:e,height:t,useMagic:i,softChange:!0})}),r.width=e,r.height=t},setPageZIndex(e,t){const i=r.pages.find(t=>t.id===e);i&&(n(i),r.pages.remove(i),r.pages.splice(t,0,i))},deletePages(e){const t=r.pages.indexOf(r.activePage);e.forEach(e=>{const t=r.pages.find(t=>t.id===e);o(t)});const n=Math.min(r.pages.length-1,t),a=r.pages[n];a&&(r._activePageId=a.id),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},groupElements(e,t={}){const o=e.map(e=>r.getElementById(e)).filter(e=>!!e);if(!o.length){return}const a=o[0].parent;if(!a){return}if(!o.every(e=>e.parent===a)){return void console.warn("store.groupElements: refusing to group elements that do not share a parent. Pass ids whose elements all live under the same page or the same group.")}o.forEach(e=>n(e));const s=a.children.reduce((e,t)=>{var i;if("group"===t.type){const o=null===(i=t.name)||void 0===i?void 0:i.match(/group-(\d+)/);if(o){const t=parseInt(o[1],10);return Math.max(e,t)}}return e},0),l=Object.assign({id:c(10),name:`group-${s+1}`,children:o,type:"group"},t);return a.children.push(l),r.selectedElementsIds=i([l.id]),a.children.find(e=>e.id===l.id)},ungroupElements(e){const t=e.map(e=>r.getElementById(e)),o=[];t.forEach(e=>{if(e&&"group"===e.type){const t=e.parent;if(!t){return}const i=t.children.indexOf(e);e.children.forEach(e=>{o.push(e.id)}),e.children.slice().forEach(e=>{n(e),t.children.push(e)}),t.children.splice(i,1)}}),r.selectedElementsIds=i(o)},deleteElements(e){const t=[];r.find(i=>(e.includes(i.id)&&t.push(i),!1)),t.forEach(e=>{o(e)}),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},on(e,t){if("change"===e){let e=b.toJSON();return s(r,i=>{const o=b.toJSON();!I(e,o)&&(e=o,t(o))})}},async _toCanvas({pixelRatio:e,ignoreBackground:t,pageId:i,mimeType:o,includeBleed:n,_skipTimeout:a,quickMode:s=!1,_exportCanvases:l}={}){var d;const c=e||1;i=i||(null===(d=r.pages[0])||void 0===d?void 0:d.id);const g=r.pages.find(e=>e.id===i);if(!g){throw new Error(`No page for export with id ${i}`)}const m=r._elementsPixelRatio;c>r._elementsPixelRatio&&b.setElementsPixelRatio(c),s?null==g||g.set({_forceMount:!0}):null==g||g.set({_exporting:!0});const u=await _(()=>{const e=p.stages.filter(e=>e.getAttr("pageId")===i);return 0===e.length?null:e});if(!u){throw null==g||g.set({_forceMount:!1,_exporting:!1}),b.setElementsPixelRatio(m),new Error(`Export is failed. Can not find stage for page ${i}. Looks like <Workspace /> component is not mounted, but it is required in order to process the export.`)}u.length>1&&console.error(`Polotno error: Detected several canvas elements for page "${i}" in the document. This is not supported and will lead to incorrect export. Make sure to use unique ids for all pages and make sure you unmount <Workspace /> when it is not needed.`);const f=u[0];await b.waitLoading({_skipTimeout:a});const h=f.findOne(".page-container");if(!h){throw b.setElementsPixelRatio(m),null==g||g.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const y=f.position();f.position({x:0,y:0}),f.find("Transformer").forEach(e=>{e.setAttr("oldVisible",e.visible()),e.visible(!1)}),h.find(".page-background").forEach(e=>e.shadowEnabled(!1)),h.find(".page-background").forEach(e=>e.strokeEnabled(!1)),h.find(".highlighter").forEach(e=>e.visible(!1));const v=h.findOne(".page-background-group"),P=v.clip();v.clip({x:null,y:null,width:null,height:null});const E=h.findOne(".elements-container"),x=E.clip();E.clip({x:null,y:null,width:null,height:null});const I=h.find(e=>!e.visible()&&e.getAttr("editModeEnabled")&&!e.getAttr("hideInExport"));I.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()});const k=h.find(e=>e.getAttr("hideInExport"));k.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()}),t&&h.find(".page-background").forEach(e=>e.hide());const S=n?g.bleed:0;let T=S;!r.bleedVisible&&n||(r.bleedVisible||n?r.bleedVisible&&n?T=0:r.bleedVisible&&!n&&(T=-g.bleed):T=0);const O=g.computedWidth+2*S,j=g.computedHeight+2*S,R=h.scale();h.scale({x:1,y:1});const F=w(h,{x:h.x()-T,y:h.y()-T,width:O,height:j,pixelRatio:c,sceneCanvas:null==l?void 0:l.sceneCanvas,bufferCanvas:null==l?void 0:l.bufferCanvas});h.scale(R);const C=F._canvas;if("image/jpeg"===o){const e=C.getContext("2d");e.save(),e.globalCompositeOperation="destination-over",e.fillStyle="white",e.fillRect(0,0,C.width,C.height),e.restore()}return t&&h.find(".page-background").forEach(e=>e.show()),k.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),I.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),h.find(".page-background").forEach(e=>e.shadowEnabled(!0)),h.find(".page-background").forEach(e=>e.strokeEnabled(!0)),f.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),h.find(".highlighter").forEach(e=>e.visible(!0)),v.clip(P),E.clip(x),f.position(y),null==g||g.set({_exporting:!1,_forceMount:!1}),await Promise.resolve(),b.setElementsPixelRatio(m),C},async toDataURL(t={}){var{mimeType:i,quality:o,dpi:n,dpiMetadata:a="auto"}=t,s=e(t,["mimeType","quality","dpi","dpiMetadata"]);const l=await b._toCanvas(Object.assign({mimeType:i},s)),d=i||"image/png",c=l.toDataURL(d,o);p.Util.releaseCanvas(l);const g=null!=n?n:r.dpi;return"image/png"!==d&&"image/jpeg"!==d||"never"===a||"auto"===a&&72===g?c:P(c,d,g)},async toBlob(t={}){var{mimeType:i,quality:o}=t,n=e(t,["mimeType","quality"]);const a=await b._toCanvas(Object.assign({mimeType:i},n)),s=await new Promise(e=>{a.toBlob(e,i,o)});return p.Util.releaseCanvas(a),s},async saveAsImage(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=(o.mimeType||"image/png").split("/")[1];m(await b.toDataURL(o),i||"polotno."+n)},async _toPDF(e){const t=e.dpi||r.dpi,i=e.parallel||1,o=e.unit||("px"===r.unit?"mm":r.unit),n=e.pixelRatio||1,a=e.pageIds||(e.pageId?[e.pageId]:r.pages.map(e=>e.id)),s=r.pages.filter(e=>a.includes(e.id)),l=await u(),d=e=>x({px:e,unit:o,dpi:t}),c=e.cropMarkSize||0,p=d(c),g=s[0]||{},m=e.includeBleed?g.bleed:0,f=d(g.computedWidth+2*m+2*p),h=d(g.computedHeight+2*m+2*p);var y=new l({unit:o,orientation:f>h?"landscape":"portrait",format:[f,h],compress:!0,putOnlyUsedFonts:!0});y.deletePage(1);const v=((e,t)=>{const i=[];for(let o=0;o<e.length;o+=t){i.push(e.slice(o,o+t))}return i})(s,i);let P=0;for(const r of v){const t=r.map(async t=>{const i=e.includeBleed?t.bleed:0,o=t.computedWidth+2*i+2*c,s=t.computedHeight+2*i+2*c,r=d(o),l=d(s);let p=0,g=n;for(;p<10;){p+=1;const i=await b.toDataURL(Object.assign(Object.assign({},e),{pageId:t.id,pixelRatio:g,dpiMetadata:"never"}));if(i.length>20){return g!==n&&console.error(`Polotno can not export PDF with current settings. Quality is automatically reduced. pixelRatio was reduced to ${parseFloat(g.toFixed(3))}.`),e.onProgress&&e.onProgress(++P/a.length*.9),{url:i,width:r,height:l,widthPx:o,heightPx:s}}g*=.8}});(await Promise.all(t)).filter(e=>void 0!==e).forEach(({url:e,width:t,height:i,widthPx:n,heightPx:a})=>{y.addPage([t,i],t>i?"landscape":"portrait");const s=y.getCurrentPageInfo();var r;switch(o){case"pt":r=1;break;case"mm":r=72/25.4;break;case"cm":r=72/2.54;break;case"in":r=72;break;case"px":r=.75;break;default:throw"Invalid unit: "+o}if(s.pageContext.cropBox={bottomLeftX:0,bottomLeftY:0,topRightX:t*r,topRightY:i*r},s.pageContext.artBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(n-c-m)*r,topRightY:d(a-c-m)*r},s.pageContext.bleedBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(n-c-m)*r,topRightY:d(a-c-m)*r},p){y.setLineWidth(d(1));const e=p+d(m);y.line(e,0,e,p),y.line(0,e,p,e),y.line(t-e,0,t-e,p),y.line(t,e,t-p,e),y.line(0,i-e,p,i-e),y.line(e,i,e,i-p),y.line(t,i-e,t-p,i-e),y.line(t-e,i,t-e,i-p)}y.addImage(e,p,p,t-2*p,i-2*p,void 0,"FAST")})}return y},toPDFDataURL:async e=>(await b._toPDF(Object.assign({mimeType:"image/jpeg"},e))).output("datauristring"),async toGIFDataURL(e={}){const t=e.pixelRatio||1,i=e.pageIds||(e.pageId?[e.pageId]:r.pages.map(e=>e.id)),o=r.pages.filter(e=>i.includes(e.id));if(!o.length){throw new Error("No pages found for GIF export")}const n=o[0],a=await f({width:n.computedWidth*t,height:n.computedHeight*t}),s=1e3/(e.fps||10);for(const l of o){const e=Math.max(1,Math.floor(l.duration/s));for(let i=0;i<e;i++){const e=l.startTime+i*s||1;b.setCurrentTime(e);for(const t of r.pages){t.set({_rendering:t.id===l.id})}const o=await b._toCanvas({pixelRatio:t,pageId:l.id,_skipTimeout:!0});a.addFrame(o.getContext("2d"),{delay:s,copy:!0})}}for(const l of r.pages){l.set({_rendering:!1})}return b.stop(),a.render(),new Promise(e=>{a.on("finished",function(t){!function(e,t){var i=new FileReader;i.onload=function(e){t(e.target.result)},i.readAsDataURL(e)}(t,e)})})},async saveAsGIF(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=await b.toGIFDataURL(o);m(n,i||"polotno.gif")},async toHTML({elementHook:e}={}){const t=b.toJSON();return k({json:t,elementHook:e})},async saveAsHTML({fileName:e,elementHook:t}={}){const i=await b.toHTML({elementHook:t}),o="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));m(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:t,fontEmbedding:i="inline"}={fontEmbedding:"inline"}){var o;const n=b.toJSON();t=t||(null===(o=n.pages[0])||void 0===o?void 0:o.id);const a=n.pages.find(e=>e.id===t);return S({json:Object.assign(Object.assign({},n),{pages:a?[a]:[]}),elementHook:e,fontEmbedding:i})},async saveAsSVG({fileName:e,elementHook:t,pageId:i,fontEmbedding:o="inline"}={}){const n=await b.toSVG({elementHook:t,pageId:i,fontEmbedding:o}),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(n)));m(a,e||"polotno.svg")},async saveAsPDF(t={}){var{fileName:i}=t,o=e(t,["fileName"]);(await b._toPDF(Object.assign({mimeType:"image/jpeg"},o))).save(i||"polotno.pdf")},async waitLoading({_skipTimeout:e=!1}={}){e||await new Promise(e=>setTimeout(e,50)),await E()},toJSON:()=>({width:r.width,height:r.height,fonts:a(r.fonts),pages:a(r.pages),audios:a(r.audios),unit:r.unit,dpi:r.dpi,custom:r.custom,schemaVersion:r.schemaVersion}),loadJSON(e,i=!1){var o,n,s;const l="boolean"==typeof i?i:null!==(o=null==i?void 0:i.keepHistory)&&void 0!==o&&o,d="boolean"!=typeof i&&null!==(n=null==i?void 0:i.modernizeTextBackground)&&void 0!==n&&n,c=JSON.parse(JSON.stringify(e)),p=c.schemaVersion||0;p<1&&(v.htmlRenderEnabled||v.renderTagTextEnabled)&&j({children:c.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),p<2&&j({children:c.pages},e=>{e.filters&&Object.keys(e.filters).forEach(t=>{if(["warm","cold","natural"].includes(t)){return}const i=e.filters[t];i&&"number"==typeof i.intensity&&(i.intensity=i.intensity/100)})}),p<3&&(v.htmlRenderEnabled||v.renderTagTextEnabled)&&!d&&j({children:c.pages},e=>{"text"===e.type&&e.backgroundEnabled&&(e.legacyBackground=!0)}),delete c.schemaVersion;const g=r.activePage?r.pages.indexOf(r.activePage):0;let m=null===(s=c.pages[g]||c.pages[0])||void 0===s?void 0:s.id;c._activePageId=m;const u=Object.assign({},a(r));Object.assign(u,c),u.history=l?a(r.history):{history:[],undoIdx:-1,targetPath:""},t(r,u)},clear({keepHistory:e=!1}={}){const t=r.pages.map(e=>e.id);b.deletePages(t),r.custom=null,e||r.history.clear()},addFont(e){b.removeFont(e.fontFamily),r.fonts.push(e)},removeFont(e){r.fonts.filter(t=>t.fontFamily===e).forEach(e=>o(e))},addAudio(e){const t=R.create(Object.assign({id:c(10)},e));r.audios.push(t)},removeAudio(e){const t=r.audios.find(t=>t.id===e);t&&r.audios.remove(t)},async loadFont(e,t,i,o){const n=r.fonts.find(t=>t.fontFamily===e)||y.globalFonts.find(t=>t.fontFamily===e);let a=[{fontStyle:"normal",fontWeight:"normal"},{fontStyle:"normal",fontWeight:"bold"}];return n?(n.styles&&(a=n.styles.map(e=>({fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"normal"}))),y.injectCustomFont(n)):y.injectGoogleFont(e),t&&i&&!a.some(e=>e.fontStyle===t&&e.fontWeight===i)&&a.push({fontStyle:t,fontWeight:i}),Promise.all(a.map(t=>y.loadFont(e,t.fontStyle,t.fontWeight,o)))},validate:e=>Store.validate(e,[{path:"",type:Store}]).map(e=>({path:"store"+e.context.map(e=>e.path).join("."),message:e.message}))};return b});export function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){return b(e),Store.create({_forceShowCredit:t})}export default createStore;
|
|
1
|
+
var e=this&&this.__rest||function(e,t){var i={};for(var o in e){Object.prototype.hasOwnProperty.call(e,o)&&t.indexOf(o)<0&&(i[o]=e[o])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(o=Object.getOwnPropertySymbols(e);n<o.length;n++){t.indexOf(o[n])<0&&Object.prototype.propertyIsEnumerable.call(e,o[n])&&(i[o[n]]=e[o[n]])}}return i};import{applySnapshot as t,cast as i,destroy as o,detach as n,getSnapshot as a,onSnapshot as s,setLivelinessChecking as r,types as l}from"mobx-state-tree";import{UndoManager as d}from"./history.js";import{nanoid as c}from"nanoid";import p from"konva";import{computed as g}from"mobx";import{downloadFile as m}from"../utils/download.js";import{getJsPDF as u}from"../utils/pdf.js";import{createGIF as f}from"../utils/gif-lib.js";import{validateKey as h,setKey as b}from"../utils/validate-key.js";import*as y from"../utils/fonts.js";import{flags as v}from"../utils/flags.js";import{addDpiMetadataToImage as P}from"../utils/image-dpi.js";import{nodeToCanvas as w}from"../utils/canvas.js";import{whenLoaded as E}from"../utils/loader.js";import{pxToUnit as x}from"../utils/unit.js";import{deepEqual as I}from"../utils/deep-equal.js";import{waitTillAvailable as _}from"../utils/wait.js";import{jsonToHTML as k}from"../utils/to-html.js";import{jsonToSVG as S}from"../utils/to-svg.js";import{Page as T}from"./page-model.js";import{forEveryChild as O,forEveryNode as j}from"./group-model.js";import{Audio as R}from"./audio-model.js";r("ignore");export const Font=l.model("Font",{fontFamily:l.string,url:l.optional(l.string,""),styles:l.frozen()}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontFamily:e.fontFamily||e.name}));export const ROLES={ADMIN:"admin",VIEWER:"viewer"};export const Store=l.model("Store",{role:"",pages:l.array(T),fonts:l.array(Font),audios:l.array(R),width:1080,height:1080,currentTime:0,isPlaying:!1,scale:1,scaleToFit:1,unit:l.optional(l.enumeration("UnitType",["pt","mm","cm","in","px"]),"px"),dpi:72,schemaVersion:4,bleedVisible:!1,rulesVisible:!1,distanceGuidesVisible:!1,openedSidePanel:"",previousOpenedSidePanel:"",custom:l.frozen(),tool:l.optional(l.enumeration("Tool",["selection","draw","pan","text","eraser"]),"selection"),toolOptions:l.optional(l.model({brushType:l.optional(l.enumeration("BrushType",["brush","highlighter"]),"brush"),strokeWidth:l.optional(l.number,5),stroke:l.optional(l.string,"#000000"),opacity:l.optional(l.number,1)}),{}),selectedElementsIds:l.array(l.string),animatedElementsIds:l.array(l.string),history:l.optional(d,{targetPath:"../pages"}),_elementsPixelRatio:Math.min(2,"undefined"!=typeof window&&window.devicePixelRatio||1),_activePageId:"",_selectedPagesIds:l.array(l.string),_forceShowCredit:!1,_validated:!1}).views(e=>{const t=g(()=>{const t={};return j({children:e.pages},e=>(t[e.id]=e,!1)),t},{keepAlive:!0});return{get _idsMap(){return t.get()}}}).views(e=>({get _bleedVisible(){return console.warn("store._bleedVisible is deprecated. Please use store.bleedVisible instead."),e.bleedVisible},get selectedElements(){return e.selectedElementsIds.map(t=>e._idsMap[t]).filter(e=>!!e)},get children(){return e.pages},get selectedShapes(){const e=[];return O({children:this.selectedElements},t=>{"group"!==t.type&&e.push(t)}),e},get activePage(){return e.pages.slice().find(t=>t.id===e._activePageId)||(e.pages.length?e.pages[0]:null)},get selectedPages(){return e._selectedPagesIds.map(t=>e.pages.find(e=>e.id===t))},get duration(){let t=0;return e.pages.forEach(e=>{t+=e.duration}),t},get _hasCroppedImages(){return this.find(e=>"image"===e.type&&e._cropModeEnabled)},find(t){let i;return j({children:e.pages},e=>{if(!i&&t(e)){return i=e,!0}}),i},getElementById:t=>e._idsMap[t]})).actions(r=>{let l=0,d=null,g=!1;const b={afterCreate(){r.history.canUndo},setCurrentTime(e){r.currentTime=e},_togglePlaying(e=!r.isPlaying){r.isPlaying=e},play({animatedElementsIds:e=[],startTime:t=0,currentTime:o=0,endTime:n=r.duration,repeat:a=!1}={}){o&&(console.warn("currentTime property of store.play() is deprecated. Please use startTime instead."),t=o),r.animatedElementsIds=i(e),r.currentTime=t,r.isPlaying=!0,l=Date.now(),d=n,g=a,requestAnimationFrame(()=>b.seek())},checkActivePage(){let e=0;for(const t of r.pages){if(r.currentTime>=t.startTime&&r.currentTime<t.startTime+t.duration){b.selectPage(t.id);break}e+=t.duration}},seek(){if(!r.isPlaying){return}const e=Date.now(),t=e-l;l=e,r.currentTime+=t,b.checkActivePage();const i=d||r.duration;r.isPlaying&&r.currentTime<i?requestAnimationFrame(()=>b.seek()):r.isPlaying&&g?(r.currentTime=0,requestAnimationFrame(()=>b.seek())):b.stop()},stop(){r.isPlaying=!1,r.currentTime=0,r.animatedElementsIds=i([]),b.checkActivePage()},__(){r._validated||(h(r._forceShowCredit),r._validated=!0)},set(e){Object.assign(r,e)},setUnit({unit:e,dpi:t}){r.unit=e||r.unit,r.dpi=t||r.dpi},setRole(e){r.role=e},setTool(e){r.tool=e},setToolOptions(e){Object.assign(r.toolOptions,e)},addPage(e){const t=T.create(Object.assign({id:c(10)},e));return r.pages.push(t),r._activePageId=t.id,t},selectPage(e){r._activePageId=e,1===r._selectedPagesIds.length&&(r._selectedPagesIds=i([e]))},selectPages(e){r._selectedPagesIds=i(e),1===r._selectedPagesIds.length&&(r._activePageId=r._selectedPagesIds[0])},selectElements(e){const t=e.map(e=>r.getElementById(e)).filter(e=>!!e);t.sort((e,t)=>{var i,o,n,a;return(null!==(o=null===(i=e.parent)||void 0===i?void 0:i.children.indexOf(e))&&void 0!==o?o:0)-(null!==(a=null===(n=t.parent)||void 0===n?void 0:n.children.indexOf(t))&&void 0!==a?a:0)}),r.selectedElementsIds=i(t.map(e=>e.id))},toggleBleed(e){r.bleedVisible=null!=e?e:!r.bleedVisible},toggleRulers(e){r.rulesVisible=null!=e?e:!r.rulesVisible},toggleDistanceGuides(e){r.distanceGuidesVisible=null!=e?e:!r.distanceGuidesVisible},openSidePanel(e){r.openedSidePanel!==e&&(r.previousOpenedSidePanel=r.openedSidePanel,r.openedSidePanel=e)},restoreSidePanel(){const e=r.previousOpenedSidePanel;e&&e!==r.openedSidePanel?r.openedSidePanel=e:r.openedSidePanel="photos"},setScale(e){r.scale=e},_setScaleToFit(e){r.scaleToFit=e},setElementsPixelRatio(e){r._elementsPixelRatio=e},setSize(e,t,i){r.pages.forEach(o=>{o.setSize({width:e,height:t,useMagic:i,softChange:!0})}),r.width=e,r.height=t},setPageZIndex(e,t){const i=r.pages.find(t=>t.id===e);i&&(n(i),r.pages.remove(i),r.pages.splice(t,0,i))},deletePages(e){const t=r.pages.indexOf(r.activePage);e.forEach(e=>{const t=r.pages.find(t=>t.id===e);o(t)});const n=Math.min(r.pages.length-1,t),a=r.pages[n];a&&(r._activePageId=a.id),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},groupElements(e,t={}){const o=e.map(e=>r.getElementById(e)).filter(e=>!!e);if(!o.length){return}const a=o[0].parent;if(!a){return}if(!o.every(e=>e.parent===a)){return void console.warn("store.groupElements: refusing to group elements that do not share a parent. Pass ids whose elements all live under the same page or the same group.")}o.forEach(e=>n(e));const s=a.children.reduce((e,t)=>{var i;if("group"===t.type){const o=null===(i=t.name)||void 0===i?void 0:i.match(/group-(\d+)/);if(o){const t=parseInt(o[1],10);return Math.max(e,t)}}return e},0),l=Object.assign({id:c(10),name:`group-${s+1}`,children:o,type:"group"},t);return a.children.push(l),r.selectedElementsIds=i([l.id]),a.children.find(e=>e.id===l.id)},ungroupElements(e){const t=e.map(e=>r.getElementById(e)),o=[];t.forEach(e=>{if(e&&"group"===e.type){const t=e.parent;if(!t){return}const i=t.children.indexOf(e);e.children.forEach(e=>{o.push(e.id)}),e.children.slice().forEach(e=>{n(e),t.children.push(e)}),t.children.splice(i,1)}}),r.selectedElementsIds=i(o)},deleteElements(e){const t=[];r.find(i=>(e.includes(i.id)&&t.push(i),!1)),t.forEach(e=>{o(e)}),r.selectedElementsIds=i(r.selectedElementsIds.filter(e=>r.getElementById(e)))},on(e,t){if("change"===e){let e=b.toJSON();return s(r,i=>{const o=b.toJSON();!I(e,o)&&(e=o,t(o))})}},async _toCanvas({pixelRatio:e,ignoreBackground:t,pageId:i,mimeType:o,includeBleed:n,_skipTimeout:a,quickMode:s=!1,_exportCanvases:l}={}){var d;const c=e||1;i=i||(null===(d=r.pages[0])||void 0===d?void 0:d.id);const g=r.pages.find(e=>e.id===i);if(!g){throw new Error(`No page for export with id ${i}`)}const m=r._elementsPixelRatio;c>r._elementsPixelRatio&&b.setElementsPixelRatio(c),s?null==g||g.set({_forceMount:!0}):null==g||g.set({_exporting:!0});const u=await _(()=>{const e=p.stages.filter(e=>e.getAttr("pageId")===i);return 0===e.length?null:e});if(!u){throw null==g||g.set({_forceMount:!1,_exporting:!1}),b.setElementsPixelRatio(m),new Error(`Export is failed. Can not find stage for page ${i}. Looks like <Workspace /> component is not mounted, but it is required in order to process the export.`)}u.length>1&&console.error(`Polotno error: Detected several canvas elements for page "${i}" in the document. This is not supported and will lead to incorrect export. Make sure to use unique ids for all pages and make sure you unmount <Workspace /> when it is not needed.`);const f=u[0];await b.waitLoading({_skipTimeout:a});const h=f.findOne(".page-container");if(!h){throw b.setElementsPixelRatio(m),null==g||g.set({_forceMount:!1,_exporting:!1}),new Error("Export is failed. Canvas was unmounted.")}const y=f.position();f.position({x:0,y:0}),f.find("Transformer").forEach(e=>{e.setAttr("oldVisible",e.visible()),e.visible(!1)}),h.find(".page-background").forEach(e=>e.shadowEnabled(!1)),h.find(".page-background").forEach(e=>e.strokeEnabled(!1)),h.find(".highlighter").forEach(e=>e.visible(!1));const v=h.findOne(".page-background-group"),P=v.clip();v.clip({x:null,y:null,width:null,height:null});const E=h.findOne(".elements-container"),x=E.clip();E.clip({x:null,y:null,width:null,height:null});const I=h.find(e=>!e.visible()&&e.getAttr("editModeEnabled")&&!e.getAttr("hideInExport"));I.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.show()});const k=h.find(e=>e.getAttr("hideInExport"));k.forEach(e=>{e.setAttr("oldVisible",e.visible()),e.hide()}),t&&h.find(".page-background").forEach(e=>e.hide());const S=n?g.bleed:0;let T=S;!r.bleedVisible&&n||(r.bleedVisible||n?r.bleedVisible&&n?T=0:r.bleedVisible&&!n&&(T=-g.bleed):T=0);const O=g.computedWidth+2*S,j=g.computedHeight+2*S,R=h.scale();h.scale({x:1,y:1});const F=w(h,{x:h.x()-T,y:h.y()-T,width:O,height:j,pixelRatio:c,sceneCanvas:null==l?void 0:l.sceneCanvas,bufferCanvas:null==l?void 0:l.bufferCanvas});h.scale(R);const C=F._canvas;if("image/jpeg"===o){const e=C.getContext("2d");e.save(),e.globalCompositeOperation="destination-over",e.fillStyle="white",e.fillRect(0,0,C.width,C.height),e.restore()}return t&&h.find(".page-background").forEach(e=>e.show()),k.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),I.forEach(e=>{e.visible(e.getAttr("oldVisible"))}),h.find(".page-background").forEach(e=>e.shadowEnabled(!0)),h.find(".page-background").forEach(e=>e.strokeEnabled(!0)),f.find("Transformer").forEach(e=>{e.visible(e.getAttr("oldVisible"))}),h.find(".highlighter").forEach(e=>e.visible(!0)),v.clip(P),E.clip(x),f.position(y),null==g||g.set({_exporting:!1,_forceMount:!1}),await Promise.resolve(),b.setElementsPixelRatio(m),C},async toDataURL(t={}){var{mimeType:i,quality:o,dpi:n,dpiMetadata:a="auto"}=t,s=e(t,["mimeType","quality","dpi","dpiMetadata"]);const l=await b._toCanvas(Object.assign({mimeType:i},s)),d=i||"image/png",c=l.toDataURL(d,o);p.Util.releaseCanvas(l);const g=null!=n?n:r.dpi;return"image/png"!==d&&"image/jpeg"!==d||"never"===a||"auto"===a&&72===g?c:P(c,d,g)},async toBlob(t={}){var{mimeType:i,quality:o}=t,n=e(t,["mimeType","quality"]);const a=await b._toCanvas(Object.assign({mimeType:i},n)),s=await new Promise(e=>{a.toBlob(e,i,o)});return p.Util.releaseCanvas(a),s},async saveAsImage(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=(o.mimeType||"image/png").split("/")[1];m(await b.toDataURL(o),i||"polotno."+n)},async _toPDF(e){const t=e.dpi||r.dpi,i=e.parallel||1,o=e.unit||("px"===r.unit?"mm":r.unit),n=e.pixelRatio||1,a=e.pageIds||(e.pageId?[e.pageId]:r.pages.map(e=>e.id)),s=r.pages.filter(e=>a.includes(e.id)),l=await u(),d=e=>x({px:e,unit:o,dpi:t}),c=e.cropMarkSize||0,p=d(c),g=s[0]||{},m=e.includeBleed?g.bleed:0,f=d(g.computedWidth+2*m+2*p),h=d(g.computedHeight+2*m+2*p);var y=new l({unit:o,orientation:f>h?"landscape":"portrait",format:[f,h],compress:!0,putOnlyUsedFonts:!0});y.deletePage(1);const v=((e,t)=>{const i=[];for(let o=0;o<e.length;o+=t){i.push(e.slice(o,o+t))}return i})(s,i);let P=0;for(const r of v){const t=r.map(async t=>{const i=e.includeBleed?t.bleed:0,o=t.computedWidth+2*i+2*c,s=t.computedHeight+2*i+2*c,r=d(o),l=d(s);let p=0,g=n;for(;p<10;){p+=1;const i=await b.toDataURL(Object.assign(Object.assign({},e),{pageId:t.id,pixelRatio:g,dpiMetadata:"never"}));if(i.length>20){return g!==n&&console.error(`Polotno can not export PDF with current settings. Quality is automatically reduced. pixelRatio was reduced to ${parseFloat(g.toFixed(3))}.`),e.onProgress&&e.onProgress(++P/a.length*.9),{url:i,width:r,height:l,widthPx:o,heightPx:s}}g*=.8}});(await Promise.all(t)).filter(e=>void 0!==e).forEach(({url:e,width:t,height:i,widthPx:n,heightPx:a})=>{y.addPage([t,i],t>i?"landscape":"portrait");const s=y.getCurrentPageInfo();var r;switch(o){case"pt":r=1;break;case"mm":r=72/25.4;break;case"cm":r=72/2.54;break;case"in":r=72;break;case"px":r=.75;break;default:throw"Invalid unit: "+o}if(s.pageContext.cropBox={bottomLeftX:0,bottomLeftY:0,topRightX:t*r,topRightY:i*r},s.pageContext.artBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(n-c-m)*r,topRightY:d(a-c-m)*r},s.pageContext.bleedBox={bottomLeftX:d(c+m)*r,bottomLeftY:d(c+m)*r,topRightX:d(n-c-m)*r,topRightY:d(a-c-m)*r},p){y.setLineWidth(d(1));const e=p+d(m);y.line(e,0,e,p),y.line(0,e,p,e),y.line(t-e,0,t-e,p),y.line(t,e,t-p,e),y.line(0,i-e,p,i-e),y.line(e,i,e,i-p),y.line(t,i-e,t-p,i-e),y.line(t-e,i,t-e,i-p)}y.addImage(e,p,p,t-2*p,i-2*p,void 0,"FAST")})}return y},toPDFDataURL:async e=>(await b._toPDF(Object.assign({mimeType:"image/jpeg"},e))).output("datauristring"),async toGIFDataURL(e={}){const t=e.pixelRatio||1,i=e.pageIds||(e.pageId?[e.pageId]:r.pages.map(e=>e.id)),o=r.pages.filter(e=>i.includes(e.id));if(!o.length){throw new Error("No pages found for GIF export")}const n=o[0],a=await f({width:n.computedWidth*t,height:n.computedHeight*t}),s=1e3/(e.fps||10);for(const l of o){const e=Math.max(1,Math.floor(l.duration/s));for(let i=0;i<e;i++){const e=l.startTime+i*s||1;b.setCurrentTime(e);for(const t of r.pages){t.set({_rendering:t.id===l.id})}const o=await b._toCanvas({pixelRatio:t,pageId:l.id,_skipTimeout:!0});a.addFrame(o.getContext("2d"),{delay:s,copy:!0})}}for(const l of r.pages){l.set({_rendering:!1})}return b.stop(),a.render(),new Promise(e=>{a.on("finished",function(t){!function(e,t){var i=new FileReader;i.onload=function(e){t(e.target.result)},i.readAsDataURL(e)}(t,e)})})},async saveAsGIF(t={}){var{fileName:i}=t,o=e(t,["fileName"]);const n=await b.toGIFDataURL(o);m(n,i||"polotno.gif")},async toHTML({elementHook:e}={}){const t=b.toJSON();return k({json:t,elementHook:e})},async saveAsHTML({fileName:e,elementHook:t}={}){const i=await b.toHTML({elementHook:t}),o="data:text/html;base64,"+window.btoa(unescape(encodeURIComponent(i)));m(o,e||"polotno.html")},async toSVG({elementHook:e,pageId:t,fontEmbedding:i="inline"}={fontEmbedding:"inline"}){var o;const n=b.toJSON();t=t||(null===(o=n.pages[0])||void 0===o?void 0:o.id);const a=n.pages.find(e=>e.id===t);return S({json:Object.assign(Object.assign({},n),{pages:a?[a]:[]}),elementHook:e,fontEmbedding:i})},async saveAsSVG({fileName:e,elementHook:t,pageId:i,fontEmbedding:o="inline"}={}){const n=await b.toSVG({elementHook:t,pageId:i,fontEmbedding:o}),a="data:text/svg;base64,"+window.btoa(unescape(encodeURIComponent(n)));m(a,e||"polotno.svg")},async saveAsPDF(t={}){var{fileName:i}=t,o=e(t,["fileName"]);(await b._toPDF(Object.assign({mimeType:"image/jpeg"},o))).save(i||"polotno.pdf")},async waitLoading({_skipTimeout:e=!1}={}){e||await new Promise(e=>setTimeout(e,50)),await E()},toJSON:()=>({width:r.width,height:r.height,fonts:a(r.fonts),pages:a(r.pages),audios:a(r.audios),unit:r.unit,dpi:r.dpi,custom:r.custom,schemaVersion:r.schemaVersion}),loadJSON(e,i=!1){var o,n,s;const l="boolean"==typeof i?i:null!==(o=null==i?void 0:i.keepHistory)&&void 0!==o&&o,d="boolean"!=typeof i&&null!==(n=null==i?void 0:i.modernizeTextBackground)&&void 0!==n&&n,c=JSON.parse(JSON.stringify(e)),p=c.schemaVersion||0;p<1&&(v.htmlRenderEnabled||v.renderTagTextEnabled)&&j({children:c.pages},e=>{if("text"===e.type){const t=16,i=e.letterSpacing*t;e.letterSpacing=i/e.fontSize}}),p<2&&j({children:c.pages},e=>{e.filters&&Object.keys(e.filters).forEach(t=>{if(["warm","cold","natural"].includes(t)){return}const i=e.filters[t];i&&"number"==typeof i.intensity&&(i.intensity=i.intensity/100)})}),p<3&&(v.htmlRenderEnabled||v.renderTagTextEnabled)&&!d&&j({children:c.pages},e=>{"text"===e.type&&e.backgroundEnabled&&(e.legacyBackground=!0)}),delete c.schemaVersion;const g=r.activePage?r.pages.indexOf(r.activePage):0;let m=null===(s=c.pages[g]||c.pages[0])||void 0===s?void 0:s.id;c._activePageId=m;const u=Object.assign({},a(r));Object.assign(u,c),u.history=l?a(r.history):{history:[],undoIdx:-1,targetPath:""},t(r,u)},clear({keepHistory:e=!1}={}){const t=r.pages.map(e=>e.id);b.deletePages(t),r.custom=null,e||r.history.clear()},addFont(e){b.removeFont(e.fontFamily),r.fonts.push(e)},removeFont(e){r.fonts.filter(t=>t.fontFamily===e).forEach(e=>o(e))},addAudio(e){const t=R.create(Object.assign({id:c(10)},e));r.audios.push(t)},removeAudio(e){const t=r.audios.find(t=>t.id===e);t&&r.audios.remove(t)},async loadFont(e,t,i,o){const n=r.fonts.find(t=>t.fontFamily===e)||y.globalFonts.find(t=>t.fontFamily===e);let a=[{fontStyle:"normal",fontWeight:"normal"},{fontStyle:"normal",fontWeight:"bold"}];return n?(n.styles&&(a=n.styles.map(e=>({fontStyle:e.fontStyle||"normal",fontWeight:e.fontWeight||"normal"}))),y.injectCustomFont(n)):y.injectGoogleFont(e),t&&i&&!a.some(e=>e.fontStyle===t&&e.fontWeight===i)&&a.push({fontStyle:t,fontWeight:i}),Promise.all(a.map(t=>y.loadFont(e,t.fontStyle,t.fontWeight,o)))},validate:e=>Store.validate(e,[{path:"",type:Store}]).map(e=>({path:"store"+e.context.map(e=>e.path).join("."),message:e.message}))};return b});export function createStore({key:e,showCredit:t}={key:"",showCredit:!1}){return b(e),Store.create({_forceShowCredit:t})}export default createStore;
|
package/model/video-model.d.ts
CHANGED
|
@@ -71,6 +71,7 @@ export declare const VideoElement: import("mobx-state-tree").IModelType<{
|
|
|
71
71
|
startTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
72
72
|
endTime: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
73
73
|
volume: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
74
|
+
speed: import("mobx-state-tree").IType<number | undefined, number, number>;
|
|
74
75
|
}, {
|
|
75
76
|
readonly page: any;
|
|
76
77
|
readonly store: any;
|
package/model/video-model.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ImageElement as e}from"./image-model.js";export const VideoElement=e.named("Video").props({type:"video",duration:0,startTime:0,endTime:1,volume:1});
|
|
1
|
+
import{ImageElement as e}from"./image-model.js";export const VideoElement=e.named("Video").props({type:"video",duration:0,startTime:0,endTime:1,volume:1,speed:1});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polotno",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Design Editor Framework",
|
|
5
5
|
"author": "Anton Lavrenov",
|
|
6
6
|
"keywords": [
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
97
|
"@base-ui/react": "^1.5.0",
|
|
98
|
+
"@polotno/schema": "0.1.0",
|
|
98
99
|
"class-variance-authority": "^0.7.1",
|
|
99
100
|
"clsx": "^2.1.1",
|
|
100
101
|
"gifuct-js": "^2.1.2",
|
|
@@ -102,7 +103,7 @@
|
|
|
102
103
|
"konva": "^10.3.0",
|
|
103
104
|
"lodash-es": "^4.18.1",
|
|
104
105
|
"lucide-react": "^1.18.0",
|
|
105
|
-
"mediabunny": "^1.
|
|
106
|
+
"mediabunny": "^1.47.0",
|
|
106
107
|
"mensch": "^0.3.4",
|
|
107
108
|
"mobx": "6.16.1",
|
|
108
109
|
"mobx-react-lite": "^4.1.1",
|
|
@@ -192,18 +193,19 @@
|
|
|
192
193
|
"jsdom": "^29.1.1",
|
|
193
194
|
"license-checker": "^25.0.1",
|
|
194
195
|
"playwright": "^1.60.0",
|
|
196
|
+
"postcss": "^8.5.15",
|
|
195
197
|
"postcss-selector-parser": "^7.1.4",
|
|
196
198
|
"pptxgenjs": "^4.0.1",
|
|
197
199
|
"process": "^0.11.10",
|
|
198
200
|
"react": "^19.2.7",
|
|
199
201
|
"react-dom": "^19.2.7",
|
|
200
202
|
"size-limit": "^12.1.0",
|
|
201
|
-
"skia-canvas": "^3.0.8",
|
|
202
203
|
"tailwindcss": "^4.3.1",
|
|
203
204
|
"terser": "^5.48.0",
|
|
204
205
|
"tw-animate-css": "^1.4.0",
|
|
205
|
-
"typescript": "
|
|
206
|
-
"
|
|
206
|
+
"typescript": "~6.0.3",
|
|
207
|
+
"vite": "^8.0.16",
|
|
208
|
+
"vitest": "^4.1.9"
|
|
207
209
|
},
|
|
208
210
|
"homepage": "https://polotno.com/",
|
|
209
211
|
"scripts": {
|
|
@@ -216,15 +218,14 @@
|
|
|
216
218
|
"check:css": "node build/check-css-hygiene.cjs ./lib/ui.css",
|
|
217
219
|
"check:agreement": "node build/check-agreement.cjs ./lib/ui.css ./lib/toolbar ./lib/side-panel ./lib/pages-timeline ./lib/primitives ./lib/canvas",
|
|
218
220
|
"check:parity": "node build/structural-parity.cjs",
|
|
219
|
-
"test:parity": "
|
|
221
|
+
"test:parity": "pnpm run check:parity && pnpm run check:agreement && pnpm run check:css",
|
|
220
222
|
"minify": "node minify.cjs",
|
|
221
|
-
"build
|
|
222
|
-
"build": "npm run typecheck && npm run clean && npm run prefix-build && npm run tsc && npm run add_version && node rename-imports.js && npm run minify && npm run build:css && npm run check:css && npm run check:agreement && npm run build:bundle && node blueprint-scope.js && cp ./src/fonts.css ./lib/fonts.css && mkdir -p ./lib/themes && cp ./src/themes/blueprint.css ./lib/themes/blueprint.css && cp ./package.json ./lib && cp ./README.md ./lib && cp ./LICENSE.md ./lib && npm run remove-test-from-lib && npm run build:schema",
|
|
223
|
+
"build": "pnpm run typecheck && pnpm run clean && pnpm run prefix-build && pnpm run tsc && pnpm run add_version && node rename-imports.js && pnpm run minify && pnpm run build:css && pnpm run check:css && pnpm run check:agreement && pnpm run build:bundle && node blueprint-scope.js && cp ./src/fonts.css ./lib/fonts.css && mkdir -p ./lib/themes && cp ./src/themes/blueprint.css ./lib/themes/blueprint.css && node build/copy-package-json.cjs && cp ./README.md ./lib && cp ./LICENSE.md ./lib && pnpm run remove-test-from-lib",
|
|
223
224
|
"remove-test-from-lib": "find ./lib -type d -name \"__tests__\" -exec rm -rf {} + && find ./lib \\( -name \"*.test.js\" -o -name \"*.test.d.ts\" \\) -type f -delete",
|
|
224
225
|
"add_version": "sed -i.bak 's/SDK_VERSION/'$npm_package_version'/' ./lib/utils/validate-key.js && rm -f ./lib/utils/validate-key.js.bak",
|
|
225
226
|
"build:bundle": "vite build && find ./lib -name '*.js.map' -type f -delete",
|
|
226
|
-
"size": "
|
|
227
|
-
"test": "vitest"
|
|
227
|
+
"size": "pnpm run build && size-limit",
|
|
228
|
+
"test": "vitest run"
|
|
228
229
|
},
|
|
229
230
|
"license": "SEE LICENSE IN LICENSE.md"
|
|
230
231
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=this&&this.__rest||function(e,t){var n={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++){t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]])}}return n};import{jsx as t,jsxs as n}from"react/jsx-runtime";import i from"react";import{observer as o}from"mobx-react-lite";import{PolotnoIcon as s}from"../icons/registry.js";import{t as a}from"../utils/l10n.js";import{firstSliderValue as r}from"../lib/utils.js";import{DropdownMenu as l,DropdownMenuContent as m,DropdownMenuItem as d,DropdownMenuSeparator as p}from"../primitives/dropdown-menu.js";import{Slider as c}from"../primitives/slider.js";import{
|
|
1
|
+
var e=this&&this.__rest||function(e,t){var n={};for(var i in e){Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(n[i]=e[i])}if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(i=Object.getOwnPropertySymbols(e);o<i.length;o++){t.indexOf(i[o])<0&&Object.prototype.propertyIsEnumerable.call(e,i[o])&&(n[i[o]]=e[i[o]])}}return n};import{jsx as t,jsxs as n}from"react/jsx-runtime";import i from"react";import{observer as o}from"mobx-react-lite";import{PolotnoIcon as s}from"../icons/registry.js";import{t as a}from"../utils/l10n.js";import{firstSliderValue as r}from"../lib/utils.js";import{DropdownMenu as l,DropdownMenuContent as m,DropdownMenuItem as d,DropdownMenuSeparator as p}from"../primitives/dropdown-menu.js";import{Slider as c}from"../primitives/slider.js";import{SpeedControl as u}from"../primitives/speed-control.js";import{Spinner as h}from"./spinner.js";import{useWaveformData as v,useWaveformPath as f}from"./waveform.js";import{TrackWrapper as x,TrackContainer as y,TrackMenu as g,TrackMenuButton as M,TrackHandleLeft as T,TrackHandleRight as w,WaveformSvg as b}from"./track-styles.js";export const AUDIO_ROW_HEIGHT=28;export const AUDIO_TRACK_HEIGHT=24;const j=({position:e,store:t,scale:n})=>{const i=t.pages;for(const o of i){const t=o.startTime,i=o.startTime+o.duration;if(Math.abs(e-t)<10/n){return t}if(Math.abs(e-i)<10/n){return i}}return null};export const AudioTrack=o(({audio:o,scale:I,store:O,index:D})=>{const[E,A]=i.useState(1),S=i.useRef(null),L=0===o.volume,N=()=>{L?o.set({volume:E>0?E:1}):(A(o.volume),o.set({volume:0}))},P=(e=o.startTime,t=o.endTime,n=o.speed)=>Math.max(0,(t-e)*(o.duration||0)/n),C=e=>Math.max(0,O.duration-e),_=(e,t=P())=>Math.min(Math.max(0,e),C(t)),z=P(),X=O.duration*I-o.delay*I,k=Math.min(z*I,X),H=o.delay*I,{data:R,isLoading:$}=v(o.src),B=o.visibleDuration*I,V=f(R,20).path,Y=(e,t)=>{e.stopPropagation(),e.preventDefault();const n=e.clientX,i=H,s=k,a=o.endTime,r=o.startTime,l=o.delay,m=o.duration||1,d=o.speed,p=e=>{e.preventDefault();const p=(e.clientX-n)/I;if("start"===t){if(p>=0){const e=p*d,t=Math.max(0,a-.1-r)*m,n=Math.min(e,t);if(n<=0){return}let i=r+n/m;const s=(o.endTime-i)*m/d,c=l+n/d,u=C(s);let h=Math.min(Math.max(0,c),u);const v=j({position:h,store:O,scale:I});h=Math.min(Math.max(0,null!=v?v:h),u);const f=h-c;i=Math.min(o.endTime-.1,Math.max(0,i+f*d/m)),o.set({delay:h,startTime:i})}else{const e=-p*d,t=r*m,n=Math.min(e,t);if(n<=0){return}const i=n/m;let s=Math.max(0,r-i);const a=(o.endTime-s)*m/d,c=l-n/d,u=C(a);let h=Math.min(Math.max(0,c),u);const v=j({position:h,store:O,scale:I});h=Math.min(Math.max(0,null!=v?v:h),u);const f=h-c;s=Math.max(0,Math.min(o.endTime-.1,s+f*d/m)),o.set({delay:h,startTime:s})}}else{const e=i/I+s/I;let t=e+p;const n=j({position:t,store:O,scale:I});t=null!=n?n:t;const r=(t-e)*d/o.duration,l=Math.min(1,Math.max(o.startTime+.1,a+r));o.set({endTime:l})}},c=()=>{if(window.removeEventListener("mousemove",p),window.removeEventListener("mouseup",c),"start"===t){const e=j({position:o.delay,store:O,scale:I});if(null!=e&&e!==o.delay){const t=P(o.startTime,o.endTime),n=_(e,t),i=n-o.delay,s=Math.max(0,Math.min(o.endTime-.1,o.startTime+i*d/m));o.set({delay:n,startTime:s})}}};window.addEventListener("mousemove",p),window.addEventListener("mouseup",c)};return t(x,{ref:S,style:{left:`${H}px`,top:28*D+"px",width:`${k}px`,height:"24px"},className:"polotno-audio-container",children:n(y,{style:{width:"100%",height:"100%"},onMouseDown:e=>{const t=e.clientX,n=H;e.preventDefault();const i=e=>{e.preventDefault();const i=(e.clientX-t)/I;let s=n/I+i;const a=s+z,r=j({position:s,store:O,scale:I}),l=j({position:a,store:O,scale:I}),m=null!==r?Math.abs(s-r):Number.POSITIVE_INFINITY,d=null!==l?Math.abs(a-l):Number.POSITIVE_INFINITY;let p;p=_(null!==r&&m<d?r:null!==l?l-z:s),o.set({delay:_(p)})},s=()=>{window.removeEventListener("mousemove",i),window.removeEventListener("mouseup",s)};window.addEventListener("mousemove",i),window.addEventListener("mouseup",s)},children:[t("div",{style:{position:"absolute",left:"4px",top:"50%",transform:"translateY(-50%)",zIndex:10,pointerEvents:"auto"},onClick:e=>{e.stopPropagation(),N()},onMouseDown:e=>e.stopPropagation(),children:t(s,L?{name:"action.muted",className:"pn:size-3.5",style:{opacity:.7,cursor:"pointer"}}:{name:"action.unmuted",className:"pn:size-3.5",style:{opacity:.7,cursor:"pointer"}})}),t("div",{style:{position:"absolute",inset:"0 0 0 0",display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:n("div",{style:{display:"flex",alignItems:"center",width:"100%",height:"100%",gap:"8px",paddingLeft:"22px"},children:[V&&t("div",{style:{flex:1,height:"14px",overflow:"hidden",opacity:L?.4:1},children:t(b,{width:B,height:"14",viewBox:`0 0 ${B} 20`,preserveAspectRatio:"none",style:{width:B+"px",height:"14px",transform:`translateX(-${o.startTime*B}px)`},children:t("path",{d:V})})}),$&&t("div",{style:{flex:1,display:"flex",justifyContent:"center",alignItems:"center"},children:t(h,{})})]})}),t(T,{onMouseDown:e=>Y(e,"start")}),t(w,{onMouseDown:e=>Y(e,"end")}),t(g,{onClick:e=>{e.stopPropagation()},onMouseDown:e=>e.stopPropagation(),children:n(l,{children:[t(M,{}),n(m,{side:"top",align:"start",anchor:S,style:{width:"220px"},children:[n("div",{style:{padding:"8px 12px"},children:[n("div",{style:{fontSize:"12px",marginBottom:"6px",display:"flex",justifyContent:"space-between",alignItems:"center"},children:[t("span",{children:a("pagesTimeline.volume")}),n("span",{children:[Math.round(100*o.volume),"%"]})]}),t(c,{value:[o.volume],min:0,max:1,step:.01,onValueChange:e=>(e=>{const t=Math.max(0,Math.min(1,e));t>0&&A(t),o.set({volume:t})})(r(e))})]}),n("div",{style:{padding:"8px 12px"},children:[t("div",{style:{fontSize:"12px",marginBottom:"6px"},children:a("pagesTimeline.speed")}),t(u,{value:o.speed,onChange:e=>{const t=P(o.startTime,o.endTime,e);o.set({speed:e,delay:_(o.delay,t)})}})]}),t(p,{}),n(d,{onSelect:e=>{e.preventDefault(),N()},children:[t(s,L?{name:"action.unmuted"}:{name:"action.muted"}),a(L?"pagesTimeline.unmuteAudio":"pagesTimeline.muteAudio")]}),n(d,{onSelect:t=>{t.preventDefault(),(()=>{const t=o.toJSON(),n=o.visibleDuration,i=o.delay+n,s=O.duration-i;let a=o.delay;s>=n?a=i:s>0&&(a=Math.max(0,O.duration-n));const{id:r}=t,l=e(t,["id"]);O.addAudio(Object.assign(Object.assign({},l),{delay:a}))})()},children:[t(s,{name:"action.duplicate"}),a("pagesTimeline.duplicateAudio")]}),t(p,{}),n(d,{onSelect:e=>{e.preventDefault(),O.removeAudio(o.id)},children:[t(s,{name:"action.remove"}),a("pagesTimeline.removeAudio")]})]})]})})]})})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t,Fragment as
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as i}from"react/jsx-runtime";import n from"react";import{observer as r}from"mobx-react-lite";import{PolotnoIcon as s}from"../icons/registry.js";import{flags as o}from"../utils/flags.js";import{t as a}from"../utils/l10n.js";import{cn as l}from"../lib/utils.js";import{Button as p}from"../primitives/button.js";import{floatingControl as m}from"../primitives/floating-control.js";import{Navbar as d}from"../primitives/navbar.js";import{Pages as c}from"./pages.js";import{CurrentTime as u}from"./current-time.js";import{Audios as h}from"./audios.js";import{ElementsTimeline as v}from"./elements.js";import{PlayButton as f}from"./play-button.js";import{TimeRuler as g}from"./time-ruler.js";export const PagesTimeline=r(({store:r,defaultOpened:b=!1})=>{const x=n.useRef(null),[w,y]=n.useState(b),[j,E]=n.useState(.02),[z,k]=n.useState(()=>(e=>{if(!o.animationsEnabled){return 65}const t=e.pages.reduce((e,t)=>e+t.children.length,0),i=25*e.audios.length+20*t+140;return Math.min(Math.max(i,140),420)})(r)),[L,C]=n.useState(!1),N=n.useRef(0),M=n.useRef(z),R=n.useRef(!1),S=r.duration*j,D=n.useCallback(e=>{if(!R.current){return}const t=e.clientY-N.current,i=M.current-t,n=Math.min(420,Math.max(140,i));k(n)},[]),P=n.useCallback(()=>{R.current&&(R.current=!1,C(!1),window.removeEventListener("mousemove",D),window.removeEventListener("mouseup",P))},[D]);return n.useEffect(()=>()=>{window.removeEventListener("mousemove",D),window.removeEventListener("mouseup",P)},[D,P]),t(i,{children:[e("div",{style:{position:"relative",height:"0px"},children:t(p,{variant:"ghost",size:"sm",onClick:()=>{y(!w)},className:l(m(),"pn:absolute pn:bottom-[5px] pn:left-[5px] pn:z-[1] pn:dark:hover:bg-accent"),children:[o.animationsEnabled&&!w?e(s,{name:"pagesTimeline.play",className:"pn:size-4"}):null,a("pagesTimeline.pages")]})}),t(d,{attached:"top",style:{padding:"5px",height:"auto",zIndex:1,position:"relative",overflow:"visible",display:w?"block":"none"},className:"polotno-pages-timeline pn:whitespace-normal pn:bg-background",children:[o.animationsEnabled&&e("div",{onMouseDown:e=>{e.preventDefault(),N.current=e.clientY,M.current=z,R.current=!0,C(!0),window.addEventListener("mousemove",D),window.addEventListener("mouseup",P)},className:"pn:group/pn-resize-handle pn:absolute pn:top-0 pn:left-0 pn:right-0 pn:flex pn:h-[14px] pn:-translate-y-1/2 pn:cursor-ns-resize pn:items-center pn:justify-center"+(L?" active":""),title:"Drag to adjust timeline height",children:e("div",{className:"pn:h-1 pn:w-full pn:rounded-[2px] pn:transition-colors pn:group-hover/pn-resize-handle:bg-primary"+(L?" pn:bg-primary":" pn:bg-transparent")})}),o.animationsEnabled&&e("div",{style:{display:"flex",justifyContent:"center"},children:e(f,{store:r,scale:j,onScaleChange:E})}),e("div",{dir:"ltr",style:{width:"100%",position:"relative",height:z},children:e("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,overflowX:"auto",padding:"0 24px"},ref:x,children:t("div",{style:{position:"relative",minWidth:o.animationsEnabled?S+"px":void 0},children:[o.animationsEnabled&&e(g,{store:r,scale:j,minWidth:S}),t("div",{style:{position:"relative",display:"flex"},children:[e("div",{style:{position:"relative",minWidth:o.animationsEnabled?S+"px":void 0,height:"60px"},children:e(c,{store:r,scale:j})}),e(p,{variant:"ghost",size:"icon",style:{width:"60px",height:"60px",marginLeft:"12px"},onClick:()=>{var e;r.addPage({bleed:(null===(e=r.activePage)||void 0===e?void 0:e.bleed)||0})},children:e(s,{name:"action.add",className:"pn:size-4"})})]}),o.animationsEnabled&&t(i,{children:[e(v,{store:r,scale:j,width:S}),e(h,{store:r,scale:j,width:S})]}),o.animationsEnabled&&e(u,{store:r,scale:j,dragAreaRef:x,variant:"timeline"})]})})})]})]})});
|