Sebastiankay
commited on
Commit
•
52ae39e
1
Parent(s):
e69040c
Upload 20 files
Browse files- js/align.js +371 -0
- js/converter.js +118 -0
- js/database.js +660 -0
- js/encode-worker.js +96 -0
- js/events.js +1022 -0
- js/functions.js +0 -0
- js/init.js +1075 -0
- js/libraries/anime.min.js +8 -0
- js/libraries/fabric.min.js +0 -0
- js/libraries/ffmpeg.min.js +2 -0
- js/libraries/jquery.nice-select.min.js +4 -0
- js/libraries/localbase.js +0 -0
- js/libraries/pickr.min.js +5 -0
- js/libraries/range-slider.min.js +10 -0
- js/libraries/sortable.min.js +2 -0
- js/lottie.js +39 -0
- js/recorder.js +362 -0
- js/text.js +269 -0
- js/ui.js +2369 -0
- js/webm-writer2.js +1165 -0
js/align.js
ADDED
@@ -0,0 +1,371 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Center line reference
|
2 |
+
function initLines() {
|
3 |
+
if (canvas.getItemById('center_h')) {
|
4 |
+
canvas.remove(canvas.getItemById('center_h'));
|
5 |
+
canvas.remove(canvas.getItemById('center_v'));
|
6 |
+
}
|
7 |
+
if (canvas.getItemById('line_h')) {
|
8 |
+
canvas.remove(canvas.getItemById('line_h'));
|
9 |
+
canvas.remove(canvas.getItemById('line_v'));
|
10 |
+
}
|
11 |
+
|
12 |
+
// Canvas center reference
|
13 |
+
canvas.add(
|
14 |
+
new fabric.Line(
|
15 |
+
[
|
16 |
+
canvas.get('width') / 2,
|
17 |
+
0,
|
18 |
+
canvas.get('width') / 2,
|
19 |
+
canvas.get('height'),
|
20 |
+
],
|
21 |
+
{
|
22 |
+
opacity: 0,
|
23 |
+
selectable: false,
|
24 |
+
evented: false,
|
25 |
+
id: 'center_h',
|
26 |
+
}
|
27 |
+
)
|
28 |
+
);
|
29 |
+
canvas.add(
|
30 |
+
new fabric.Line(
|
31 |
+
[
|
32 |
+
0,
|
33 |
+
canvas.get('height') / 2,
|
34 |
+
canvas.get('width'),
|
35 |
+
canvas.get('height') / 2,
|
36 |
+
],
|
37 |
+
{
|
38 |
+
opacity: 0,
|
39 |
+
selectable: false,
|
40 |
+
evented: false,
|
41 |
+
id: 'center_v',
|
42 |
+
}
|
43 |
+
)
|
44 |
+
);
|
45 |
+
|
46 |
+
// Canvas alignemnt guides
|
47 |
+
line_h = new fabric.Line(
|
48 |
+
[
|
49 |
+
canvas.get('width') / 2,
|
50 |
+
artboard.get('top'),
|
51 |
+
canvas.get('width') / 2,
|
52 |
+
artboard.get('height') + artboard.get('top'),
|
53 |
+
],
|
54 |
+
{
|
55 |
+
stroke: 'red',
|
56 |
+
opacity: 0,
|
57 |
+
selectable: false,
|
58 |
+
evented: false,
|
59 |
+
id: 'line_h',
|
60 |
+
}
|
61 |
+
);
|
62 |
+
line_v = new fabric.Line(
|
63 |
+
[
|
64 |
+
artboard.get('left'),
|
65 |
+
canvas.get('height') / 2,
|
66 |
+
artboard.get('width') + artboard.get('left'),
|
67 |
+
canvas.get('height') / 2,
|
68 |
+
],
|
69 |
+
{
|
70 |
+
stroke: 'red',
|
71 |
+
opacity: 0,
|
72 |
+
selectable: false,
|
73 |
+
evented: false,
|
74 |
+
id: 'line_v',
|
75 |
+
}
|
76 |
+
);
|
77 |
+
canvas.add(line_h);
|
78 |
+
canvas.add(line_v);
|
79 |
+
}
|
80 |
+
|
81 |
+
function alignControls(object, type) {
|
82 |
+
if (type == 'align-top') {
|
83 |
+
object.set(
|
84 |
+
'top',
|
85 |
+
artboard.get('top') +
|
86 |
+
(object.get('height') * object.get('scaleY')) / 2
|
87 |
+
);
|
88 |
+
} else if (type == 'align-center-v') {
|
89 |
+
object.set(
|
90 |
+
'top',
|
91 |
+
artboard.get('top') + artboard.get('height') / 2
|
92 |
+
);
|
93 |
+
} else if (type == 'align-bottom') {
|
94 |
+
object.set(
|
95 |
+
'top',
|
96 |
+
artboard.get('top') +
|
97 |
+
artboard.get('height') -
|
98 |
+
(object.get('height') * object.get('scaleY')) / 2
|
99 |
+
);
|
100 |
+
} else if (type == 'align-left') {
|
101 |
+
object.set(
|
102 |
+
'left',
|
103 |
+
artboard.get('left') +
|
104 |
+
(object.get('width') * object.get('scaleX')) / 2
|
105 |
+
);
|
106 |
+
} else if (type == 'align-center-h') {
|
107 |
+
object.set(
|
108 |
+
'left',
|
109 |
+
artboard.get('left') + artboard.get('width') / 2
|
110 |
+
);
|
111 |
+
} else {
|
112 |
+
object.set(
|
113 |
+
'left',
|
114 |
+
artboard.get('left') +
|
115 |
+
artboard.get('width') -
|
116 |
+
(object.get('width') * object.get('scaleX')) / 2
|
117 |
+
);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
// Align object
|
122 |
+
function alignObject() {
|
123 |
+
const type = $(this).attr('id');
|
124 |
+
const object = canvas.getActiveObject();
|
125 |
+
console.log(canvas.getActiveObject().type);
|
126 |
+
if (canvas.getActiveObject().type == 'activeSelection') {
|
127 |
+
const tempselection = canvas.getActiveObject();
|
128 |
+
canvas.discardActiveObject();
|
129 |
+
tempselection._objects.forEach(function (object) {
|
130 |
+
alignControls(object, type);
|
131 |
+
canvas.renderAll();
|
132 |
+
newKeyframe(
|
133 |
+
'left',
|
134 |
+
object,
|
135 |
+
currenttime,
|
136 |
+
object.get('left'),
|
137 |
+
true
|
138 |
+
);
|
139 |
+
newKeyframe(
|
140 |
+
'top',
|
141 |
+
object,
|
142 |
+
currenttime,
|
143 |
+
object.get('top'),
|
144 |
+
true
|
145 |
+
);
|
146 |
+
});
|
147 |
+
reselect(tempselection);
|
148 |
+
} else {
|
149 |
+
alignControls(object, type);
|
150 |
+
canvas.renderAll();
|
151 |
+
newKeyframe(
|
152 |
+
'left',
|
153 |
+
object,
|
154 |
+
currenttime,
|
155 |
+
object.get('left'),
|
156 |
+
true
|
157 |
+
);
|
158 |
+
newKeyframe('top', object, currenttime, object.get('top'), true);
|
159 |
+
}
|
160 |
+
}
|
161 |
+
$(document).on('click', '.align', alignObject);
|
162 |
+
|
163 |
+
// Alignment guides
|
164 |
+
function centerLines(e) {
|
165 |
+
if (!cropping) {
|
166 |
+
line_h.opacity = 0;
|
167 |
+
line_v.opacity = 0;
|
168 |
+
canvas.renderAll();
|
169 |
+
const snapZone = 5;
|
170 |
+
const obj_left = e.target.left;
|
171 |
+
const obj_top = e.target.top;
|
172 |
+
const obj_width = e.target.get('width') * e.target.get('scaleX');
|
173 |
+
const obj_height =
|
174 |
+
e.target.get('height') * e.target.get('scaleY');
|
175 |
+
canvas.forEachObject(function (obj, index, array) {
|
176 |
+
// Check for horizontal snapping
|
177 |
+
function checkHSnap(a, b, snapZone, e, type) {
|
178 |
+
if (a > b - snapZone && a < b + snapZone) {
|
179 |
+
line_h.opacity = 1;
|
180 |
+
line_h.bringToFront();
|
181 |
+
var value = b;
|
182 |
+
if (type == 1) {
|
183 |
+
value = b;
|
184 |
+
} else if (type == 2) {
|
185 |
+
value =
|
186 |
+
b -
|
187 |
+
(e.target.get('width') * e.target.get('scaleX')) / 2;
|
188 |
+
} else if (type == 3) {
|
189 |
+
value =
|
190 |
+
b +
|
191 |
+
(e.target.get('width') * e.target.get('scaleX')) / 2;
|
192 |
+
}
|
193 |
+
e.target
|
194 |
+
.set({
|
195 |
+
left: value,
|
196 |
+
})
|
197 |
+
.setCoords();
|
198 |
+
line_h
|
199 |
+
.set({
|
200 |
+
x1: b,
|
201 |
+
y1: artboard.get('top'),
|
202 |
+
x2: b,
|
203 |
+
y2: artboard.get('height') + artboard.get('top'),
|
204 |
+
})
|
205 |
+
.setCoords();
|
206 |
+
canvas.renderAll();
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
// Check for vertical snapping
|
211 |
+
function checkVSnap(a, b, snapZone, e, type) {
|
212 |
+
if (a > b - snapZone && a < b + snapZone) {
|
213 |
+
line_v.opacity = 1;
|
214 |
+
line_v.bringToFront();
|
215 |
+
var value = b;
|
216 |
+
if (type == 1) {
|
217 |
+
value = b;
|
218 |
+
} else if (type == 2) {
|
219 |
+
value =
|
220 |
+
b -
|
221 |
+
(e.target.get('height') * e.target.get('scaleY')) / 2;
|
222 |
+
} else if (type == 3) {
|
223 |
+
value =
|
224 |
+
b +
|
225 |
+
(e.target.get('height') * e.target.get('scaleY')) / 2;
|
226 |
+
}
|
227 |
+
e.target
|
228 |
+
.set({
|
229 |
+
top: value,
|
230 |
+
})
|
231 |
+
.setCoords();
|
232 |
+
line_v
|
233 |
+
.set({
|
234 |
+
y1: b,
|
235 |
+
x1: artboard.get('left'),
|
236 |
+
y2: b,
|
237 |
+
x2: artboard.get('width') + artboard.get('left'),
|
238 |
+
})
|
239 |
+
.setCoords();
|
240 |
+
canvas.renderAll();
|
241 |
+
}
|
242 |
+
}
|
243 |
+
if (obj != e.target && obj != line_h && obj != line_v) {
|
244 |
+
if (
|
245 |
+
obj.get('id') == 'center_h' ||
|
246 |
+
obj.get('id') == 'center_v'
|
247 |
+
) {
|
248 |
+
var check1 = [[obj_left, obj.get('left'), 1]];
|
249 |
+
var check2 = [[obj_top, obj.get('top'), 1]];
|
250 |
+
|
251 |
+
for (var i = 0; i < check1.length; i++) {
|
252 |
+
checkHSnap(
|
253 |
+
check1[i][0],
|
254 |
+
check1[i][1],
|
255 |
+
snapZone,
|
256 |
+
e,
|
257 |
+
check1[i][2]
|
258 |
+
);
|
259 |
+
checkVSnap(
|
260 |
+
check2[i][0],
|
261 |
+
check2[i][1],
|
262 |
+
snapZone,
|
263 |
+
e,
|
264 |
+
check2[i][2]
|
265 |
+
);
|
266 |
+
}
|
267 |
+
} else {
|
268 |
+
var check1 = [
|
269 |
+
[obj_left, obj.get('left'), 1],
|
270 |
+
[
|
271 |
+
obj_left,
|
272 |
+
obj.get('left') +
|
273 |
+
(obj.get('width') * obj.get('scaleX')) / 2,
|
274 |
+
1,
|
275 |
+
],
|
276 |
+
[
|
277 |
+
obj_left,
|
278 |
+
obj.get('left') -
|
279 |
+
(obj.get('width') * obj.get('scaleX')) / 2,
|
280 |
+
1,
|
281 |
+
],
|
282 |
+
[obj_left + obj_width / 2, obj.get('left'), 2],
|
283 |
+
[
|
284 |
+
obj_left + obj_width / 2,
|
285 |
+
obj.get('left') +
|
286 |
+
(obj.get('width') * obj.get('scaleX')) / 2,
|
287 |
+
2,
|
288 |
+
],
|
289 |
+
[
|
290 |
+
obj_left + obj_width / 2,
|
291 |
+
obj.get('left') -
|
292 |
+
(obj.get('width') * obj.get('scaleX')) / 2,
|
293 |
+
2,
|
294 |
+
],
|
295 |
+
[obj_left - obj_width / 2, obj.get('left'), 3],
|
296 |
+
[
|
297 |
+
obj_left - obj_width / 2,
|
298 |
+
obj.get('left') +
|
299 |
+
(obj.get('width') * obj.get('scaleX')) / 2,
|
300 |
+
3,
|
301 |
+
],
|
302 |
+
[
|
303 |
+
obj_left - obj_width / 2,
|
304 |
+
obj.get('left') -
|
305 |
+
(obj.get('width') * obj.get('scaleX')) / 2,
|
306 |
+
3,
|
307 |
+
],
|
308 |
+
];
|
309 |
+
var check2 = [
|
310 |
+
[obj_top, obj.get('top'), 1],
|
311 |
+
[
|
312 |
+
obj_top,
|
313 |
+
obj.get('top') +
|
314 |
+
(obj.get('height') * obj.get('scaleY')) / 2,
|
315 |
+
1,
|
316 |
+
],
|
317 |
+
[
|
318 |
+
obj_top,
|
319 |
+
obj.get('top') -
|
320 |
+
(obj.get('height') * obj.get('scaleY')) / 2,
|
321 |
+
1,
|
322 |
+
],
|
323 |
+
[obj_top + obj_height / 2, obj.get('top'), 2],
|
324 |
+
[
|
325 |
+
obj_top + obj_height / 2,
|
326 |
+
obj.get('top') +
|
327 |
+
(obj.get('height') * obj.get('scaleY')) / 2,
|
328 |
+
2,
|
329 |
+
],
|
330 |
+
[
|
331 |
+
obj_top + obj_height / 2,
|
332 |
+
obj.get('top') -
|
333 |
+
(obj.get('height') * obj.get('scaleY')) / 2,
|
334 |
+
2,
|
335 |
+
],
|
336 |
+
[obj_top - obj_height / 2, obj.get('top'), 3],
|
337 |
+
[
|
338 |
+
obj_top - obj_height / 2,
|
339 |
+
obj.get('top') +
|
340 |
+
(obj.get('height') * obj.get('scaleY')) / 2,
|
341 |
+
3,
|
342 |
+
],
|
343 |
+
[
|
344 |
+
obj_top - obj_height / 2,
|
345 |
+
obj.get('top') -
|
346 |
+
(obj.get('height') * obj.get('scaleY')) / 2,
|
347 |
+
3,
|
348 |
+
],
|
349 |
+
];
|
350 |
+
|
351 |
+
for (var i = 0; i < check1.length; i++) {
|
352 |
+
checkHSnap(
|
353 |
+
check1[i][0],
|
354 |
+
check1[i][1],
|
355 |
+
snapZone,
|
356 |
+
e,
|
357 |
+
check1[i][2]
|
358 |
+
);
|
359 |
+
checkVSnap(
|
360 |
+
check2[i][0],
|
361 |
+
check2[i][1],
|
362 |
+
snapZone,
|
363 |
+
e,
|
364 |
+
check2[i][2]
|
365 |
+
);
|
366 |
+
}
|
367 |
+
}
|
368 |
+
}
|
369 |
+
});
|
370 |
+
}
|
371 |
+
}
|
js/converter.js
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var workerPath =
|
2 |
+
'https://archive.org/download/ffmpeg_asm/ffmpeg_asm.js';
|
3 |
+
|
4 |
+
function processInWebWorker() {
|
5 |
+
var blob = URL.createObjectURL(
|
6 |
+
new Blob(
|
7 |
+
[
|
8 |
+
'importScripts("' +
|
9 |
+
workerPath +
|
10 |
+
'");var now = Date.now;function print(text) {postMessage({"type" : "stdout","data" : text});};onmessage = function(event) {var message = event.data;if (message.type === "command") {var Module = {print: print,printErr: print,files: message.files || [],arguments: message.arguments || [],TOTAL_MEMORY: message.TOTAL_MEMORY||536870912 || false};postMessage({"type" : "start","data" : Module.arguments.join(" ")});postMessage({"type" : "stdout","data" : "Received command: " +Module.arguments.join(" ") +((Module.TOTAL_MEMORY ) ? ". Processing with " + Module.TOTAL_MEMORY + " bits." : "")});var time = now();var result = ffmpeg_run(Module);var totalTime = now() - time;postMessage({"type" : "stdout","data" : "Finished processing (took " + totalTime + "ms)"});postMessage({"type" : "done","data" : result,"time" : totalTime});}};postMessage({"type" : "ready"});',
|
11 |
+
],
|
12 |
+
{
|
13 |
+
type: 'application/javascript',
|
14 |
+
}
|
15 |
+
)
|
16 |
+
);
|
17 |
+
|
18 |
+
var worker = new Worker(blob);
|
19 |
+
URL.revokeObjectURL(blob);
|
20 |
+
return worker;
|
21 |
+
}
|
22 |
+
|
23 |
+
var worker;
|
24 |
+
|
25 |
+
function convertStreams(videoBlob, setting) {
|
26 |
+
var aab;
|
27 |
+
var buffersReady;
|
28 |
+
var workerReady;
|
29 |
+
var posted;
|
30 |
+
|
31 |
+
var fileReader = new FileReader();
|
32 |
+
fileReader.onload = function () {
|
33 |
+
aab = this.result;
|
34 |
+
postMessage();
|
35 |
+
};
|
36 |
+
fileReader.readAsArrayBuffer(videoBlob);
|
37 |
+
|
38 |
+
if (!worker) {
|
39 |
+
worker = processInWebWorker();
|
40 |
+
}
|
41 |
+
worker.onmessage = function (event) {
|
42 |
+
var message = event.data;
|
43 |
+
if (message.type == 'ready') {
|
44 |
+
workerReady = true;
|
45 |
+
if (buffersReady) postMessage();
|
46 |
+
} else if (message.type == 'done') {
|
47 |
+
var result = message.data[0];
|
48 |
+
if (setting == 'gif') {
|
49 |
+
var blob = new File([result.data], 'test.gif', {
|
50 |
+
type: 'image/gif',
|
51 |
+
});
|
52 |
+
PostBlob(blob);
|
53 |
+
} else if (setting == 'mp4') {
|
54 |
+
var blob = new File([result.data], 'test.mp4', {
|
55 |
+
type: 'video/mp4',
|
56 |
+
});
|
57 |
+
PostBlob(blob);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
};
|
61 |
+
var postMessage = function () {
|
62 |
+
posted = true;
|
63 |
+
if (setting == 'gif') {
|
64 |
+
worker.postMessage({
|
65 |
+
type: 'command',
|
66 |
+
arguments: '-i video.webm -r 24 output-10.gif'.split(' '),
|
67 |
+
files: [
|
68 |
+
{
|
69 |
+
data: new Uint8Array(aab),
|
70 |
+
name: 'video.webm',
|
71 |
+
},
|
72 |
+
],
|
73 |
+
});
|
74 |
+
} else if (setting == 'mp4') {
|
75 |
+
worker.postMessage({
|
76 |
+
type: 'command',
|
77 |
+
arguments:
|
78 |
+
'-i video.webm -c:v mpeg4 -b:v 6400k -strict experimental output.mp4'.split(
|
79 |
+
' '
|
80 |
+
),
|
81 |
+
files: [
|
82 |
+
{
|
83 |
+
data: new Uint8Array(aab),
|
84 |
+
name: 'video.webm',
|
85 |
+
},
|
86 |
+
],
|
87 |
+
});
|
88 |
+
}
|
89 |
+
};
|
90 |
+
}
|
91 |
+
|
92 |
+
function PostBlob(blob) {
|
93 |
+
var url = URL.createObjectURL(blob);
|
94 |
+
const a = document.createElement('a');
|
95 |
+
a.style.display = 'none';
|
96 |
+
a.href = url;
|
97 |
+
a.download = name;
|
98 |
+
document.body.appendChild(a);
|
99 |
+
a.click();
|
100 |
+
recording = false;
|
101 |
+
currenttime = 0;
|
102 |
+
animate(false, 0);
|
103 |
+
$('#seekbar').offset({
|
104 |
+
left:
|
105 |
+
offset_left +
|
106 |
+
$('#inner-timeline').offset().left +
|
107 |
+
currenttime / timelinetime,
|
108 |
+
});
|
109 |
+
canvas.renderAll();
|
110 |
+
resizeCanvas();
|
111 |
+
if (background_audio != false) {
|
112 |
+
background_audio.pause();
|
113 |
+
background_audio = new Audio(background_audio.src);
|
114 |
+
}
|
115 |
+
$('#download-real').html('Download');
|
116 |
+
$('#download-real').removeClass('downloading');
|
117 |
+
updateRecordCanvas();
|
118 |
+
}
|
js/database.js
ADDED
@@ -0,0 +1,660 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// For debugging purposes
|
2 |
+
db.config.debug = false;
|
3 |
+
|
4 |
+
// Check if a project exists
|
5 |
+
function checkDB() {
|
6 |
+
db.collection('projects')
|
7 |
+
.get()
|
8 |
+
.then((project) => {
|
9 |
+
if (project.length == 0) {
|
10 |
+
canvas.clipPath = null;
|
11 |
+
const inst = canvas.toDatalessJSON([
|
12 |
+
'volume',
|
13 |
+
'audioSrc',
|
14 |
+
'defaultLeft',
|
15 |
+
'defaultTop',
|
16 |
+
'defaultScaleX',
|
17 |
+
'defaultScaleY',
|
18 |
+
'notnew',
|
19 |
+
'starttime',
|
20 |
+
'top',
|
21 |
+
'left',
|
22 |
+
'width',
|
23 |
+
'height',
|
24 |
+
'scaleX',
|
25 |
+
'scaleY',
|
26 |
+
'flipX',
|
27 |
+
'flipY',
|
28 |
+
'originX',
|
29 |
+
'originY',
|
30 |
+
'transformMatrix',
|
31 |
+
'stroke',
|
32 |
+
'strokeWidth',
|
33 |
+
'strokeDashArray',
|
34 |
+
'strokeLineCap',
|
35 |
+
'strokeDashOffset',
|
36 |
+
'strokeLineJoin',
|
37 |
+
'strokeMiterLimit',
|
38 |
+
'angle',
|
39 |
+
'opacity',
|
40 |
+
'fill',
|
41 |
+
'globalCompositeOperation',
|
42 |
+
'shadow',
|
43 |
+
'clipTo',
|
44 |
+
'visible',
|
45 |
+
'backgroundColor',
|
46 |
+
'skewX',
|
47 |
+
'skewY',
|
48 |
+
'fillRule',
|
49 |
+
'paintFirst',
|
50 |
+
'strokeUniform',
|
51 |
+
'rx',
|
52 |
+
'ry',
|
53 |
+
'selectable',
|
54 |
+
'hasControls',
|
55 |
+
'subTargetCheck',
|
56 |
+
'id',
|
57 |
+
'hoverCursor',
|
58 |
+
'defaultCursor',
|
59 |
+
'filesrc',
|
60 |
+
'isEditing',
|
61 |
+
'source',
|
62 |
+
'assetType',
|
63 |
+
'duration',
|
64 |
+
'inGroup',
|
65 |
+
'filters',
|
66 |
+
]);
|
67 |
+
canvas.clipPath = artboard;
|
68 |
+
db.collection('projects').add({
|
69 |
+
id: 1,
|
70 |
+
canvas: JSON.stringify(inst),
|
71 |
+
keyframes: JSON.stringify(keyframes.slice()),
|
72 |
+
p_keyframes: JSON.stringify(p_keyframes.slice()),
|
73 |
+
objects: JSON.stringify(objects.slice()),
|
74 |
+
colormode: colormode,
|
75 |
+
speed: speed,
|
76 |
+
duration: duration,
|
77 |
+
currenttime: currenttime,
|
78 |
+
layercount: layer_count,
|
79 |
+
width: artboard.width,
|
80 |
+
height: artboard.height,
|
81 |
+
animatedtext: JSON.stringify(animatedtext),
|
82 |
+
groups: JSON.stringify(groups),
|
83 |
+
files: JSON.stringify(files),
|
84 |
+
activepreset: activepreset,
|
85 |
+
});
|
86 |
+
checkstatus = true;
|
87 |
+
getAssets();
|
88 |
+
} else {
|
89 |
+
loadProject();
|
90 |
+
}
|
91 |
+
});
|
92 |
+
}
|
93 |
+
|
94 |
+
// Automatically save project (locally)
|
95 |
+
function autoSave() {
|
96 |
+
if (checkstatus) {
|
97 |
+
canvas.clipPath = null;
|
98 |
+
objects.forEach(async function (object) {
|
99 |
+
var obj = canvas.getItemById(object.id);
|
100 |
+
if (obj.filters) {
|
101 |
+
if (obj.filters.length > 0) {
|
102 |
+
object.filters = [];
|
103 |
+
obj.filters.forEach(function (filter) {
|
104 |
+
if (
|
105 |
+
filter.type == 'BlackWhite' ||
|
106 |
+
filter.type == 'Invert' ||
|
107 |
+
filter.type == 'Sepia' ||
|
108 |
+
filter.type == 'Kodachrome' ||
|
109 |
+
filter.type == 'Polaroid' ||
|
110 |
+
filter.type == 'Technicolor' ||
|
111 |
+
filter.type == 'Brownie' ||
|
112 |
+
filter.type == 'Vintage'
|
113 |
+
) {
|
114 |
+
object.filters.push({ type: filter.type });
|
115 |
+
} else if (filter.type == 'Brightness') {
|
116 |
+
object.filters.push({
|
117 |
+
type: filter.type,
|
118 |
+
value: filter.brightness,
|
119 |
+
});
|
120 |
+
} else if (filter.type == 'Contrast') {
|
121 |
+
object.filters.push({
|
122 |
+
type: filter.type,
|
123 |
+
value: filter.contrast,
|
124 |
+
});
|
125 |
+
} else if (filter.type == 'Vibrance') {
|
126 |
+
object.filters.push({
|
127 |
+
type: filter.type,
|
128 |
+
value: filter.vibrance,
|
129 |
+
});
|
130 |
+
} else if (filter.type == 'Saturation') {
|
131 |
+
object.filters.push({
|
132 |
+
type: filter.type,
|
133 |
+
value: filter.saturation,
|
134 |
+
});
|
135 |
+
} else if (filter.type == 'HueRotation') {
|
136 |
+
object.filters.push({
|
137 |
+
type: filter.type,
|
138 |
+
value: filter.rotation,
|
139 |
+
});
|
140 |
+
} else if (filter.type == 'Blur') {
|
141 |
+
object.filters.push({
|
142 |
+
type: filter.type,
|
143 |
+
value: filter.blur,
|
144 |
+
});
|
145 |
+
} else if (filter.type == 'Noise') {
|
146 |
+
object.filters.push({
|
147 |
+
type: filter.type,
|
148 |
+
value: filter.noise,
|
149 |
+
});
|
150 |
+
} else if (filter.type == 'RemoveColor') {
|
151 |
+
object.filters.push({
|
152 |
+
type: filter.type,
|
153 |
+
distance: filter.distance,
|
154 |
+
color: filter.color,
|
155 |
+
});
|
156 |
+
}
|
157 |
+
});
|
158 |
+
obj.filters = [];
|
159 |
+
obj.applyFilters();
|
160 |
+
var backend = fabric.filterBackend;
|
161 |
+
if (backend && backend.evictCachesForKey) {
|
162 |
+
backend.evictCachesForKey(obj.cacheKey);
|
163 |
+
backend.evictCachesForKey(obj.cacheKey + '_filtered');
|
164 |
+
}
|
165 |
+
if (
|
166 |
+
obj.filters.length > 0 &&
|
167 |
+
obj.get('id').indexOf('Video') >= 0
|
168 |
+
) {
|
169 |
+
await obj.setElement(obj.saveElem);
|
170 |
+
}
|
171 |
+
} else {
|
172 |
+
object.filters = [];
|
173 |
+
}
|
174 |
+
} else {
|
175 |
+
object.filters = [];
|
176 |
+
}
|
177 |
+
});
|
178 |
+
const inst = canvas.toDatalessJSON([
|
179 |
+
'volume',
|
180 |
+
'audioSrc',
|
181 |
+
'defaultLeft',
|
182 |
+
'defaultTop',
|
183 |
+
'defaultScaleX',
|
184 |
+
'defaultScaleY',
|
185 |
+
'notnew',
|
186 |
+
'starttime',
|
187 |
+
'top',
|
188 |
+
'left',
|
189 |
+
'width',
|
190 |
+
'height',
|
191 |
+
'scaleX',
|
192 |
+
'scaleY',
|
193 |
+
'flipX',
|
194 |
+
'flipY',
|
195 |
+
'originX',
|
196 |
+
'originY',
|
197 |
+
'transformMatrix',
|
198 |
+
'stroke',
|
199 |
+
'strokeWidth',
|
200 |
+
'strokeDashArray',
|
201 |
+
'strokeLineCap',
|
202 |
+
'strokeDashOffset',
|
203 |
+
'strokeLineJoin',
|
204 |
+
'strokeMiterLimit',
|
205 |
+
'angle',
|
206 |
+
'opacity',
|
207 |
+
'fill',
|
208 |
+
'globalCompositeOperation',
|
209 |
+
'shadow',
|
210 |
+
'clipTo',
|
211 |
+
'visible',
|
212 |
+
'backgroundColor',
|
213 |
+
'skewX',
|
214 |
+
'skewY',
|
215 |
+
'fillRule',
|
216 |
+
'paintFirst',
|
217 |
+
'strokeUniform',
|
218 |
+
'rx',
|
219 |
+
'ry',
|
220 |
+
'selectable',
|
221 |
+
'hasControls',
|
222 |
+
'subTargetCheck',
|
223 |
+
'id',
|
224 |
+
'hoverCursor',
|
225 |
+
'defaultCursor',
|
226 |
+
'filesrc',
|
227 |
+
'isEditing',
|
228 |
+
'source',
|
229 |
+
'assetType',
|
230 |
+
'duration',
|
231 |
+
'inGroup',
|
232 |
+
]);
|
233 |
+
canvas.clipPath = artboard;
|
234 |
+
db.collection('projects')
|
235 |
+
.doc({ id: 1 })
|
236 |
+
.update({
|
237 |
+
canvas: JSON.stringify(inst),
|
238 |
+
keyframes: JSON.stringify(keyframes.slice()),
|
239 |
+
p_keyframes: JSON.stringify(p_keyframes.slice()),
|
240 |
+
objects: JSON.stringify(objects.slice()),
|
241 |
+
colormode: colormode,
|
242 |
+
duration: duration,
|
243 |
+
currenttime: currenttime,
|
244 |
+
layercount: layer_count,
|
245 |
+
speed: speed,
|
246 |
+
audiosrc: background_key,
|
247 |
+
animatedtext: JSON.stringify(animatedtext),
|
248 |
+
files: JSON.stringify(files),
|
249 |
+
groups: JSON.stringify(groups),
|
250 |
+
activepreset: activepreset,
|
251 |
+
width: artboard.width,
|
252 |
+
height: artboard.height,
|
253 |
+
});
|
254 |
+
objects.forEach(function (object) {
|
255 |
+
replaceSource(canvas.getItemById(object.id), canvas);
|
256 |
+
});
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
var isSameSet = function (arr1, arr2) {
|
261 |
+
return (
|
262 |
+
$(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0
|
263 |
+
);
|
264 |
+
};
|
265 |
+
|
266 |
+
function loadProject() {
|
267 |
+
db.collection('projects')
|
268 |
+
.doc({ id: 1 })
|
269 |
+
.get()
|
270 |
+
.then((document) => {
|
271 |
+
var project = document;
|
272 |
+
keyframes = JSON.parse(project.keyframes);
|
273 |
+
p_keyframes = JSON.parse(project.p_keyframes);
|
274 |
+
objects = JSON.parse(project.objects);
|
275 |
+
files = JSON.parse(project.files);
|
276 |
+
colormode = project.colormode;
|
277 |
+
duration = project.duration;
|
278 |
+
layer_count = project.layercount;
|
279 |
+
speed = project.speed;
|
280 |
+
animatedtext = JSON.parse(project.animatedtext);
|
281 |
+
animatedtext.forEach(function (text, index) {
|
282 |
+
var temp = new AnimatedText(text.text, text.props);
|
283 |
+
temp.assignTo(text.id);
|
284 |
+
animatedtext[index] = temp;
|
285 |
+
});
|
286 |
+
$('#speed span').html(speed.toFixed(1) + 'x');
|
287 |
+
groups = JSON.parse(project.groups);
|
288 |
+
activepreset = project.activepreset;
|
289 |
+
currenttime = 0;
|
290 |
+
canvas.clipPath = null;
|
291 |
+
canvas.clear();
|
292 |
+
fabric.filterBackend = webglBackend;
|
293 |
+
f = fabric.Image.filters;
|
294 |
+
canvas.loadFromJSON(JSON.parse(project.canvas), function () {
|
295 |
+
canvas.clipPath = artboard;
|
296 |
+
canvas.getItemById('line_h').set({ opacity: 0 });
|
297 |
+
canvas.getItemById('line_v').set({ opacity: 0 });
|
298 |
+
canvas.renderAll();
|
299 |
+
$('.object-props').remove();
|
300 |
+
$('.layer').remove();
|
301 |
+
objects.forEach(function (object) {
|
302 |
+
var animatethis = false;
|
303 |
+
if (object.animate.length > 5) {
|
304 |
+
if (isSameSet(object.animate, props)) {
|
305 |
+
animatethis = true;
|
306 |
+
}
|
307 |
+
}
|
308 |
+
renderLayer(canvas.getItemById(object.id), animatethis);
|
309 |
+
if (
|
310 |
+
!canvas.getItemById(object.id).get('assetType') ||
|
311 |
+
canvas.getItemById(object.id).get('assetType') != 'audio'
|
312 |
+
) {
|
313 |
+
props.forEach(function (prop) {
|
314 |
+
if (
|
315 |
+
prop != 'top' &&
|
316 |
+
prop != 'scaleY' &&
|
317 |
+
prop != 'width' &&
|
318 |
+
prop != 'height' &&
|
319 |
+
prop != 'shadow.offsetX' &&
|
320 |
+
prop != 'shadow.offsetY' &&
|
321 |
+
prop != 'shadow.opacity' &&
|
322 |
+
prop != 'shadow.blur' &&
|
323 |
+
prop != 'lineHeight'
|
324 |
+
) {
|
325 |
+
renderProp(prop, canvas.getItemById(object.id));
|
326 |
+
}
|
327 |
+
});
|
328 |
+
replaceSource(canvas.getItemById(object.id), canvas);
|
329 |
+
} else {
|
330 |
+
renderProp('volume', canvas.getItemById(object.id));
|
331 |
+
}
|
332 |
+
});
|
333 |
+
keyframes.forEach(function (keyframe) {
|
334 |
+
if (
|
335 |
+
keyframe.name != 'top' &&
|
336 |
+
keyframe.name != 'scaleY' &&
|
337 |
+
keyframe.name != 'width' &&
|
338 |
+
keyframe.name != 'height' &&
|
339 |
+
keyframe.name != 'shadow.offsetX' &&
|
340 |
+
keyframe.name != 'shadow.offsetY' &&
|
341 |
+
keyframe.name != 'shadow.opacity' &&
|
342 |
+
keyframe.name != 'shadow.blur' &&
|
343 |
+
keyframe.name != 'lineHeight'
|
344 |
+
) {
|
345 |
+
renderKeyframe(
|
346 |
+
canvas.getItemById(keyframe.id),
|
347 |
+
keyframe.name,
|
348 |
+
keyframe.t
|
349 |
+
);
|
350 |
+
}
|
351 |
+
});
|
352 |
+
artboard.set({
|
353 |
+
width: project.width,
|
354 |
+
height: project.height,
|
355 |
+
});
|
356 |
+
canvas.renderAll();
|
357 |
+
resizeCanvas();
|
358 |
+
updatePanel();
|
359 |
+
|
360 |
+
animatedtext.forEach(function (text, index) {
|
361 |
+
text.reset(text.text, text.props, canvas);
|
362 |
+
canvas.renderAll();
|
363 |
+
});
|
364 |
+
|
365 |
+
// Set defaults
|
366 |
+
setDuration(duration);
|
367 |
+
setTimelineZoom(5);
|
368 |
+
checkstatus = true;
|
369 |
+
|
370 |
+
getAssets();
|
371 |
+
|
372 |
+
canvas.renderAll();
|
373 |
+
|
374 |
+
animate(false, 0);
|
375 |
+
|
376 |
+
//newLottieAnimation(100,100);
|
377 |
+
});
|
378 |
+
});
|
379 |
+
}
|
380 |
+
|
381 |
+
function blobToBase64(blob) {
|
382 |
+
return new Promise((resolve, _) => {
|
383 |
+
const reader = new FileReader();
|
384 |
+
reader.onloadend = () => resolve(reader.result);
|
385 |
+
reader.readAsDataURL(blob);
|
386 |
+
});
|
387 |
+
}
|
388 |
+
|
389 |
+
async function saveFile(thumbnail, file, type, name, place, hidden) {
|
390 |
+
file = await blobToBase64(file);
|
391 |
+
thumbnail = await blobToBase64(thumbnail);
|
392 |
+
uploading = false;
|
393 |
+
var key = Math.random().toString(36).substr(2, 9);
|
394 |
+
db.collection('assets').add({
|
395 |
+
key: key,
|
396 |
+
src: file,
|
397 |
+
thumb: thumbnail,
|
398 |
+
name: name,
|
399 |
+
type: type,
|
400 |
+
hidden: hidden,
|
401 |
+
});
|
402 |
+
if (type === 'image') {
|
403 |
+
uploaded_images.push({
|
404 |
+
src: file,
|
405 |
+
thumb: thumbnail,
|
406 |
+
key: key,
|
407 |
+
type: 'image',
|
408 |
+
hidden: false,
|
409 |
+
});
|
410 |
+
populateGrid('images-tab');
|
411 |
+
} else if (type === 'video') {
|
412 |
+
uploaded_videos.push({
|
413 |
+
src: file,
|
414 |
+
thumb: thumbnail,
|
415 |
+
key: key,
|
416 |
+
type: 'video',
|
417 |
+
hidden: false,
|
418 |
+
});
|
419 |
+
populateGrid('videos-tab');
|
420 |
+
}
|
421 |
+
$('#upload-button').html(
|
422 |
+
"<img src='assets/upload.svg'> Upload media"
|
423 |
+
);
|
424 |
+
$('#upload-button').removeClass('uploading');
|
425 |
+
if (place) {
|
426 |
+
loadImage(
|
427 |
+
file,
|
428 |
+
artboard.get('left') + artboard.get('width') / 2,
|
429 |
+
artboard.get('top') + artboard.get('height') / 2,
|
430 |
+
200
|
431 |
+
);
|
432 |
+
}
|
433 |
+
save();
|
434 |
+
}
|
435 |
+
|
436 |
+
async function savePixabayImage(url, xpos, ypos, width) {
|
437 |
+
$('#load-image').addClass('loading-active');
|
438 |
+
fetch(url)
|
439 |
+
.then((res) => res.blob())
|
440 |
+
.then((blob) => {
|
441 |
+
url = blob;
|
442 |
+
var reader = new FileReader();
|
443 |
+
reader.readAsDataURL(blob);
|
444 |
+
reader.onloadend = function () {
|
445 |
+
url = reader.result;
|
446 |
+
var key = Math.random().toString(36).substr(2, 9);
|
447 |
+
db.collection('assets').add({
|
448 |
+
key: key,
|
449 |
+
src: url,
|
450 |
+
thumb: url,
|
451 |
+
name: 'test',
|
452 |
+
type: 'image',
|
453 |
+
hidden: true,
|
454 |
+
});
|
455 |
+
loadImage(url, xpos, ypos, width, false);
|
456 |
+
};
|
457 |
+
});
|
458 |
+
}
|
459 |
+
|
460 |
+
async function saveAudio(url) {
|
461 |
+
var reader = new FileReader();
|
462 |
+
reader.readAsDataURL(url);
|
463 |
+
reader.onloadend = function () {
|
464 |
+
var key = Math.random().toString(36).substr(2, 9);
|
465 |
+
db.collection('assets').add({
|
466 |
+
key: key,
|
467 |
+
src: reader.result,
|
468 |
+
name: 'test',
|
469 |
+
type: 'audio',
|
470 |
+
hidden: true,
|
471 |
+
});
|
472 |
+
newAudioLayer(reader.result);
|
473 |
+
};
|
474 |
+
}
|
475 |
+
|
476 |
+
async function savePixabayVideo(url, thumb, x, y) {
|
477 |
+
$('#load-video').addClass('loading-active');
|
478 |
+
fetch(url)
|
479 |
+
.then((res) => res.blob())
|
480 |
+
.then((blob) => {
|
481 |
+
var reader = new FileReader();
|
482 |
+
reader.readAsDataURL(blob);
|
483 |
+
reader.onloadend = function () {
|
484 |
+
fetch(thumb)
|
485 |
+
.then((res) => res.blob())
|
486 |
+
.then((blob2) => {
|
487 |
+
var reader2 = new FileReader();
|
488 |
+
reader2.readAsDataURL(blob2);
|
489 |
+
reader2.onloadend = function () {
|
490 |
+
url = reader.result;
|
491 |
+
thumb = reader2.result;
|
492 |
+
var key = Math.random().toString(36).substr(2, 9);
|
493 |
+
db.collection('assets').add({
|
494 |
+
key: key,
|
495 |
+
src: url,
|
496 |
+
thumb: thumb,
|
497 |
+
name: 'test',
|
498 |
+
type: 'video',
|
499 |
+
hidden: true,
|
500 |
+
});
|
501 |
+
loadVideo(url, x, y, false);
|
502 |
+
};
|
503 |
+
});
|
504 |
+
};
|
505 |
+
});
|
506 |
+
}
|
507 |
+
|
508 |
+
function deleteAsset(key) {
|
509 |
+
db.collection('assets')
|
510 |
+
.doc({ key: key })
|
511 |
+
.get()
|
512 |
+
.then((asset) => {
|
513 |
+
var temp = files.filter((x) => x.file == asset.src);
|
514 |
+
if (temp.length > 0) {
|
515 |
+
temp.forEach(function (file) {
|
516 |
+
deleteObject(canvas.getItemById(file.name));
|
517 |
+
files = $.grep(files, function (a) {
|
518 |
+
return a != file;
|
519 |
+
});
|
520 |
+
});
|
521 |
+
}
|
522 |
+
db.collection('assets').doc({ key: key }).delete();
|
523 |
+
if (asset.type == 'image') {
|
524 |
+
uploaded_images = uploaded_images.filter(function (obj) {
|
525 |
+
return obj.key !== key;
|
526 |
+
});
|
527 |
+
populateGrid('images-tab');
|
528 |
+
} else {
|
529 |
+
uploaded_videos = uploaded_videos.filter(function (obj) {
|
530 |
+
return obj.key !== key;
|
531 |
+
});
|
532 |
+
populateGrid('videos-tab');
|
533 |
+
}
|
534 |
+
});
|
535 |
+
}
|
536 |
+
|
537 |
+
function getAssets() {
|
538 |
+
db.collection('assets')
|
539 |
+
.get()
|
540 |
+
.then((assets) => {
|
541 |
+
// Sometimes the assets aren't ready when importing, really annoying
|
542 |
+
if (assets === undefined) {
|
543 |
+
getAssets();
|
544 |
+
} else if (assets.length > 0) {
|
545 |
+
assets.forEach(function (asset) {
|
546 |
+
if (asset.type == 'image') {
|
547 |
+
uploaded_images.push({
|
548 |
+
src: asset.src,
|
549 |
+
thumb: asset.thumb,
|
550 |
+
key: asset.key,
|
551 |
+
type: 'image',
|
552 |
+
hidden: asset.hidden,
|
553 |
+
});
|
554 |
+
} else if (asset.type == 'video') {
|
555 |
+
uploaded_videos.push({
|
556 |
+
src: asset.src,
|
557 |
+
thumb: asset.thumb,
|
558 |
+
key: asset.key,
|
559 |
+
type: 'video',
|
560 |
+
hidden: asset.hidden,
|
561 |
+
});
|
562 |
+
}
|
563 |
+
});
|
564 |
+
}
|
565 |
+
});
|
566 |
+
}
|
567 |
+
|
568 |
+
function readTextFile(file, callback) {
|
569 |
+
var rawFile = new XMLHttpRequest();
|
570 |
+
rawFile.overrideMimeType('application/json');
|
571 |
+
rawFile.open('GET', file, true);
|
572 |
+
rawFile.onreadystatechange = function () {
|
573 |
+
if (rawFile.readyState === 4 && rawFile.status == '200') {
|
574 |
+
callback(rawFile.responseText);
|
575 |
+
}
|
576 |
+
};
|
577 |
+
rawFile.send(null);
|
578 |
+
}
|
579 |
+
|
580 |
+
async function importProject(e) {
|
581 |
+
$('#import-project span').html('Importing...');
|
582 |
+
var file = e.target.files[0];
|
583 |
+
var path = (window.URL || window.webkitURL).createObjectURL(file);
|
584 |
+
readTextFile(path, function (text) {
|
585 |
+
var data = JSON.parse(text);
|
586 |
+
delete data.project[0].id;
|
587 |
+
if (data.project.length > 0) {
|
588 |
+
if (data.assets.length > 0) {
|
589 |
+
data.assets.forEach(function (asset) {
|
590 |
+
delete asset.id;
|
591 |
+
db.collection('assets').add(asset);
|
592 |
+
});
|
593 |
+
}
|
594 |
+
db.collection('projects')
|
595 |
+
.doc({ id: 1 })
|
596 |
+
.update(data.project[0])
|
597 |
+
.then((response) => {
|
598 |
+
$('#import-project span').html('Import');
|
599 |
+
hideModals();
|
600 |
+
loadProject();
|
601 |
+
});
|
602 |
+
} else {
|
603 |
+
alert('Wrong file type');
|
604 |
+
}
|
605 |
+
});
|
606 |
+
}
|
607 |
+
|
608 |
+
function importHandle() {
|
609 |
+
$('#import').click();
|
610 |
+
}
|
611 |
+
|
612 |
+
function exportProject() {
|
613 |
+
$('#export-project span').html('Exporting...');
|
614 |
+
db.collection('projects')
|
615 |
+
.get()
|
616 |
+
.then((project) => {
|
617 |
+
if (project.length > 0) {
|
618 |
+
db.collection('assets')
|
619 |
+
.get()
|
620 |
+
.then((assets) => {
|
621 |
+
var exportarr = { project: project, assets: assets };
|
622 |
+
$('<a />', {
|
623 |
+
download: 'data.json',
|
624 |
+
href:
|
625 |
+
'data:application/json,' +
|
626 |
+
encodeURIComponent(JSON.stringify(exportarr)),
|
627 |
+
})
|
628 |
+
.appendTo('body')
|
629 |
+
.click(function () {
|
630 |
+
$(this).remove();
|
631 |
+
$('#export-project span').html('Export');
|
632 |
+
})[0]
|
633 |
+
.click();
|
634 |
+
});
|
635 |
+
} else {
|
636 |
+
alert('Empty project');
|
637 |
+
$('#export-project span').html('Export');
|
638 |
+
}
|
639 |
+
});
|
640 |
+
}
|
641 |
+
|
642 |
+
$(document).on('click', '#import-project', importHandle);
|
643 |
+
$(document).on('click', '#export-project', exportProject);
|
644 |
+
$(document).on('change', '#import', importProject);
|
645 |
+
|
646 |
+
function clearProject() {
|
647 |
+
if (
|
648 |
+
window.confirm(
|
649 |
+
'Are you sure you want to clear this project? This action cannot be undone.'
|
650 |
+
)
|
651 |
+
) {
|
652 |
+
db.collection('projects').delete();
|
653 |
+
db.collection('assets').delete();
|
654 |
+
window.setTimeout(function () {
|
655 |
+
location.reload();
|
656 |
+
}, 1000);
|
657 |
+
}
|
658 |
+
hideMore();
|
659 |
+
}
|
660 |
+
$(document).on('click', '#clear-project', clearProject);
|
js/encode-worker.js
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
importScripts('./webm-writer2.js');
|
2 |
+
|
3 |
+
let webmWriter = null;
|
4 |
+
let fileWritableStream = null;
|
5 |
+
let frameReader = null;
|
6 |
+
|
7 |
+
async function startRecording(
|
8 |
+
fileHandle,
|
9 |
+
frameStream,
|
10 |
+
trackSettings
|
11 |
+
) {
|
12 |
+
let frameCounter = 0;
|
13 |
+
|
14 |
+
fileWritableStream = await fileHandle.createWritable();
|
15 |
+
|
16 |
+
webmWriter = new WebMWriter({
|
17 |
+
fileWriter: fileWritableStream,
|
18 |
+
codec: 'VP9',
|
19 |
+
width: trackSettings.width,
|
20 |
+
height: trackSettings.height,
|
21 |
+
});
|
22 |
+
|
23 |
+
frameReader = frameStream.getReader();
|
24 |
+
|
25 |
+
const init = {
|
26 |
+
output: (chunk) => {
|
27 |
+
webmWriter.addFrame(chunk);
|
28 |
+
},
|
29 |
+
error: (e) => {
|
30 |
+
console.log(e.message);
|
31 |
+
stopRecording();
|
32 |
+
},
|
33 |
+
};
|
34 |
+
|
35 |
+
const config = {
|
36 |
+
codec: 'vp09.00.10.08',
|
37 |
+
width: trackSettings.width,
|
38 |
+
height: trackSettings.height,
|
39 |
+
bitrate: 10e6,
|
40 |
+
};
|
41 |
+
|
42 |
+
let encoder = new VideoEncoder(init);
|
43 |
+
let support = await VideoEncoder.isConfigSupported(config);
|
44 |
+
console.assert(support.supported);
|
45 |
+
encoder.configure(config);
|
46 |
+
|
47 |
+
frameReader
|
48 |
+
.read()
|
49 |
+
.then(async function processFrame({ done, value }) {
|
50 |
+
let frame = value;
|
51 |
+
|
52 |
+
if (done) {
|
53 |
+
await encoder.flush();
|
54 |
+
encoder.close();
|
55 |
+
return;
|
56 |
+
}
|
57 |
+
|
58 |
+
if (encoder.encodeQueueSize <= 30) {
|
59 |
+
if (++frameCounter % 20 == 0) {
|
60 |
+
console.log(frameCounter + ' frames processed');
|
61 |
+
}
|
62 |
+
|
63 |
+
const insert_keyframe = frameCounter % 150 == 0;
|
64 |
+
encoder.encode(frame, { keyFrame: insert_keyframe });
|
65 |
+
} else {
|
66 |
+
console.log('dropping frame, encoder falling behind');
|
67 |
+
}
|
68 |
+
|
69 |
+
frame.close();
|
70 |
+
frameReader.read().then(processFrame);
|
71 |
+
});
|
72 |
+
}
|
73 |
+
|
74 |
+
async function stopRecording() {
|
75 |
+
await frameReader.cancel();
|
76 |
+
await webmWriter.complete();
|
77 |
+
fileWritableStream.close();
|
78 |
+
frameReader = null;
|
79 |
+
webmWriter = null;
|
80 |
+
fileWritableStream = null;
|
81 |
+
}
|
82 |
+
|
83 |
+
self.addEventListener('message', function (e) {
|
84 |
+
switch (e.data.type) {
|
85 |
+
case 'start':
|
86 |
+
startRecording(
|
87 |
+
e.data.fileHandle,
|
88 |
+
e.data.frameStream,
|
89 |
+
e.data.trackSettings
|
90 |
+
);
|
91 |
+
break;
|
92 |
+
case 'stop':
|
93 |
+
stopRecording();
|
94 |
+
break;
|
95 |
+
}
|
96 |
+
});
|
js/events.js
ADDED
@@ -0,0 +1,1022 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
$(document).ready(function () {
|
2 |
+
// An object is being moved in the canvas
|
3 |
+
canvas.on('object:moving', function (e) {
|
4 |
+
e.target.hasControls = false;
|
5 |
+
centerLines(e);
|
6 |
+
if (cropping) {
|
7 |
+
if (
|
8 |
+
canvas.getItemById('crop').isContainedWithinObject(cropobj)
|
9 |
+
) {
|
10 |
+
cropleft = canvas.getItemById('crop').get('left');
|
11 |
+
croptop = canvas.getItemById('crop').get('top');
|
12 |
+
cropscalex = canvas.getItemById('crop').get('scaleX');
|
13 |
+
cropscaley = canvas.getItemById('crop').get('scaleY');
|
14 |
+
}
|
15 |
+
crop(canvas.getItemById('cropped'));
|
16 |
+
} else if (
|
17 |
+
lockmovement &&
|
18 |
+
e.e.shiftKey &&
|
19 |
+
canvas.getActiveObject()
|
20 |
+
) {
|
21 |
+
if (canvasx < shiftx + 30 && canvasx > shiftx - 30) {
|
22 |
+
canvas.getActiveObject().set({ left: shiftx });
|
23 |
+
canvas.getActiveObject().lockMovementX = true;
|
24 |
+
canvas.getActiveObject().lockMovementY = false;
|
25 |
+
} else {
|
26 |
+
canvas.getActiveObject().set({ top: shifty });
|
27 |
+
canvas.getActiveObject().lockMovementX = false;
|
28 |
+
canvas.getActiveObject().lockMovementY = true;
|
29 |
+
}
|
30 |
+
} else if (canvas.getActiveObject() && !e.e.shiftKey) {
|
31 |
+
lockmovement = false;
|
32 |
+
canvas.getActiveObject().lockMovementX = false;
|
33 |
+
canvas.getActiveObject().lockMovementY = false;
|
34 |
+
}
|
35 |
+
});
|
36 |
+
|
37 |
+
// An object is being scaled in the canvas
|
38 |
+
canvas.on('object:scaling', function (e) {
|
39 |
+
e.target.hasControls = false;
|
40 |
+
centerLines(e);
|
41 |
+
if (cropping) {
|
42 |
+
if (
|
43 |
+
canvas.getItemById('crop').isContainedWithinObject(cropobj)
|
44 |
+
) {
|
45 |
+
cropleft = canvas.getItemById('crop').get('left');
|
46 |
+
croptop = canvas.getItemById('crop').get('top');
|
47 |
+
cropscalex = canvas.getItemById('crop').get('scaleX');
|
48 |
+
cropscaley = canvas.getItemById('crop').get('scaleY');
|
49 |
+
}
|
50 |
+
crop(canvas.getItemById('cropped'));
|
51 |
+
}
|
52 |
+
});
|
53 |
+
|
54 |
+
// An object is being resized in the canvas
|
55 |
+
canvas.on('object:resizing', function (e) {
|
56 |
+
e.target.hasControls = false;
|
57 |
+
centerLines(e);
|
58 |
+
if (cropping) {
|
59 |
+
if (
|
60 |
+
canvas.getItemById('crop').isContainedWithinObject(cropobj)
|
61 |
+
) {
|
62 |
+
cropleft = canvas.getItemById('crop').get('left');
|
63 |
+
croptop = canvas.getItemById('crop').get('top');
|
64 |
+
cropscalex = canvas.getItemById('crop').get('scaleX');
|
65 |
+
cropscaley = canvas.getItemById('crop').get('scaleY');
|
66 |
+
}
|
67 |
+
crop(canvas.getItemById('cropped'));
|
68 |
+
}
|
69 |
+
});
|
70 |
+
|
71 |
+
// An object is being rotated in the canvas
|
72 |
+
canvas.on('object:rotating', function (e) {
|
73 |
+
if (e.e.shiftKey) {
|
74 |
+
canvas.getActiveObject().snapAngle = 15;
|
75 |
+
} else {
|
76 |
+
canvas.getActiveObject().snapAngle = 0;
|
77 |
+
}
|
78 |
+
e.target.hasControls = false;
|
79 |
+
});
|
80 |
+
|
81 |
+
// An object has been modified in the canvas
|
82 |
+
canvas.on('object:modified', function (e) {
|
83 |
+
e.target.hasControls = true;
|
84 |
+
if (!editinggroup && !cropping) {
|
85 |
+
canvas.getActiveObject().lockMovementX = false;
|
86 |
+
canvas.getActiveObject().lockMovementY = false;
|
87 |
+
canvas.renderAll();
|
88 |
+
if (e.target.type == 'activeSelection') {
|
89 |
+
const tempselection = canvas.getActiveObject();
|
90 |
+
canvas.discardActiveObject();
|
91 |
+
e.target._objects.forEach(function (object) {
|
92 |
+
autoKeyframe(object, e, true);
|
93 |
+
});
|
94 |
+
reselect(tempselection);
|
95 |
+
} else {
|
96 |
+
autoKeyframe(e.target, e, false);
|
97 |
+
}
|
98 |
+
updatePanelValues();
|
99 |
+
save();
|
100 |
+
}
|
101 |
+
if (cropping) {
|
102 |
+
var obj = e.target;
|
103 |
+
checkCrop(obj);
|
104 |
+
}
|
105 |
+
});
|
106 |
+
|
107 |
+
// A selection has been updated in the canvas
|
108 |
+
canvas.on('selection:updated', function (e) {
|
109 |
+
updatePanel(true);
|
110 |
+
updatePanelValues();
|
111 |
+
updateSelection(e);
|
112 |
+
closeFilters();
|
113 |
+
});
|
114 |
+
|
115 |
+
// A selection has been made in the canvas
|
116 |
+
canvas.on('selection:created', function (e) {
|
117 |
+
shiftx = canvas.getActiveObject().get('left');
|
118 |
+
shifty = canvas.getActiveObject().get('top');
|
119 |
+
if (!editingpanel) {
|
120 |
+
updatePanel(true);
|
121 |
+
}
|
122 |
+
updateSelection(e);
|
123 |
+
canvas.renderAll();
|
124 |
+
closeFilters();
|
125 |
+
});
|
126 |
+
|
127 |
+
// A selection has been cleared in the canvas
|
128 |
+
canvas.on('selection:cleared', function (e) {
|
129 |
+
if (!editingpanel && !setting) {
|
130 |
+
updatePanel(false);
|
131 |
+
}
|
132 |
+
$('.layer-selected').removeClass('layer-selected');
|
133 |
+
if (cropping) {
|
134 |
+
crop(cropobj);
|
135 |
+
}
|
136 |
+
closeFilters();
|
137 |
+
});
|
138 |
+
|
139 |
+
function kFormatter(num) {
|
140 |
+
return Math.abs(num) > 999
|
141 |
+
? Math.sign(num) * (Math.abs(num) / 1000).toFixed(1) + 'k'
|
142 |
+
: Math.sign(num) * Math.abs(num);
|
143 |
+
}
|
144 |
+
|
145 |
+
// Zoom in/out of the canvas
|
146 |
+
canvas.on('mouse:wheel', function (opt) {
|
147 |
+
var delta = opt.e.deltaY;
|
148 |
+
var zoom = canvas.getZoom();
|
149 |
+
zoom *= 0.999 ** delta;
|
150 |
+
$('#zoom-level span').html(
|
151 |
+
kFormatter((zoom * 100).toFixed(0)) + '%'
|
152 |
+
);
|
153 |
+
if (zoom > 20) zoom = 20;
|
154 |
+
if (zoom < 0.01) zoom = 0.01;
|
155 |
+
canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom);
|
156 |
+
opt.e.preventDefault();
|
157 |
+
opt.e.stopPropagation();
|
158 |
+
});
|
159 |
+
|
160 |
+
// Start panning if space is down or hand tool is enabled
|
161 |
+
canvas.on('mouse:down', function (opt) {
|
162 |
+
var e = opt.e;
|
163 |
+
if (spaceDown || handtool) {
|
164 |
+
this.isDragging = true;
|
165 |
+
this.selection = false;
|
166 |
+
this.lastPosX = e.clientX;
|
167 |
+
this.lastPosY = e.clientY;
|
168 |
+
}
|
169 |
+
if (opt.target) {
|
170 |
+
opt.target.hasControls = true;
|
171 |
+
wip = false;
|
172 |
+
}
|
173 |
+
});
|
174 |
+
|
175 |
+
// Pan while dragging mouse
|
176 |
+
canvas.on('mouse:move', function (opt) {
|
177 |
+
var pointer = canvas.getPointer(opt.e);
|
178 |
+
canvasx = pointer.x;
|
179 |
+
canvasy = pointer.y;
|
180 |
+
if (this.isDragging) {
|
181 |
+
var e = opt.e;
|
182 |
+
var vpt = this.viewportTransform;
|
183 |
+
vpt[4] += e.clientX - this.lastPosX;
|
184 |
+
vpt[5] += e.clientY - this.lastPosY;
|
185 |
+
this.requestRenderAll();
|
186 |
+
this.lastPosX = e.clientX;
|
187 |
+
this.lastPosY = e.clientY;
|
188 |
+
}
|
189 |
+
});
|
190 |
+
|
191 |
+
// Stop panning
|
192 |
+
canvas.on('mouse:up', function (opt) {
|
193 |
+
this.setViewportTransform(this.viewportTransform);
|
194 |
+
this.isDragging = false;
|
195 |
+
this.selection = true;
|
196 |
+
line_h.opacity = 0;
|
197 |
+
line_v.opacity = 0;
|
198 |
+
});
|
199 |
+
|
200 |
+
// Detect mouse over canvas (for dragging objects from the library)
|
201 |
+
canvas.on('mouse:move', function (e) {
|
202 |
+
overCanvas = true;
|
203 |
+
if (
|
204 |
+
e.target &&
|
205 |
+
!canvas.getActiveObject() &&
|
206 |
+
draggingPanel &&
|
207 |
+
e.target.type == 'image'
|
208 |
+
) {
|
209 |
+
wip = true;
|
210 |
+
e.target.hasControls = false;
|
211 |
+
canvas.setActiveObject(e.target);
|
212 |
+
}
|
213 |
+
});
|
214 |
+
canvas.on('mouse:out', function (e) {
|
215 |
+
overCanvas = false;
|
216 |
+
if (wip) {
|
217 |
+
e.target.hasControls = true;
|
218 |
+
canvas.discardActiveObject();
|
219 |
+
wip = false;
|
220 |
+
canvas.renderAll();
|
221 |
+
}
|
222 |
+
});
|
223 |
+
|
224 |
+
// Double click on image to get into cropping mode
|
225 |
+
fabric.util.addListener(
|
226 |
+
canvas.upperCanvasEl,
|
227 |
+
'dblclick',
|
228 |
+
function (e) {
|
229 |
+
var target = canvas.findTarget(e);
|
230 |
+
if (target) {
|
231 |
+
if (target.type == 'image') {
|
232 |
+
cropImage(target);
|
233 |
+
}
|
234 |
+
}
|
235 |
+
}
|
236 |
+
);
|
237 |
+
|
238 |
+
// Key event handling
|
239 |
+
$(document)
|
240 |
+
.keyup(function (e) {
|
241 |
+
// Space bar (panning and playback)
|
242 |
+
if (
|
243 |
+
e.keyCode == 32 &&
|
244 |
+
!editinglayer &&
|
245 |
+
!editingproject &&
|
246 |
+
$(e.target)[0].tagName != 'INPUT'
|
247 |
+
) {
|
248 |
+
spacerelease = true;
|
249 |
+
spaceDown = false;
|
250 |
+
canvas.defaultCursor = 'default';
|
251 |
+
canvas.renderAll();
|
252 |
+
if (!spacehold) {
|
253 |
+
if (
|
254 |
+
!(
|
255 |
+
canvas.getActiveObject() &&
|
256 |
+
canvas.getActiveObject().isEditing
|
257 |
+
)
|
258 |
+
) {
|
259 |
+
if (paused) {
|
260 |
+
play();
|
261 |
+
} else {
|
262 |
+
pause();
|
263 |
+
}
|
264 |
+
}
|
265 |
+
} else {
|
266 |
+
if (!handtool) {
|
267 |
+
$('#hand-tool').removeClass('hand-active');
|
268 |
+
$('#hand-tool')
|
269 |
+
.find('img')
|
270 |
+
.attr('src', 'assets/hand-tool.svg');
|
271 |
+
}
|
272 |
+
}
|
273 |
+
spacehold = false;
|
274 |
+
}
|
275 |
+
// Delete object/keyframe
|
276 |
+
if (
|
277 |
+
(e.keyCode == 46 ||
|
278 |
+
e.key == 'Delete' ||
|
279 |
+
e.code == 'Delete' ||
|
280 |
+
e.key == 'Backspace') &&
|
281 |
+
!focus &&
|
282 |
+
!editinglayer
|
283 |
+
) {
|
284 |
+
if (
|
285 |
+
$('.show-properties').length > 0 ||
|
286 |
+
shiftkeys.length > 0
|
287 |
+
) {
|
288 |
+
deleteKeyframe();
|
289 |
+
} else {
|
290 |
+
deleteSelection();
|
291 |
+
}
|
292 |
+
}
|
293 |
+
// Shift key is up (stop locking horizontal/vertical object movement)
|
294 |
+
if (e.keyCode == 16) {
|
295 |
+
lockmovement = false;
|
296 |
+
shiftdown = false;
|
297 |
+
}
|
298 |
+
})
|
299 |
+
.keydown(function (e) {
|
300 |
+
// Space bar (panning and playback)
|
301 |
+
if (
|
302 |
+
e.keyCode == 32 &&
|
303 |
+
!editinglayer &&
|
304 |
+
!editingproject &&
|
305 |
+
$(e.target)[0].tagName != 'INPUT'
|
306 |
+
) {
|
307 |
+
spacerelease = false;
|
308 |
+
spaceDown = true;
|
309 |
+
canvas.defaultCursor = 'grab';
|
310 |
+
canvas.renderAll();
|
311 |
+
window.setTimeout(function () {
|
312 |
+
if (!spacerelease) {
|
313 |
+
spacehold = true;
|
314 |
+
if (!handtool) {
|
315 |
+
$('#hand-tool').addClass('hand-active');
|
316 |
+
$('#hand-tool')
|
317 |
+
.find('img')
|
318 |
+
.attr('src', 'assets/hand-tool-active.svg');
|
319 |
+
}
|
320 |
+
}
|
321 |
+
}, 1000);
|
322 |
+
}
|
323 |
+
// Redo
|
324 |
+
if (e.which === 90 && (e.ctrlKey || e.metaKey) && e.shiftKey) {
|
325 |
+
undoRedo(redo, undo, redoarr, undoarr);
|
326 |
+
}
|
327 |
+
// Undo
|
328 |
+
if (e.which === 90 && (e.ctrlKey || e.metaKey)) {
|
329 |
+
undoRedo(undo, redo, undoarr, redoarr);
|
330 |
+
}
|
331 |
+
// Duplicate object
|
332 |
+
if (e.which === 68 && (e.ctrlKey || e.metaKey)) {
|
333 |
+
e.preventDefault();
|
334 |
+
if (canvas.getActiveObject()) {
|
335 |
+
clipboard = canvas.getActiveObject();
|
336 |
+
copyObject();
|
337 |
+
}
|
338 |
+
}
|
339 |
+
// Shift key (Lock horizontal/vertical movement for objects)
|
340 |
+
if (e.shiftKey) {
|
341 |
+
shiftdown = true;
|
342 |
+
lockmovement = true;
|
343 |
+
if (canvas.getActiveObject()) {
|
344 |
+
shiftx = canvas.getActiveObject().get('left');
|
345 |
+
shifty = canvas.getActiveObject().get('top');
|
346 |
+
}
|
347 |
+
}
|
348 |
+
// Return (save layer name)
|
349 |
+
if (e.keyCode === 13 && editinglayer) {
|
350 |
+
saveLayerName();
|
351 |
+
}
|
352 |
+
// Return (save project name)
|
353 |
+
if (e.keyCode === 13 && editingproject) {
|
354 |
+
saveProjectName();
|
355 |
+
}
|
356 |
+
// Left arrow key (move object to the left)
|
357 |
+
if (e.keyCode === 37 && canvas.getActiveObject()) {
|
358 |
+
var obj = canvas.getActiveObject();
|
359 |
+
var step = 2;
|
360 |
+
// Bigger step if shift is down
|
361 |
+
if (e.shiftKey) {
|
362 |
+
step = 7;
|
363 |
+
}
|
364 |
+
obj.left = obj.left - step;
|
365 |
+
canvas.renderAll();
|
366 |
+
autoKeyframe(obj, { action: 'drag' }, false);
|
367 |
+
}
|
368 |
+
// Up arrow key (move object up)
|
369 |
+
if (e.keyCode === 38 && canvas.getActiveObject()) {
|
370 |
+
var obj = canvas.getActiveObject();
|
371 |
+
var step = 2;
|
372 |
+
// Bigger step if shift is down
|
373 |
+
if (e.shiftKey) {
|
374 |
+
step = 7;
|
375 |
+
}
|
376 |
+
obj.top = obj.top - step;
|
377 |
+
canvas.renderAll();
|
378 |
+
autoKeyframe(obj, { action: 'drag' }, false);
|
379 |
+
}
|
380 |
+
// Right arrow key (move object to the right)
|
381 |
+
if (e.keyCode === 39 && canvas.getActiveObject()) {
|
382 |
+
var obj = canvas.getActiveObject();
|
383 |
+
var step = 2;
|
384 |
+
// Bigger step if shift is down
|
385 |
+
if (e.shiftKey) {
|
386 |
+
step = 7;
|
387 |
+
}
|
388 |
+
obj.left = obj.left + step;
|
389 |
+
canvas.renderAll();
|
390 |
+
autoKeyframe(obj, { action: 'drag' }, false);
|
391 |
+
}
|
392 |
+
// Down arrow key (move object down)
|
393 |
+
if (e.keyCode === 40 && canvas.getActiveObject()) {
|
394 |
+
var obj = canvas.getActiveObject();
|
395 |
+
var step = 2;
|
396 |
+
// Bigger step if shift is down
|
397 |
+
if (e.shiftKey) {
|
398 |
+
step = 7;
|
399 |
+
}
|
400 |
+
obj.top = obj.top + step;
|
401 |
+
canvas.renderAll();
|
402 |
+
autoKeyframe(obj, { action: 'drag' }, false);
|
403 |
+
}
|
404 |
+
|
405 |
+
// Move object up layer list
|
406 |
+
if (
|
407 |
+
e.keyCode === 221 &&
|
408 |
+
canvas.getActiveObjects() &&
|
409 |
+
e.metaKey
|
410 |
+
) {
|
411 |
+
if (canvas.getActiveObjects().length == 1) {
|
412 |
+
var obj = canvas.getActiveObject();
|
413 |
+
$(".layer[data-object='" + obj.id + "']")
|
414 |
+
.prev()
|
415 |
+
.insertAfter($(".layer[data-object='" + obj.id + "']"));
|
416 |
+
$('#' + obj.id)
|
417 |
+
.prev()
|
418 |
+
.insertAfter($('#' + obj.id));
|
419 |
+
orderLayers();
|
420 |
+
} else {
|
421 |
+
canvas.getActiveObjects().forEach(function (obj) {
|
422 |
+
$(".layer[data-object='" + obj.id + "']")
|
423 |
+
.prev()
|
424 |
+
.insertAfter($(".layer[data-object='" + obj.id + "']"));
|
425 |
+
$('#' + obj.id)
|
426 |
+
.prev()
|
427 |
+
.insertAfter($('#' + obj.id));
|
428 |
+
orderLayers();
|
429 |
+
});
|
430 |
+
}
|
431 |
+
}
|
432 |
+
|
433 |
+
// Move object down layer list
|
434 |
+
if (
|
435 |
+
e.keyCode === 219 &&
|
436 |
+
canvas.getActiveObjects() &&
|
437 |
+
e.metaKey
|
438 |
+
) {
|
439 |
+
if (canvas.getActiveObjects().length == 1) {
|
440 |
+
var obj = canvas.getActiveObject();
|
441 |
+
$(".layer[data-object='" + obj.id + "']")
|
442 |
+
.next()
|
443 |
+
.insertBefore($(".layer[data-object='" + obj.id + "']"));
|
444 |
+
$('#' + obj.id)
|
445 |
+
.next()
|
446 |
+
.insertBefore($('#' + obj.id));
|
447 |
+
orderLayers();
|
448 |
+
} else {
|
449 |
+
canvas.getActiveObjects().forEach(function (obj) {
|
450 |
+
$(".layer[data-object='" + obj.id + "']")
|
451 |
+
.next()
|
452 |
+
.insertBefore(
|
453 |
+
$(".layer[data-object='" + obj.id + "']")
|
454 |
+
);
|
455 |
+
$('#' + obj.id)
|
456 |
+
.next()
|
457 |
+
.insertBefore($('#' + obj.id));
|
458 |
+
orderLayers();
|
459 |
+
});
|
460 |
+
}
|
461 |
+
}
|
462 |
+
|
463 |
+
// Move object top of layer list
|
464 |
+
if (
|
465 |
+
e.keyCode === 221 &&
|
466 |
+
canvas.getActiveObjects() &&
|
467 |
+
e.altKey
|
468 |
+
) {
|
469 |
+
if (canvas.getActiveObjects().length == 1) {
|
470 |
+
var obj = canvas.getActiveObject();
|
471 |
+
$('#layer-inner-list').prepend(
|
472 |
+
$(".layer[data-object='" + obj.id + "']")
|
473 |
+
);
|
474 |
+
$('#inner-timeline').prepend($('#' + obj.id));
|
475 |
+
orderLayers();
|
476 |
+
} else {
|
477 |
+
canvas.getActiveObjects().forEach(function (obj) {
|
478 |
+
$('#layer-inner-list').prepend(
|
479 |
+
$(".layer[data-object='" + obj.id + "']")
|
480 |
+
);
|
481 |
+
$('#inner-timeline').prepend($('#' + obj.id));
|
482 |
+
orderLayers();
|
483 |
+
});
|
484 |
+
}
|
485 |
+
}
|
486 |
+
|
487 |
+
// Move object bottom of layer list
|
488 |
+
if (e.keyCode === 219 && canvas.getActiveObject() && e.altKey) {
|
489 |
+
if (canvas.getActiveObjects().length == 1) {
|
490 |
+
var obj = canvas.getActiveObject();
|
491 |
+
$('#layer-inner-list').append(
|
492 |
+
$(".layer[data-object='" + obj.id + "']")
|
493 |
+
);
|
494 |
+
$('#inner-timeline').append($('#' + obj.id));
|
495 |
+
orderLayers();
|
496 |
+
} else {
|
497 |
+
canvas.getActiveObjects().forEach(function (obj) {
|
498 |
+
$('#layer-inner-list').append(
|
499 |
+
$(".layer[data-object='" + obj.id + "']")
|
500 |
+
);
|
501 |
+
$('#inner-timeline').append($('#' + obj.id));
|
502 |
+
orderLayers();
|
503 |
+
});
|
504 |
+
}
|
505 |
+
}
|
506 |
+
|
507 |
+
// Zoom in
|
508 |
+
if (e.keyCode === 187 && e.shiftKey) {
|
509 |
+
var zoom = canvas.getZoom() + 0.2;
|
510 |
+
if (zoom > 20) zoom = 20;
|
511 |
+
if (zoom < 0.01) zoom = 0.01;
|
512 |
+
canvas.setZoom(1);
|
513 |
+
canvas.renderAll();
|
514 |
+
var vpw = canvas.width / zoom;
|
515 |
+
var vph = canvas.height / zoom;
|
516 |
+
var x = artboard.left + artboard.width / 2 - vpw / 2;
|
517 |
+
var y = artboard.top + artboard.height / 2 - vph / 2;
|
518 |
+
canvas.absolutePan({ x: x, y: y });
|
519 |
+
canvas.setZoom(zoom);
|
520 |
+
canvas.renderAll();
|
521 |
+
$('#zoom-level span').html(
|
522 |
+
(canvas.getZoom() * 100).toFixed(0) + '%'
|
523 |
+
);
|
524 |
+
}
|
525 |
+
|
526 |
+
// Zoom out
|
527 |
+
if (e.keyCode === 189 && e.shiftKey) {
|
528 |
+
var zoom = canvas.getZoom() - 0.2;
|
529 |
+
if (zoom > 20) zoom = 20;
|
530 |
+
if (zoom < 0.01) zoom = 0.01;
|
531 |
+
canvas.setZoom(1);
|
532 |
+
canvas.renderAll();
|
533 |
+
var vpw = canvas.width / zoom;
|
534 |
+
var vph = canvas.height / zoom;
|
535 |
+
var x = artboard.left + artboard.width / 2 - vpw / 2;
|
536 |
+
var y = artboard.top + artboard.height / 2 - vph / 2;
|
537 |
+
canvas.absolutePan({ x: x, y: y });
|
538 |
+
canvas.setZoom(zoom);
|
539 |
+
canvas.renderAll();
|
540 |
+
$('#zoom-level span').html(
|
541 |
+
(canvas.getZoom() * 100).toFixed(0) + '%'
|
542 |
+
);
|
543 |
+
}
|
544 |
+
});
|
545 |
+
|
546 |
+
// Copy event
|
547 |
+
window.addEventListener('copy', function (e) {
|
548 |
+
// Copy selected object
|
549 |
+
if (
|
550 |
+
canvas.getActiveObject() &&
|
551 |
+
shiftkeys.length == 0 &&
|
552 |
+
!canvas.getActiveObject().isEditing
|
553 |
+
) {
|
554 |
+
var emptyInp = document.getElementById('emptyInput');
|
555 |
+
emptyInp.select();
|
556 |
+
emptyInp.focus();
|
557 |
+
setTimeout(function () {
|
558 |
+
document.execCommand('copy');
|
559 |
+
}, 0);
|
560 |
+
clipboard = canvas.getActiveObject();
|
561 |
+
cliptype = 'object';
|
562 |
+
// Copy selected keyframe(s)
|
563 |
+
} else if (
|
564 |
+
shiftkeys.length > 0 &&
|
565 |
+
!canvas.getActiveObject().isEditing
|
566 |
+
) {
|
567 |
+
var emptyInp = document.getElementById('emptyInput');
|
568 |
+
emptyInp.select();
|
569 |
+
emptyInp.focus();
|
570 |
+
setTimeout(function () {
|
571 |
+
document.execCommand('copy');
|
572 |
+
}, 0);
|
573 |
+
clipboard = [];
|
574 |
+
shiftkeys.forEach(function (keyframe) {
|
575 |
+
var drag = $(keyframe.keyframe);
|
576 |
+
var keyarr = $.grep(keyframes, function (e) {
|
577 |
+
return (
|
578 |
+
e.t == drag.attr('data-time') &&
|
579 |
+
e.id == drag.attr('data-object') &&
|
580 |
+
e.name == drag.attr('data-property')
|
581 |
+
);
|
582 |
+
});
|
583 |
+
clipboard.push(keyarr[0]);
|
584 |
+
});
|
585 |
+
cliptype = 'keyframe';
|
586 |
+
}
|
587 |
+
});
|
588 |
+
|
589 |
+
// Paste event
|
590 |
+
window.addEventListener('paste', function (e) {
|
591 |
+
var imgs = e.clipboardData.items;
|
592 |
+
if (imgs == undefined) return false;
|
593 |
+
|
594 |
+
// Paste object or keyframe(s)
|
595 |
+
if (imgs.length == 1 && e.clipboardData.getData('text') == ' ') {
|
596 |
+
copyObject();
|
597 |
+
// Paste external image (by uploading it)
|
598 |
+
} else {
|
599 |
+
for (var i = 0; i < imgs.length; i++) {
|
600 |
+
if (imgs[i].type.indexOf('image') == -1) continue;
|
601 |
+
var imgObj = imgs[i].getAsFile();
|
602 |
+
if (imgObj.size / 1024 / 1024 <= 10) {
|
603 |
+
createThumbnail(imgObj, 250).then(function (data) {
|
604 |
+
saveFile(
|
605 |
+
dataURItoBlob(data),
|
606 |
+
imgObj,
|
607 |
+
imgObj['type'].split('/')[0],
|
608 |
+
'temp',
|
609 |
+
true,
|
610 |
+
true
|
611 |
+
);
|
612 |
+
});
|
613 |
+
} else {
|
614 |
+
alert('Image is too big');
|
615 |
+
}
|
616 |
+
}
|
617 |
+
}
|
618 |
+
});
|
619 |
+
|
620 |
+
// Stop cropping when clicking on the blacked out properties panel
|
621 |
+
$(document).on('click', '#properties-overlay', function () {
|
622 |
+
if (cropping) {
|
623 |
+
canvas.discardActiveObject();
|
624 |
+
}
|
625 |
+
});
|
626 |
+
|
627 |
+
// Scroll horizontally through assets in the library
|
628 |
+
$(document).on('click', '.right-arrow', function () {
|
629 |
+
$(this).parent().animate({ scrollLeft: '+=1000' }, 500);
|
630 |
+
});
|
631 |
+
$(document).on('click', '.left-arrow', function () {
|
632 |
+
$(this).parent().animate({ scrollLeft: '-=1000' }, 500);
|
633 |
+
});
|
634 |
+
|
635 |
+
// Playback
|
636 |
+
$(document).on('click', '#play-button', function () {
|
637 |
+
if (paused) {
|
638 |
+
play();
|
639 |
+
} else {
|
640 |
+
pause();
|
641 |
+
}
|
642 |
+
});
|
643 |
+
|
644 |
+
// Detect when not clicking on certain elements
|
645 |
+
$(document).on('mousedown', function (e) {
|
646 |
+
// De-select keyframes
|
647 |
+
if (
|
648 |
+
!$('#keyframe-properties').is(e.target) &&
|
649 |
+
$('#keyframe-properties').has(e.target).length === 0 &&
|
650 |
+
!$('.keyframe').is(e.target) &&
|
651 |
+
$('.keyframe').has(e.target).length === 0
|
652 |
+
) {
|
653 |
+
$('#keyframe-properties').removeClass('show-properties');
|
654 |
+
$('.keyframe-selected').removeClass('keyframe-selected');
|
655 |
+
shiftkeys = [];
|
656 |
+
}
|
657 |
+
|
658 |
+
// Hide color picker
|
659 |
+
if (
|
660 |
+
!$('.object-color').is(e.target) &&
|
661 |
+
$('.object-color').has(e.target).length === 0 &&
|
662 |
+
!$('.pcr-app').is(e.target) &&
|
663 |
+
$('.prc-app').has(e.target).length === 0 &&
|
664 |
+
!$('.pcr-selection').is(e.target) &&
|
665 |
+
$('.pcr-selection').has(e.target).length === 0 &&
|
666 |
+
!$('.pcr-swatches').is(e.target) &&
|
667 |
+
$('.pcr-swatches').has(e.target).length === 0 &&
|
668 |
+
!$('.pcr-interaction').is(e.target) &&
|
669 |
+
$('.pcr-interaction').has(e.target).length === 0
|
670 |
+
) {
|
671 |
+
o_fill.hide();
|
672 |
+
}
|
673 |
+
|
674 |
+
// Hide zoom controls
|
675 |
+
if (
|
676 |
+
!$('#other-controls').is(e.target) &&
|
677 |
+
$('#other-controls').has(e.target).length === 0
|
678 |
+
) {
|
679 |
+
$('#zoom-options').addClass('zoom-hidden');
|
680 |
+
$('#zoom-level img').removeClass('zoom-open');
|
681 |
+
}
|
682 |
+
|
683 |
+
// Hide speed settings
|
684 |
+
if (
|
685 |
+
!$('#speed').is(e.target) &&
|
686 |
+
$('#speed').has(e.target).length === 0
|
687 |
+
) {
|
688 |
+
$('#speed-settings').removeClass('show-speed');
|
689 |
+
$('#speed-arrow').removeClass('arrow-on');
|
690 |
+
}
|
691 |
+
|
692 |
+
// Hide more menu
|
693 |
+
if (
|
694 |
+
!$('#more-tool').is(e.target) &&
|
695 |
+
$('#more-tool').has(e.target).length === 0 &&
|
696 |
+
!$('#more-over').is(e.target) &&
|
697 |
+
$('#more-over').has(e.target).length === 0
|
698 |
+
) {
|
699 |
+
hideMore();
|
700 |
+
}
|
701 |
+
});
|
702 |
+
|
703 |
+
// Detect focus on an input in the properties
|
704 |
+
$(document)
|
705 |
+
.on('focus', '.property-input', function () {
|
706 |
+
focus = true;
|
707 |
+
})
|
708 |
+
.on('focusout', function () {
|
709 |
+
focus = false;
|
710 |
+
});
|
711 |
+
|
712 |
+
// Toggle zoom dropdown
|
713 |
+
$(document).on('click', '#zoom-level', function () {
|
714 |
+
$('#zoom-options').toggleClass('zoom-hidden');
|
715 |
+
$('#zoom-level img').toggleClass('zoom-open');
|
716 |
+
});
|
717 |
+
|
718 |
+
// Skip to the beginning or end
|
719 |
+
$(document).on('click', '#skip-backward', function () {
|
720 |
+
animate(false, 0);
|
721 |
+
$('#seekbar').offset({
|
722 |
+
left:
|
723 |
+
offset_left +
|
724 |
+
$('#inner-timeline').offset().left +
|
725 |
+
currenttime / timelinetime,
|
726 |
+
});
|
727 |
+
});
|
728 |
+
$(document).on('click', '#skip-forward', function () {
|
729 |
+
animate(false, duration);
|
730 |
+
$('#seekbar').offset({
|
731 |
+
left:
|
732 |
+
offset_left +
|
733 |
+
$('#inner-timeline').offset().left +
|
734 |
+
currenttime / timelinetime,
|
735 |
+
});
|
736 |
+
});
|
737 |
+
|
738 |
+
// Change layer name
|
739 |
+
$(document).on('dblclick', '.layer-custom-name', function () {
|
740 |
+
$(this).prop('readonly', false);
|
741 |
+
$(this).addClass('name-active');
|
742 |
+
$(this).focus();
|
743 |
+
document.execCommand('selectAll', false, null);
|
744 |
+
editinglayer = true;
|
745 |
+
});
|
746 |
+
|
747 |
+
// Trigger file picker when clicking the upload button
|
748 |
+
$(document).on('click', '#upload-button', function () {
|
749 |
+
$('#upload-popup').addClass('upload-show');
|
750 |
+
});
|
751 |
+
|
752 |
+
$(document).on('click', '#upload-overlay', function () {
|
753 |
+
$('.upload-show').removeClass('upload-show');
|
754 |
+
});
|
755 |
+
|
756 |
+
$(document).on('click', '#upload-popup-close', function () {
|
757 |
+
$('.upload-show').removeClass('upload-show');
|
758 |
+
});
|
759 |
+
|
760 |
+
$(document).on('click', '#upload-drop-area', function () {
|
761 |
+
$('#filepick').click();
|
762 |
+
});
|
763 |
+
|
764 |
+
$(document).on('dragover', function (e) {
|
765 |
+
e.preventDefault();
|
766 |
+
e.stopPropagation();
|
767 |
+
});
|
768 |
+
|
769 |
+
$(document).on('dragover', '#upload-drop-area', function (e) {
|
770 |
+
e.preventDefault();
|
771 |
+
e.stopPropagation();
|
772 |
+
$('#upload-drop-area').addClass('dropping');
|
773 |
+
});
|
774 |
+
|
775 |
+
$(document).on('dragenter', '#upload-drop-area', function (e) {
|
776 |
+
e.preventDefault();
|
777 |
+
e.stopPropagation();
|
778 |
+
$('#upload-drop-area').addClass('dropping');
|
779 |
+
});
|
780 |
+
|
781 |
+
$(document).on('drop', function (e) {
|
782 |
+
e.preventDefault();
|
783 |
+
e.stopPropagation();
|
784 |
+
$('#upload-drop-area').removeClass('dropping');
|
785 |
+
handleUpload(e);
|
786 |
+
});
|
787 |
+
|
788 |
+
$(document).on('dragleave', function () {
|
789 |
+
$('#upload-drop-area').removeClass('dropping');
|
790 |
+
});
|
791 |
+
|
792 |
+
$(document).on('dragend', function () {
|
793 |
+
$('#upload-drop-area').removeClass('dropping');
|
794 |
+
});
|
795 |
+
|
796 |
+
// Upload or remove background audio
|
797 |
+
$(document).on('click', '#audio-upload-button', function () {
|
798 |
+
$('#filepick2').click();
|
799 |
+
});
|
800 |
+
|
801 |
+
// Sync scrolling for the timeline
|
802 |
+
syncScroll($('#layer-inner-list'), $('#timeline'));
|
803 |
+
syncScrollHoz($('#timeline'), $('#seekarea'));
|
804 |
+
|
805 |
+
// Initialize layer sorting
|
806 |
+
sortable('#layer-inner-list', {
|
807 |
+
customDragImage: (draggedElement, elementOffset, event) => {
|
808 |
+
return {
|
809 |
+
element: document.getElementById('nothing'),
|
810 |
+
posX: event.pageX - elementOffset.left,
|
811 |
+
posY: event.pageY - elementOffset.top,
|
812 |
+
};
|
813 |
+
},
|
814 |
+
})[0].addEventListener('sortstop', function (e) {
|
815 |
+
const id = $(e.detail.item).attr('data-object');
|
816 |
+
const previd = $(e.detail.item).prev().attr('data-object');
|
817 |
+
if ($('.sortable-dragging').length == 1) {
|
818 |
+
$('.sortable-dragging').remove();
|
819 |
+
if (previd == undefined) {
|
820 |
+
$('#inner-timeline').prepend($('#' + id));
|
821 |
+
} else {
|
822 |
+
$('#' + id).insertAfter($('#' + previd));
|
823 |
+
}
|
824 |
+
orderLayers();
|
825 |
+
}
|
826 |
+
});
|
827 |
+
|
828 |
+
// Initialize dropdown for keyframe easing
|
829 |
+
$('#easing select').niceSelect();
|
830 |
+
|
831 |
+
// Initialize properties panel
|
832 |
+
updatePanel(false);
|
833 |
+
|
834 |
+
// Initialize library
|
835 |
+
updateBrowser('shape-tool');
|
836 |
+
|
837 |
+
function initFilterSliders() {
|
838 |
+
var filters = [
|
839 |
+
'filter-brightness',
|
840 |
+
'filter-contrast',
|
841 |
+
'filter-saturation',
|
842 |
+
'filter-hue',
|
843 |
+
'filter-vibrance',
|
844 |
+
];
|
845 |
+
filters.forEach(function (filter) {
|
846 |
+
var selectme = document.getElementById(filter);
|
847 |
+
var slider = new RangeSlider(selectme, {
|
848 |
+
design: '2d',
|
849 |
+
theme: 'default',
|
850 |
+
handle: 'round',
|
851 |
+
popup: null,
|
852 |
+
showMinMaxLabels: false,
|
853 |
+
unit: '%',
|
854 |
+
min: -100,
|
855 |
+
max: 100,
|
856 |
+
value: 0,
|
857 |
+
step: 1,
|
858 |
+
onmove: function (x) {
|
859 |
+
if (canvas.getActiveObject()) {
|
860 |
+
var obj = canvas.getActiveObject();
|
861 |
+
if (filter == 'filter-brightness') {
|
862 |
+
if (obj.filters.find((i) => i.type == 'Brightness')) {
|
863 |
+
obj.filters.find(
|
864 |
+
(i) => i.type == 'Brightness'
|
865 |
+
).brightness = x / 100;
|
866 |
+
} else {
|
867 |
+
obj.filters.push(
|
868 |
+
new f.Brightness({ brightness: x / 100 })
|
869 |
+
);
|
870 |
+
}
|
871 |
+
} else if (filter == 'filter-contrast') {
|
872 |
+
if (obj.filters.find((i) => i.type == 'Contrast')) {
|
873 |
+
obj.filters.find(
|
874 |
+
(i) => i.type == 'Contrast'
|
875 |
+
).contrast = x / 100;
|
876 |
+
} else {
|
877 |
+
obj.filters.push(
|
878 |
+
new f.Contrast({ contrast: x / 100 })
|
879 |
+
);
|
880 |
+
}
|
881 |
+
} else if (filter == 'filter-saturation') {
|
882 |
+
if (obj.filters.find((i) => i.type == 'Saturation')) {
|
883 |
+
obj.filters.find(
|
884 |
+
(i) => i.type == 'Saturation'
|
885 |
+
).saturation = x / 100;
|
886 |
+
} else {
|
887 |
+
obj.filters.push(
|
888 |
+
new f.Saturation({ saturation: x / 100 })
|
889 |
+
);
|
890 |
+
}
|
891 |
+
} else if (filter == 'filter-vibrance') {
|
892 |
+
if (obj.filters.find((i) => i.type == 'Vibrance')) {
|
893 |
+
obj.filters.find(
|
894 |
+
(i) => i.type == 'Vibrance'
|
895 |
+
).vibrance = x / 100;
|
896 |
+
} else {
|
897 |
+
obj.filters.push(
|
898 |
+
new f.Vibrance({ vibrance: x / 100 })
|
899 |
+
);
|
900 |
+
}
|
901 |
+
} else if (filter == 'filter-hue') {
|
902 |
+
if (obj.filters.find((i) => i.type == 'HueRotation')) {
|
903 |
+
obj.filters.find(
|
904 |
+
(i) => i.type == 'HueRotation'
|
905 |
+
).rotation = x / 100;
|
906 |
+
} else {
|
907 |
+
obj.filters.push(
|
908 |
+
new f.HueRotation({ rotation: x / 100 })
|
909 |
+
);
|
910 |
+
}
|
911 |
+
}
|
912 |
+
obj.applyFilters();
|
913 |
+
canvas.renderAll();
|
914 |
+
}
|
915 |
+
},
|
916 |
+
onfinish: function (x) {
|
917 |
+
save();
|
918 |
+
},
|
919 |
+
});
|
920 |
+
sliders.push({ name: filter, slider: slider });
|
921 |
+
});
|
922 |
+
}
|
923 |
+
|
924 |
+
var selectchroma = document.getElementById('chroma-distance');
|
925 |
+
chromaslider = new RangeSlider(selectchroma, {
|
926 |
+
design: '2d',
|
927 |
+
theme: 'default',
|
928 |
+
handle: 'round',
|
929 |
+
popup: null,
|
930 |
+
showMinMaxLabels: false,
|
931 |
+
unit: '%',
|
932 |
+
min: 1,
|
933 |
+
max: 100,
|
934 |
+
value: 1,
|
935 |
+
step: 1,
|
936 |
+
onmove: function (x) {
|
937 |
+
if (canvas.getActiveObject()) {
|
938 |
+
var obj = canvas.getActiveObject();
|
939 |
+
if (obj.filters.find((x) => x.type == 'RemoveColor')) {
|
940 |
+
obj.filters.find((x) => x.type == 'RemoveColor').distance =
|
941 |
+
x / 100;
|
942 |
+
}
|
943 |
+
obj.applyFilters();
|
944 |
+
canvas.renderAll();
|
945 |
+
}
|
946 |
+
},
|
947 |
+
onfinish: function (x) {
|
948 |
+
save();
|
949 |
+
},
|
950 |
+
});
|
951 |
+
|
952 |
+
var selectnoise = document.getElementById('filter-noise');
|
953 |
+
noiseslider = new RangeSlider(selectnoise, {
|
954 |
+
design: '2d',
|
955 |
+
theme: 'default',
|
956 |
+
handle: 'round',
|
957 |
+
popup: null,
|
958 |
+
showMinMaxLabels: false,
|
959 |
+
unit: '%',
|
960 |
+
min: 0,
|
961 |
+
max: 1000,
|
962 |
+
value: 0,
|
963 |
+
step: 1,
|
964 |
+
onmove: function (x) {
|
965 |
+
if (canvas.getActiveObject()) {
|
966 |
+
var obj = canvas.getActiveObject();
|
967 |
+
if (obj.filters.find((x) => x.type == 'Noise')) {
|
968 |
+
obj.filters.find((x) => x.type == 'Noise').noise = x;
|
969 |
+
} else {
|
970 |
+
obj.filters.push(
|
971 |
+
new f.Noise({
|
972 |
+
noise: x,
|
973 |
+
})
|
974 |
+
);
|
975 |
+
}
|
976 |
+
obj.applyFilters();
|
977 |
+
canvas.renderAll();
|
978 |
+
}
|
979 |
+
},
|
980 |
+
onfinish: function (x) {
|
981 |
+
save();
|
982 |
+
},
|
983 |
+
});
|
984 |
+
|
985 |
+
var selectblur = document.getElementById('filter-blur');
|
986 |
+
blurslider = new RangeSlider(selectblur, {
|
987 |
+
design: '2d',
|
988 |
+
theme: 'default',
|
989 |
+
handle: 'round',
|
990 |
+
popup: null,
|
991 |
+
showMinMaxLabels: false,
|
992 |
+
unit: '%',
|
993 |
+
min: 0,
|
994 |
+
max: 100,
|
995 |
+
value: 0,
|
996 |
+
step: 1,
|
997 |
+
onmove: function (x) {
|
998 |
+
if (canvas.getActiveObject()) {
|
999 |
+
var obj = canvas.getActiveObject();
|
1000 |
+
if (obj.filters.find((x) => x.type == 'Blur')) {
|
1001 |
+
obj.filters.find((x) => x.type == 'Blur').blur = x / 100;
|
1002 |
+
} else {
|
1003 |
+
obj.filters.push(
|
1004 |
+
new f.Blur({
|
1005 |
+
blur: x / 100,
|
1006 |
+
})
|
1007 |
+
);
|
1008 |
+
}
|
1009 |
+
}
|
1010 |
+
obj.applyFilters();
|
1011 |
+
canvas.renderAll();
|
1012 |
+
},
|
1013 |
+
onfinish: function (x) {
|
1014 |
+
save();
|
1015 |
+
},
|
1016 |
+
});
|
1017 |
+
|
1018 |
+
$('#filters-list').val('none');
|
1019 |
+
$('#filters-list').niceSelect();
|
1020 |
+
|
1021 |
+
initFilterSliders();
|
1022 |
+
});
|
js/functions.js
ADDED
The diff for this file is too large to render.
See raw diff
|
|
js/init.js
ADDED
@@ -0,0 +1,1075 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var API_KEY = 'PIXABAY_API';
|
2 |
+
var GOOGLE_FONTS_API_KEY = 'GOOGLE_FONTS_API_KEY';
|
3 |
+
|
4 |
+
// for legacy browsers
|
5 |
+
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
6 |
+
const audioContext = new AudioContext();
|
7 |
+
var oldsrc, oldobj;
|
8 |
+
var oldtimelinepos;
|
9 |
+
var speed = 1;
|
10 |
+
var page = 1;
|
11 |
+
var checkstatus = false;
|
12 |
+
let db = new Localbase('db');
|
13 |
+
var wip = false;
|
14 |
+
var paused = true;
|
15 |
+
var currenttime = 0;
|
16 |
+
var timelinetime = 5;
|
17 |
+
const offset_left = 20;
|
18 |
+
var duration = 30000;
|
19 |
+
var keyframes = [];
|
20 |
+
var p_keyframes = [];
|
21 |
+
var props = [
|
22 |
+
'left',
|
23 |
+
'top',
|
24 |
+
'scaleX',
|
25 |
+
'scaleY',
|
26 |
+
'width',
|
27 |
+
'height',
|
28 |
+
'angle',
|
29 |
+
'opacity',
|
30 |
+
'fill',
|
31 |
+
'strokeWidth',
|
32 |
+
'stroke',
|
33 |
+
'shadow.color',
|
34 |
+
'shadow.opacity',
|
35 |
+
'shadow.offsetX',
|
36 |
+
'shadow.offsetY',
|
37 |
+
'shadow.blur',
|
38 |
+
'charSpacing',
|
39 |
+
'lineHeight',
|
40 |
+
];
|
41 |
+
var objects = [];
|
42 |
+
var o_slider, o_letter_slider, o_line_slider;
|
43 |
+
var colormode = 'fill';
|
44 |
+
var spaceDown = false;
|
45 |
+
var selectedkeyframe;
|
46 |
+
var undo = [];
|
47 |
+
var undoarr = [];
|
48 |
+
var redo = [];
|
49 |
+
var groups = [];
|
50 |
+
var redoarr = [];
|
51 |
+
var state;
|
52 |
+
var statearr = [];
|
53 |
+
var recording = false;
|
54 |
+
var canvasrecord;
|
55 |
+
var clipboard;
|
56 |
+
var focus = false;
|
57 |
+
var editingpanel = false;
|
58 |
+
var files = [];
|
59 |
+
var re = /(?:\.([^.]+))?$/;
|
60 |
+
var filelist = [];
|
61 |
+
var timeout;
|
62 |
+
var spacehold = false;
|
63 |
+
var spacerelease = false;
|
64 |
+
var tempselection;
|
65 |
+
var line_h, line_v;
|
66 |
+
var tempgroup = [];
|
67 |
+
var editinggroup = false;
|
68 |
+
var tempgroupid;
|
69 |
+
var fontPicker;
|
70 |
+
var fonts = [];
|
71 |
+
var seeking = false;
|
72 |
+
var setting = false;
|
73 |
+
var handtool = false;
|
74 |
+
var canvasx = 0;
|
75 |
+
var canvasy = 0;
|
76 |
+
var overCanvas = false;
|
77 |
+
var draggingPanel = false;
|
78 |
+
var cropping = false;
|
79 |
+
var cropobj;
|
80 |
+
var cropscalex;
|
81 |
+
var cropscaley;
|
82 |
+
var croptop;
|
83 |
+
var cropleft;
|
84 |
+
var layer_count = 1;
|
85 |
+
var lockmovement = false;
|
86 |
+
var shiftx = 0;
|
87 |
+
var shifty = 0;
|
88 |
+
var editinglayer = false;
|
89 |
+
var editingproject = false;
|
90 |
+
var shiftkeys = [];
|
91 |
+
var shiftdown = false;
|
92 |
+
var cliptype = 'object';
|
93 |
+
var chromaslider, noiseslider, blurslider;
|
94 |
+
var isChrome =
|
95 |
+
window.chrome && Object.values(window.chrome).length !== 0;
|
96 |
+
var eyeDropper;
|
97 |
+
if (isChrome) {
|
98 |
+
eyeDropper = new EyeDropper();
|
99 |
+
}
|
100 |
+
var presets = [
|
101 |
+
{
|
102 |
+
name: 'Dribbble shot',
|
103 |
+
id: 'dribbble',
|
104 |
+
width: 1600,
|
105 |
+
height: 1200,
|
106 |
+
},
|
107 |
+
{ name: 'Facebook post', id: 'facebook', width: 1280, height: 720 },
|
108 |
+
{
|
109 |
+
name: 'Facebook ad',
|
110 |
+
id: 'facebook-ad',
|
111 |
+
width: 1080,
|
112 |
+
height: 1080,
|
113 |
+
},
|
114 |
+
{ name: 'Youtube video', id: 'youtube', width: 1920, height: 1080 },
|
115 |
+
{
|
116 |
+
name: 'Instagram video',
|
117 |
+
id: 'instagram-id',
|
118 |
+
width: 1080,
|
119 |
+
height: 1920,
|
120 |
+
},
|
121 |
+
{
|
122 |
+
name: 'Instagram stories',
|
123 |
+
id: 'instagram-stories',
|
124 |
+
width: 1080,
|
125 |
+
height: 1920,
|
126 |
+
},
|
127 |
+
{ name: 'Twitter video', id: 'twitter', width: 1280, height: 720 },
|
128 |
+
{ name: 'Snapchat ad', id: 'snapchat', width: 1080, height: 1920 },
|
129 |
+
{
|
130 |
+
name: 'LinkedIn video',
|
131 |
+
id: 'linkedin',
|
132 |
+
width: 1920,
|
133 |
+
height: 1080,
|
134 |
+
},
|
135 |
+
{
|
136 |
+
name: 'Product Hunt thumbnail',
|
137 |
+
id: 'product-hunt',
|
138 |
+
width: 600,
|
139 |
+
height: 600,
|
140 |
+
},
|
141 |
+
{
|
142 |
+
name: 'Pinterest ad',
|
143 |
+
id: 'pinterest',
|
144 |
+
width: 1080,
|
145 |
+
height: 1920,
|
146 |
+
},
|
147 |
+
];
|
148 |
+
var activepreset = 'custom';
|
149 |
+
var uploaded_images = [];
|
150 |
+
var uploaded_videos = [];
|
151 |
+
var uploading = false;
|
152 |
+
var background_audio = false;
|
153 |
+
var temp_audio = false;
|
154 |
+
var background_key;
|
155 |
+
var sliders = [];
|
156 |
+
var hovertime = 0;
|
157 |
+
var animatedtext = [];
|
158 |
+
|
159 |
+
// Get list of fonts
|
160 |
+
$.ajax({
|
161 |
+
url:
|
162 |
+
'https://www.googleapis.com/webfonts/v1/webfonts?key=' +
|
163 |
+
GOOGLE_FONTS_API_KEY +
|
164 |
+
'&sort=alpha',
|
165 |
+
type: 'GET',
|
166 |
+
dataType: 'json', // added data type
|
167 |
+
success: function (response) {
|
168 |
+
response.items.forEach(function (item) {
|
169 |
+
fonts.push(item.family);
|
170 |
+
});
|
171 |
+
},
|
172 |
+
});
|
173 |
+
|
174 |
+
// Panel variants
|
175 |
+
const canvas_panel =
|
176 |
+
'<div id="canvas-properties" class="panel-section"><p class="property-title">Canvas settings</p><table><tr><th class="name-col">Preset</th><th class="value-col"><select id="preset"></select></th></tr><tr><th class="name-col">Size</th><th class="value-col"><div id="canvas-w" class="property-input" data-label="W"><input type="number" min=1 value=1000></div><div id="canvas-h" class="property-input" data-label="H"><input type="number" value=1000 min=1></div></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="canvas-color" class="object-color"><div id="color-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="canvas-color-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Duration</th><th class="value-col" id="duration-cell"><div id="canvas-duration" class="property-input" data-label="s"><input type="number" value=15.00></div></th></tr></table></div>';
|
177 |
+
const object_panel =
|
178 |
+
'<div id="layout-properties" class="panel-section"><p class="property-title">Layout</p><table><tr><th class="name-col">Position</th><th class="value-col"><div id="object-x" class="property-input" data-label="X"><input type="number" value=1000></div><div id="object-y" class="property-input" data-label="Y"><input value=1000 type="number"></div></th></tr><tr><th class="name-col">Size</th><th class="value-col"><div id="object-w" class="property-input" data-label="W"><input type="number" min=1 value=1000></div><div id="object-h" class="property-input" data-label="H"><input type="number" value=1000 min=1></div></th></tr><tr><th class="name-col">Rotation</th><th class="value-col" id="duration-cell"><div id="object-r" class="property-input" data-label="°"><input type="number" min=0 max=360 value=0></div></th></tr></table></div>';
|
179 |
+
const back_panel =
|
180 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Mask</th><th class="value-col"><select id="masks"><option value="none">None</option></select></th></tr></table></div>';
|
181 |
+
const image_panel =
|
182 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Mask</th><th class="value-col"><select id="masks"><option value="none">None</option></select></th></tr></table></div>';
|
183 |
+
const selection_panel =
|
184 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Group</th><th class="value-col"><div id="group-objects">Group selection</div></th></tr></table></div>';
|
185 |
+
const group_panel =
|
186 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Mask</th><th class="value-col"><select id="masks"><option value="none">None</option></select></th></tr><tr><th class="name-col">Group</th><th class="value-col"><div id="ungroup-objects">Ungroup selection</div></th></tr></table></div>';
|
187 |
+
const other_panel =
|
188 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Layer</p><table><tr><th class="name-col">Opacity</th><th class="value-col"><div id="select-opacity"></div><div id="object-o" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Mask</th><th class="value-col"><select id="masks"><option value="none">None</option></select></th></tr></table></div>';
|
189 |
+
const shape_panel =
|
190 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Rectangle</p><table><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-fill" class="object-color"><div id="color-fill-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-fill-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Radius</th><th class="value-col" id="duration-cell"><div id="object-corners" class="property-input" data-label="px"><input type="number" value=0 min=0></div></th></tr></table></div>';
|
191 |
+
const path_panel =
|
192 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Shape</p><table><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-fill" class="object-color"><div id="color-fill-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-fill-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr></table></div>';
|
193 |
+
const text_panel =
|
194 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Text</p><table><tr><th class="name-col">Font</th><th class="value-col"><select id="font-picker"></select></th></tr><tr><th class="name-col">Align</th><th class="value-col"><div class="align-text" id="align-text-left"><img src="assets/align-text-left.svg"></div><div class="align-text" id="align-text-center"><img src="assets/align-text-center.svg"></div><div class="align-text" id="align-text-right"><img src="assets/align-text-right.svg"></div><div class="align-text" id="align-text-justify"><img src="assets/align-text-justify.svg"></div></th></tr><tr><th class="name-col">Format</th><th class="value-col"><div class="format-text" id="format-bold"><img src="assets/bold.svg"></div><div class="format-text" id="format-italic"><img src="assets/italic.svg"></div><div class="format-text" id="format-underline"><img src="assets/underline.svg"></div><div class="format-text" id="format-strike"><img src="assets/strike.svg"></div></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-fill" class="object-color"><div id="color-fill-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-fill-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Letter</th><th class="value-col"><div id="select-letter"></div><div id="text-h" class="property-input" data-label="%"><input type="number" value=1></div></th></tr><tr><th class="name-col">Line</th><th class="value-col"><div id="select-line"></div><div id="text-v" class="property-input" data-label="%"><input type="number" value=1></div></th></tr></table></div>';
|
195 |
+
const stroke_panel =
|
196 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Stroke</p><table><tr><th class="name-col">Type</th><th class="value-col left-col"><div class="line-join" id="miter"><img src="assets/miter.svg"></div><div class="line-join" id="bevel"><img src="assets/bevel.svg"></div><div class="line-join" id="round"><img src="assets/round.svg"></div><div class="line-join" id="small-dash"><img src="assets/dash2.svg"></div></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-stroke" class="object-color"><div id="color-stroke-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-stroke-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Width</th><th class="value-col" id="duration-cell"><div id="object-stroke" class="property-input" data-label="px"><input type="number" min=0 value=0></div></th></tr></table></div>';
|
197 |
+
const shadow_panel =
|
198 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Shadow</p><table><tr><th class="name-col">Offset</th><th class="value-col"><div id="object-shadow-x" class="property-input" data-label="X"><input type="number" value=0></div><div id="object-shadow-y" class="property-input" data-label="Y"><input value=0 type="number"></div></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="object-color-shadow" class="object-color"><div id="color-shadow-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="object-color-shadow-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr><tr><th class="name-col">Blur</th><th class="value-col" id="duration-cell"><div id="object-blur" class="property-input" data-label="px"><input type="number" value=0 min=0></div></th></tr></table></div>';
|
199 |
+
const image_more_panel =
|
200 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Image</p><div id="image-buttons"><div id="filters-button"><img src="assets/filters.svg"> Edit filters</div><div id="crop-image"><img src="assets/crop-icon.svg">Crop image</div></div></div></hr>';
|
201 |
+
const video_more_panel =
|
202 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Video</p><div id="image-buttons"><div id="filters-button" class="filters-video"><img src="assets/filters.svg"> Edit filters</div></div></div></hr>';
|
203 |
+
const animated_text_panel =
|
204 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Text</p><table><tr><th class="name-col">Content</th><th class="value-col" id="duration-cell"><div id="animated-text" class="property-input" data-label=""><input id="animatedinput" type="text" value="text"><div id="animatedset">Set</div></div></th></tr><tr><th class="name-col">Font</th><th class="value-col"><select id="font-picker"></select></th></tr><tr><th class="name-col">Color</th><th class="value-col"><div id="text-color" class="object-color"><div id="color-text-side" class="color-picker"></div><input value="#FFFFFF" disabled="disabled"></div><div id="color-text-opacity" class="property-input" data-label="%"><input type="number" value=100></div></th></tr></table></div>';
|
205 |
+
const start_animation_panel =
|
206 |
+
'<hr><div id="back-properties" class="panel-section"><p class="property-title">Start animation</p><table><tr><th class="name-col">Preset</th><th class="value-col"><select id="preset-picker"></select></th></tr><tr><th class="name-col">Easing</th><th class="value-col"><select id="easing-picker"><option value="linear">Linear</option><option value="easeInQuad">Ease in</option><option value="easeOutQuad">Ease out</option><option value="easeinOutQuad">Ease in-out</option><option value="easeOutInQuad">Ease out-in</option><option value="easeInBounce">Ease in bounce</option><option value="easeOutBounce">Ease out bounce</option><option value="easeinOutBounce">Ease in-out bounce</option><option value="easeOutInBouce">Ease out-in bounce</option><option value="easeOutInBouce">Ease out-in bounce</option><option value="easeInSine">Ease in sine</option><option value="easeOutSine">Ease out sine</option><option value="easeinOutSine">Ease in-out sine</option><option value="easeOutInSine">Ease out-in sine</option><option value="easeOutInSine">Ease out-in sine</option><option value="easeInCubic">Ease in cubic</option><option value="easeOutCubic">Ease out cubic</option><option value="easeinOutCubic">Ease in-out cubic</option><option value="easeOutInCubic">Ease out-in cubic</option><option value="easeOutInCubic">Ease out-in cubic</option></select></th></tr><tr><th class="name-col">Order</th><th class="value-col"><div id="order-toggle"><div id="order-backward" class="order-toggle-item">Backward</div><div id="order-forward" class="order-toggle-item order-toggle-item-active">Forward</div></div></th></tr><tr><th class="name-col">Order</th><th class="value-col"><div id="order-toggle"><div id="type-letters" class="order-toggle-item-2">Letters</div><div id="type-words" class="order-toggle-item-2 order-toggle-item-active-2">Words</div></div></th></tr><tr><th class="name-col">Duration</th><th class="value-col" id="duration-cell"><div id="animated-text-duration" class="property-input" data-label="s"><input id="durationinput" type="number" value="0"></div></th></tr></table></div>';
|
207 |
+
const audio_panel =
|
208 |
+
'<div id="layout-properties" class="panel-section"><p class="property-title">Audio</p><table><tr><th class="name-col">Volume</th><th class="value-col" id="duration-cell"><div id="object-volume" class="property-input" data-label="%"><input type="number" value=0></div></th></tr></table></div>';
|
209 |
+
|
210 |
+
// Browser variants
|
211 |
+
const shape_browser =
|
212 |
+
'<div id="search-fixed"><p class="property-title">Objects</p><img id="collapse" src="assets/collapse.svg"><div id="browser-search"><input placeholder="Search..."><img src="assets/search.svg" id="search-icon"><img src="assets/delete.svg" id="delete-search"><div id="search-button">Go</div></div></div><div id="shapes-cont"><p class="row-title">Shapes</p><div class="gallery-row" id="shapes-row"></div><p class="row-title">Emojis</p><div class="gallery-row" id="emojis-row"></div></div>';
|
213 |
+
const image_browser =
|
214 |
+
'<div id="search-fixed"><p class="property-title">Images</p><img id="collapse" src="assets/collapse.svg"><div id="browser-search"><input placeholder="Search..."><a href="https://pixabay.com" target="_blank" id="pixabay"><img src="assets/pixabay.svg"></a><img src="assets/search.svg" id="search-icon"><img src="assets/delete.svg" id="delete-search"><div id="search-button">Go</div></div></div><div id="shapes-cont"><div id="landing"><div id="landing-text">Browse millions of high quality images from Pixabay. Use the search bar above or choose from popular categories below.</div><div id="categories"></div></div><div id="images-grid"></div></div>';
|
215 |
+
const text_browser =
|
216 |
+
'<div id="search-fixed"><p class="property-title">Text</p><img id="collapse" src="assets/collapse.svg"><div id="browser-search"><input placeholder="Search..."><img src="assets/search.svg" id="search-icon"><img src="assets/delete.svg" id="delete-search"><div id="search-button">Go</div></div></div><div id="shapes-cont"><p class="row-title">Basic text</p><div id="heading-text" data-font="Inter" class="add-text noselect">Add a heading</div><div id="subheading-text" data-font="Inter" class="add-text noselect">Add a subheading</div><div id="body-text" data-font="Inter" class="add-text noselect">Add body text</div></div>';
|
217 |
+
const video_browser =
|
218 |
+
'<div id="search-fixed"><p class="property-title">Videos</p><img id="collapse" src="assets/collapse.svg"><div id="browser-search"><input placeholder="Search..."><a href="https://pixabay.com" target="_blank" id="pixabay"><img src="assets/pixabay.svg"></a><img src="assets/search.svg" id="search-icon"><img src="assets/delete.svg" id="delete-search"><div id="search-button">Go</div></div></div><div id="shapes-cont"><div id="landing"><div id="landing-text">Browse millions of high quality images from Pixabay. Use the search bar above or choose from popular categories below.</div><div id="categories"></div></div><div id="images-grid"></div></div>';
|
219 |
+
const upload_browser =
|
220 |
+
'<div id="search-fixed"><p class="property-title">Uploads</p><div id="upload-button"><img src="assets/upload.svg"> Upload media</div><img id="collapse" src="assets/collapse.svg"><div id="upload-tabs"><div id="images-tab" class="upload-tab upload-tab-active">Images</div><div id="videos-tab" class="upload-tab">Videos</div></div></div><div id="images-grid"></div>';
|
221 |
+
const audio_browser =
|
222 |
+
'<div id="search-fixed" class="audio-browser"><p class="property-title">Audio</p><div id="audio-upload-button"><img src="assets/upload.svg"> Upload audio</div><img id="collapse" src="assets/collapse.svg"></div><div id="audio-list-parent"><div id="landing-text" class="audio-landing-text">Audio provided by Pixabay. Browse millions of assets from Pixabay by <a href="https://pixabay.com/music/" target="_blank">clicking here.</a></div><div id="audio-list"></div></div>';
|
223 |
+
|
224 |
+
// Text animation list
|
225 |
+
var text_animation_list = [
|
226 |
+
{ name: 'fade in', label: 'Fade in', src: 'assets/fade-in.svg' },
|
227 |
+
{
|
228 |
+
name: 'typewriter',
|
229 |
+
label: 'Typewriter',
|
230 |
+
src: 'assets/typewriter.svg',
|
231 |
+
},
|
232 |
+
{
|
233 |
+
name: 'slide top',
|
234 |
+
label: 'Slide top',
|
235 |
+
src: 'assets/slide-top.svg',
|
236 |
+
},
|
237 |
+
{
|
238 |
+
name: 'slide bottom',
|
239 |
+
label: 'Slide bottom',
|
240 |
+
src: 'assets/slide-bottom.svg',
|
241 |
+
},
|
242 |
+
{
|
243 |
+
name: 'slide left',
|
244 |
+
label: 'Slide left',
|
245 |
+
src: 'assets/slide-left.svg',
|
246 |
+
},
|
247 |
+
{
|
248 |
+
name: 'slide right',
|
249 |
+
label: 'Slide right',
|
250 |
+
src: 'assets/slide-right.svg',
|
251 |
+
},
|
252 |
+
{ name: 'scale', label: 'Scale', src: 'assets/scale.svg' },
|
253 |
+
{ name: 'shrink', label: 'Shrink', src: 'assets/shrink.svg' },
|
254 |
+
];
|
255 |
+
|
256 |
+
// Shapes list
|
257 |
+
var shape_grid_items = [
|
258 |
+
'assets/shapes/rectangle.svg',
|
259 |
+
'assets/shapes/circle.svg',
|
260 |
+
'assets/shapes/triangle.svg',
|
261 |
+
'assets/shapes/polygon.svg',
|
262 |
+
'assets/shapes/star.svg',
|
263 |
+
'assets/thingy.svg',
|
264 |
+
'assets/shapes/heart.svg',
|
265 |
+
'assets/shapes/arrow.svg',
|
266 |
+
];
|
267 |
+
var emoji_items = [
|
268 |
+
'assets/twemojis/laughing-emoji.png',
|
269 |
+
'assets/twemojis/crying-emoji.png',
|
270 |
+
'assets/twemojis/surprised-emoji.png',
|
271 |
+
'assets/twemojis/smiling-emoji.png',
|
272 |
+
'assets/twemojis/tongue-emoji.png',
|
273 |
+
'assets/twemojis/heart-eyes-emoji.png',
|
274 |
+
'assets/twemojis/heart-kiss-emoji.png',
|
275 |
+
'assets/twemojis/sunglasses-cool-emoji.png',
|
276 |
+
'assets/twemojis/ghost-emoji.png',
|
277 |
+
'assets/twemojis/skull-emoji.png',
|
278 |
+
'assets/twemojis/mindblown-emoji.png',
|
279 |
+
'assets/twemojis/bomb-emoji.png',
|
280 |
+
'assets/twemojis/hundred-100-points-emoji.png',
|
281 |
+
'assets/twemojis/thought-balloon-emoji.png',
|
282 |
+
'assets/twemojis/wave-emoji.png',
|
283 |
+
'assets/twemojis/point-emoji.png',
|
284 |
+
'assets/twemojis/thumbs-up-emoji.png',
|
285 |
+
'assets/twemojis/clap-emoji.png',
|
286 |
+
'assets/twemojis/raising-hands-emoji.png',
|
287 |
+
'assets/twemojis/praying-hands-emoji.png',
|
288 |
+
'assets/twemojis/nail-polish-emoji.png',
|
289 |
+
'assets/twemojis/eyes-emoji.png',
|
290 |
+
'assets/twemojis/cat-face-emoji.png',
|
291 |
+
'assets/twemojis/dog-face-emoji.png',
|
292 |
+
'assets/twemojis/rose-emoji.png',
|
293 |
+
'assets/twemojis/tulip-emoji.png',
|
294 |
+
'assets/twemojis/pizza-emoji.png',
|
295 |
+
'assets/twemojis/construction-emoji.png',
|
296 |
+
'assets/twemojis/plane-emoji.png',
|
297 |
+
'assets/twemojis/rocket-emoji.png',
|
298 |
+
'assets/twemojis/clock-emoji.png',
|
299 |
+
'assets/twemojis/star-emoji.png',
|
300 |
+
'assets/twemojis/sun-emoji.png',
|
301 |
+
'assets/twemojis/moon-emoji.png',
|
302 |
+
'assets/twemojis/fire-emoji.png',
|
303 |
+
'assets/twemojis/sparkles-emoji.png',
|
304 |
+
'assets/twemojis/party-popper-emoji.png',
|
305 |
+
'assets/twemojis/gift-emoji.png',
|
306 |
+
'assets/twemojis/trophy-emoji.png',
|
307 |
+
'assets/twemojis/target-emoji.png',
|
308 |
+
'assets/twemojis/gem-emoji.png',
|
309 |
+
'assets/twemojis/money-emoji.png',
|
310 |
+
'assets/twemojis/pencil-emoji.png',
|
311 |
+
'assets/twemojis/graph-emoji.png',
|
312 |
+
'assets/twemojis/wip-emoji.png',
|
313 |
+
'assets/twemojis/winking-face-emoji.png',
|
314 |
+
'assets/twemojis/pleading-face-emoji.png',
|
315 |
+
'assets/twemojis/thinking-face-emoji.png',
|
316 |
+
];
|
317 |
+
|
318 |
+
// Image list
|
319 |
+
var image_grid_items = [
|
320 |
+
'https://images.unsplash.com/photo-1609153259378-a8b23c766aec?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1866&q=80',
|
321 |
+
'https://images.unsplash.com/photo-1614435082296-ef0cbdb16b70?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=934&q=80',
|
322 |
+
'https://images.unsplash.com/photo-1614432254115-7e756705e910?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxMHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',
|
323 |
+
'https://images.unsplash.com/photo-1614423234685-544477464e15?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHw4fHx8ZW58MHx8fA%3D%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',
|
324 |
+
'https://images.unsplash.com/photo-1614357235247-99fabbee67f9?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxNHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',
|
325 |
+
'https://images.unsplash.com/photo-1614373371549-c7d2e4885f17?ixid=MXwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxOXx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60',
|
326 |
+
];
|
327 |
+
var image_categories = [
|
328 |
+
{ name: 'background', image: 'assets/background.png' },
|
329 |
+
{ name: 'wallpaper', image: 'assets/wallpaper.png' },
|
330 |
+
{ name: 'nature', image: 'assets/nature.png' },
|
331 |
+
{ name: 'summer', image: 'assets/summer.png' },
|
332 |
+
{ name: 'beach', image: 'assets/beach.png' },
|
333 |
+
{ name: 'space', image: 'assets/space.png' },
|
334 |
+
{ name: 'office', image: 'assets/office.png' },
|
335 |
+
{ name: 'food', image: 'assets/food.png' },
|
336 |
+
];
|
337 |
+
|
338 |
+
// Video list
|
339 |
+
var video_categories = [
|
340 |
+
{ name: 'rain', image: 'assets/rain.png' },
|
341 |
+
{ name: 'cars', image: 'assets/cars.png' },
|
342 |
+
{ name: 'meditation', image: 'assets/meditation.png' },
|
343 |
+
{ name: 'forest', image: 'assets/forest.png' },
|
344 |
+
{ name: 'animals', image: 'assets/animals.png' },
|
345 |
+
{ name: 'street', image: 'assets/street.png' },
|
346 |
+
{ name: 'travel', image: 'assets/travel.png' },
|
347 |
+
{ name: 'work', image: 'assets/work.png' },
|
348 |
+
];
|
349 |
+
|
350 |
+
// Audio list
|
351 |
+
var audio_items = [
|
352 |
+
{
|
353 |
+
name: 'Lofi Study',
|
354 |
+
desc: 'FASSounds',
|
355 |
+
duration: '2:27',
|
356 |
+
thumb: 'assets/audio/lofi-thumb.png',
|
357 |
+
src: 'assets/audio/lofi.mp3',
|
358 |
+
link: 'https://pixabay.com/users/fassounds-3433550/',
|
359 |
+
},
|
360 |
+
{
|
361 |
+
name: 'Stomping Rock (Four Shots)',
|
362 |
+
desc: 'AlexGrohl',
|
363 |
+
duration: '1:59',
|
364 |
+
thumb: 'assets/audio/stomping-rock-thumb.png',
|
365 |
+
src: 'assets/audio/stomping-rock.mp3',
|
366 |
+
link: 'https://pixabay.com/users/alexgrohl-25289918/',
|
367 |
+
},
|
368 |
+
{
|
369 |
+
name: 'Everything Feels New',
|
370 |
+
desc: 'EvgenyBardyuzha',
|
371 |
+
duration: '1:06',
|
372 |
+
thumb: 'assets/audio/everything-feels-new-thumb.png',
|
373 |
+
src: 'assets/audio/everything-feels-new.mp3',
|
374 |
+
link: 'https://pixabay.com/users/evgenybardyuzha-25235210/',
|
375 |
+
},
|
376 |
+
{
|
377 |
+
name: 'Both of Us',
|
378 |
+
desc: 'madiRFAN',
|
379 |
+
duration: '2:48',
|
380 |
+
thumb: 'assets/audio/both-of-us-thumb.png',
|
381 |
+
src: 'assets/audio/both-of-us.mp3',
|
382 |
+
link: 'https://pixabay.com/users/madirfan-50411/',
|
383 |
+
},
|
384 |
+
{
|
385 |
+
name: 'The Podcast Intro',
|
386 |
+
desc: 'Music Unlimited',
|
387 |
+
duration: '1:51',
|
388 |
+
thumb: 'assets/audio/the-podcast-intro-thumb.png',
|
389 |
+
src: 'assets/audio/the-podcast-intro.mp3',
|
390 |
+
link: 'https://pixabay.com/users/music_unlimited-27600023/',
|
391 |
+
},
|
392 |
+
{
|
393 |
+
name: 'Epic Cinematic Trailer',
|
394 |
+
desc: 'PavelYudin',
|
395 |
+
duration: '2:27',
|
396 |
+
thumb: 'assets/audio/epic-cinematic-trailer-thumb.png',
|
397 |
+
src: 'assets/audio/epic-cinematic-trailer.mp3',
|
398 |
+
link: 'https://pixabay.com/users/pavelyudin-27739282/',
|
399 |
+
},
|
400 |
+
{
|
401 |
+
name: 'Inspirational Background',
|
402 |
+
desc: 'AudioCoffee',
|
403 |
+
duration: '2:19',
|
404 |
+
thumb: 'assets/audio/inspirational-background-thumb.png',
|
405 |
+
src: 'assets/audio/inspirational-background.mp3',
|
406 |
+
link: 'https://pixabay.com/users/audiocoffee-27005420/',
|
407 |
+
},
|
408 |
+
{
|
409 |
+
name: 'Tropical Summer Music',
|
410 |
+
desc: 'Music Unlimited',
|
411 |
+
duration: '2:35',
|
412 |
+
thumb: 'assets/audio/tropical-summer-music-thumb.png',
|
413 |
+
src: 'assets/audio/tropical-summer-music.mp3',
|
414 |
+
link: 'https://pixabay.com/users/music_unlimited-27600023/',
|
415 |
+
},
|
416 |
+
];
|
417 |
+
|
418 |
+
// Text list
|
419 |
+
var text_items = {
|
420 |
+
sansserif: [
|
421 |
+
{ name: 'Roboto', fontname: 'Roboto' },
|
422 |
+
{ name: 'Montserrat', fontname: 'Montserrat' },
|
423 |
+
{ name: 'Poppins', fontname: 'Poppins' },
|
424 |
+
],
|
425 |
+
serif: [
|
426 |
+
{ name: 'Playfair Display', fontname: 'Playfair Display' },
|
427 |
+
{ name: 'Merriweather', fontname: 'Merriweather' },
|
428 |
+
{ name: 'IBM Plex Serif', fontname: 'IBM Plex Serif' },
|
429 |
+
],
|
430 |
+
monospace: [
|
431 |
+
{ name: 'Roboto Mono', fontname: 'Roboto Mono' },
|
432 |
+
{ name: 'Inconsolata', fontname: 'Inconsolata' },
|
433 |
+
{ name: 'Source Code Pro', fontname: 'Source Code Pro' },
|
434 |
+
],
|
435 |
+
handwriting: [
|
436 |
+
{ name: 'Dancing Script', fontname: 'Dancing Script' },
|
437 |
+
{ name: 'Pacifico', fontname: 'Pacifico' },
|
438 |
+
{ name: 'Indie Flower', fontname: 'Indie Flower' },
|
439 |
+
],
|
440 |
+
display: [
|
441 |
+
{ name: 'Lobster', fontname: 'Lobster' },
|
442 |
+
{ name: 'Bebas Neue', fontname: 'Bebas Neue' },
|
443 |
+
{ name: 'Titan One', fontname: 'Titan One' },
|
444 |
+
],
|
445 |
+
};
|
446 |
+
|
447 |
+
WebFont.load({
|
448 |
+
google: {
|
449 |
+
families: ['Syne'],
|
450 |
+
},
|
451 |
+
active: () => {},
|
452 |
+
});
|
453 |
+
|
454 |
+
var webglBackend;
|
455 |
+
try {
|
456 |
+
webglBackend = new fabric.WebglFilterBackend();
|
457 |
+
} catch (e) {
|
458 |
+
console.log(e);
|
459 |
+
}
|
460 |
+
var canvas2dBackend = new fabric.Canvas2dFilterBackend();
|
461 |
+
|
462 |
+
fabric.filterBackend = fabric.initFilterBackend();
|
463 |
+
fabric.filterBackend = webglBackend;
|
464 |
+
|
465 |
+
// Lottie support
|
466 |
+
fabric.Lottie = fabric.util.createClass(fabric.Image, {
|
467 |
+
type: 'lottie',
|
468 |
+
lockRotation: true,
|
469 |
+
lockSkewingX: true,
|
470 |
+
lockSkewingY: true,
|
471 |
+
srcFromAttribute: false,
|
472 |
+
|
473 |
+
initialize: function (path, options) {
|
474 |
+
if (!options.width) options.width = 480;
|
475 |
+
if (!options.height) options.height = 480;
|
476 |
+
|
477 |
+
this.path = path;
|
478 |
+
this.tmpCanvasEl = fabric.util.createCanvasElement();
|
479 |
+
this.tmpCanvasEl.width = options.width;
|
480 |
+
this.tmpCanvasEl.height = options.height;
|
481 |
+
|
482 |
+
this.lottieItem = bodymovin.loadAnimation({
|
483 |
+
renderer: 'canvas',
|
484 |
+
loop: false,
|
485 |
+
autoplay: false,
|
486 |
+
path: path,
|
487 |
+
rendererSettings: {
|
488 |
+
context: this.tmpCanvasEl.getContext('2d'),
|
489 |
+
preserveAspectRatio: 'xMidYMid meet',
|
490 |
+
},
|
491 |
+
});
|
492 |
+
|
493 |
+
this.lottieItem.addEventListener('enterFrame', (e) => {
|
494 |
+
this.canvas.requestRenderAll();
|
495 |
+
});
|
496 |
+
|
497 |
+
this.lottieItem.addEventListener('DOMLoaded', () => {
|
498 |
+
this.lottieItem.goToAndStop(currenttime, false);
|
499 |
+
this.lottieItem.duration =
|
500 |
+
this.lottieItem.getDuration(false) * 1000;
|
501 |
+
this.canvas.requestRenderAll();
|
502 |
+
canvas.renderAll();
|
503 |
+
canvas.fire('lottie:loaded', { any: 'payload' });
|
504 |
+
});
|
505 |
+
|
506 |
+
this.callSuper('initialize', this.tmpCanvasEl, options);
|
507 |
+
},
|
508 |
+
|
509 |
+
goToSeconds: function (seconds) {
|
510 |
+
this.lottieItem.goToAndStop(seconds, false);
|
511 |
+
this.canvas.requestRenderAll();
|
512 |
+
},
|
513 |
+
goToFrame: function (frame) {
|
514 |
+
this.lottieItem.goToAndStop(frame, true);
|
515 |
+
},
|
516 |
+
getDuration: function () {
|
517 |
+
return this.lottieItem.getDuration(false);
|
518 |
+
},
|
519 |
+
play: function () {
|
520 |
+
this.lottieItem.play();
|
521 |
+
},
|
522 |
+
pause: function () {
|
523 |
+
this.lottieItem.pause();
|
524 |
+
},
|
525 |
+
getSrc: function () {
|
526 |
+
return this.path;
|
527 |
+
},
|
528 |
+
});
|
529 |
+
|
530 |
+
fabric.Lottie.fromObject = function (_object, callback) {
|
531 |
+
const object = fabric.util.object.clone(_object);
|
532 |
+
fabric.Image.prototype._initFilters.call(
|
533 |
+
object,
|
534 |
+
object.filters,
|
535 |
+
function (filters) {
|
536 |
+
object.filters = filters || [];
|
537 |
+
fabric.Image.prototype._initFilters.call(
|
538 |
+
object,
|
539 |
+
[object.resizeFilter],
|
540 |
+
function (resizeFilters) {
|
541 |
+
object.resizeFilter = resizeFilters[0];
|
542 |
+
fabric.util.enlivenObjects(
|
543 |
+
[object.clipPath],
|
544 |
+
function (enlivedProps) {
|
545 |
+
object.clipPath = enlivedProps[0];
|
546 |
+
const fabricLottie = new fabric.Lottie(
|
547 |
+
object.src,
|
548 |
+
object
|
549 |
+
);
|
550 |
+
callback(fabricLottie, false);
|
551 |
+
}
|
552 |
+
);
|
553 |
+
}
|
554 |
+
);
|
555 |
+
}
|
556 |
+
);
|
557 |
+
};
|
558 |
+
|
559 |
+
// Initialize canvas
|
560 |
+
var canvas = new fabric.Canvas('canvas', {
|
561 |
+
preserveObjectStacking: true,
|
562 |
+
backgroundColor: '#FFF',
|
563 |
+
stateful: true,
|
564 |
+
});
|
565 |
+
canvas.selection = false;
|
566 |
+
canvas.controlsAboveOverlay = true;
|
567 |
+
|
568 |
+
// Customize controls
|
569 |
+
fabric.Object.prototype.set({
|
570 |
+
transparentCorners: false,
|
571 |
+
borderColor: '#51B9F9',
|
572 |
+
cornerColor: '#FFF',
|
573 |
+
borderScaleFactor: 2.5,
|
574 |
+
cornerStyle: 'circle',
|
575 |
+
cornerStrokeColor: '#0E98FC',
|
576 |
+
borderOpacityWhenMoving: 1,
|
577 |
+
});
|
578 |
+
|
579 |
+
canvas.selectionColor = 'rgba(46, 115, 252, 0.11)';
|
580 |
+
canvas.selectionBorderColor = 'rgba(98, 155, 255, 0.81)';
|
581 |
+
canvas.selectionLineWidth = 1.5;
|
582 |
+
|
583 |
+
var img = document.createElement('img');
|
584 |
+
img.src = 'assets/middlecontrol.svg';
|
585 |
+
|
586 |
+
var img2 = document.createElement('img');
|
587 |
+
img2.src = 'assets/middlecontrolhoz.svg';
|
588 |
+
|
589 |
+
var img3 = document.createElement('img');
|
590 |
+
img3.src = 'assets/edgecontrol.svg';
|
591 |
+
|
592 |
+
var img4 = document.createElement('img');
|
593 |
+
img4.src = 'assets/rotateicon.svg';
|
594 |
+
|
595 |
+
function renderIcon(ctx, left, top, styleOverride, fabricObject) {
|
596 |
+
const wsize = 20;
|
597 |
+
const hsize = 25;
|
598 |
+
ctx.save();
|
599 |
+
ctx.translate(left, top);
|
600 |
+
ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));
|
601 |
+
ctx.drawImage(img, -wsize / 2, -hsize / 2, wsize, hsize);
|
602 |
+
ctx.restore();
|
603 |
+
}
|
604 |
+
function renderIconHoz(ctx, left, top, styleOverride, fabricObject) {
|
605 |
+
const wsize = 25;
|
606 |
+
const hsize = 20;
|
607 |
+
ctx.save();
|
608 |
+
ctx.translate(left, top);
|
609 |
+
ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));
|
610 |
+
ctx.drawImage(img2, -wsize / 2, -hsize / 2, wsize, hsize);
|
611 |
+
ctx.restore();
|
612 |
+
}
|
613 |
+
function renderIconEdge(ctx, left, top, styleOverride, fabricObject) {
|
614 |
+
const wsize = 25;
|
615 |
+
const hsize = 25;
|
616 |
+
ctx.save();
|
617 |
+
ctx.translate(left, top);
|
618 |
+
ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));
|
619 |
+
ctx.drawImage(img3, -wsize / 2, -hsize / 2, wsize, hsize);
|
620 |
+
ctx.restore();
|
621 |
+
}
|
622 |
+
|
623 |
+
function renderIconRotate(
|
624 |
+
ctx,
|
625 |
+
left,
|
626 |
+
top,
|
627 |
+
styleOverride,
|
628 |
+
fabricObject
|
629 |
+
) {
|
630 |
+
const wsize = 40;
|
631 |
+
const hsize = 40;
|
632 |
+
ctx.save();
|
633 |
+
ctx.translate(left, top);
|
634 |
+
ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));
|
635 |
+
ctx.drawImage(img4, -wsize / 2, -hsize / 2, wsize, hsize);
|
636 |
+
ctx.restore();
|
637 |
+
}
|
638 |
+
function resetControls() {
|
639 |
+
fabric.Object.prototype.controls.ml = new fabric.Control({
|
640 |
+
x: -0.5,
|
641 |
+
y: 0,
|
642 |
+
offsetX: -1,
|
643 |
+
cursorStyleHandler:
|
644 |
+
fabric.controlsUtils.scaleSkewCursorStyleHandler,
|
645 |
+
actionHandler: fabric.controlsUtils.scalingXOrSkewingY,
|
646 |
+
getActionName: fabric.controlsUtils.scaleOrSkewActionName,
|
647 |
+
render: renderIcon,
|
648 |
+
});
|
649 |
+
|
650 |
+
fabric.Object.prototype.controls.mr = new fabric.Control({
|
651 |
+
x: 0.5,
|
652 |
+
y: 0,
|
653 |
+
offsetX: 1,
|
654 |
+
cursorStyleHandler:
|
655 |
+
fabric.controlsUtils.scaleSkewCursorStyleHandler,
|
656 |
+
actionHandler: fabric.controlsUtils.scalingXOrSkewingY,
|
657 |
+
getActionName: fabric.controlsUtils.scaleOrSkewActionName,
|
658 |
+
render: renderIcon,
|
659 |
+
});
|
660 |
+
|
661 |
+
fabric.Object.prototype.controls.mb = new fabric.Control({
|
662 |
+
x: 0,
|
663 |
+
y: 0.5,
|
664 |
+
offsetY: 1,
|
665 |
+
cursorStyleHandler:
|
666 |
+
fabric.controlsUtils.scaleSkewCursorStyleHandler,
|
667 |
+
actionHandler: fabric.controlsUtils.scalingYOrSkewingX,
|
668 |
+
getActionName: fabric.controlsUtils.scaleOrSkewActionName,
|
669 |
+
render: renderIconHoz,
|
670 |
+
});
|
671 |
+
|
672 |
+
fabric.Object.prototype.controls.mt = new fabric.Control({
|
673 |
+
x: 0,
|
674 |
+
y: -0.5,
|
675 |
+
offsetY: -1,
|
676 |
+
cursorStyleHandler:
|
677 |
+
fabric.controlsUtils.scaleSkewCursorStyleHandler,
|
678 |
+
actionHandler: fabric.controlsUtils.scalingYOrSkewingX,
|
679 |
+
getActionName: fabric.controlsUtils.scaleOrSkewActionName,
|
680 |
+
render: renderIconHoz,
|
681 |
+
});
|
682 |
+
|
683 |
+
fabric.Object.prototype.controls.tl = new fabric.Control({
|
684 |
+
x: -0.5,
|
685 |
+
y: -0.5,
|
686 |
+
cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,
|
687 |
+
actionHandler: fabric.controlsUtils.scalingEqually,
|
688 |
+
render: renderIconEdge,
|
689 |
+
});
|
690 |
+
|
691 |
+
fabric.Object.prototype.controls.tr = new fabric.Control({
|
692 |
+
x: 0.5,
|
693 |
+
y: -0.5,
|
694 |
+
cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,
|
695 |
+
actionHandler: fabric.controlsUtils.scalingEqually,
|
696 |
+
render: renderIconEdge,
|
697 |
+
});
|
698 |
+
|
699 |
+
fabric.Object.prototype.controls.bl = new fabric.Control({
|
700 |
+
x: -0.5,
|
701 |
+
y: 0.5,
|
702 |
+
cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,
|
703 |
+
actionHandler: fabric.controlsUtils.scalingEqually,
|
704 |
+
render: renderIconEdge,
|
705 |
+
});
|
706 |
+
|
707 |
+
fabric.Object.prototype.controls.br = new fabric.Control({
|
708 |
+
x: 0.5,
|
709 |
+
y: 0.5,
|
710 |
+
cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,
|
711 |
+
actionHandler: fabric.controlsUtils.scalingEqually,
|
712 |
+
render: renderIconEdge,
|
713 |
+
});
|
714 |
+
|
715 |
+
fabric.Object.prototype.controls.mtr = new fabric.Control({
|
716 |
+
x: 0,
|
717 |
+
y: 0.5,
|
718 |
+
cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,
|
719 |
+
actionHandler: fabric.controlsUtils.rotationWithSnapping,
|
720 |
+
offsetY: 30,
|
721 |
+
withConnecton: false,
|
722 |
+
actionName: 'rotate',
|
723 |
+
render: renderIconRotate,
|
724 |
+
});
|
725 |
+
}
|
726 |
+
resetControls();
|
727 |
+
var textBoxControls = (fabric.Textbox.prototype.controls = {});
|
728 |
+
|
729 |
+
textBoxControls.mtr = fabric.Object.prototype.controls.mtr;
|
730 |
+
textBoxControls.tr = fabric.Object.prototype.controls.tr;
|
731 |
+
textBoxControls.br = fabric.Object.prototype.controls.br;
|
732 |
+
textBoxControls.tl = fabric.Object.prototype.controls.tl;
|
733 |
+
textBoxControls.bl = fabric.Object.prototype.controls.bl;
|
734 |
+
textBoxControls.mt = fabric.Object.prototype.controls.mt;
|
735 |
+
textBoxControls.mb = fabric.Object.prototype.controls.mb;
|
736 |
+
|
737 |
+
textBoxControls.ml = new fabric.Control({
|
738 |
+
x: -0.5,
|
739 |
+
y: 0,
|
740 |
+
offsetX: -1,
|
741 |
+
cursorStyleHandler:
|
742 |
+
fabric.controlsUtils.scaleSkewCursorStyleHandler,
|
743 |
+
actionHandler: fabric.controlsUtils.changeWidth,
|
744 |
+
actionName: 'resizing',
|
745 |
+
render: renderIcon,
|
746 |
+
});
|
747 |
+
|
748 |
+
textBoxControls.mr = new fabric.Control({
|
749 |
+
x: 0.5,
|
750 |
+
y: 0,
|
751 |
+
offsetX: 1,
|
752 |
+
cursorStyleHandler:
|
753 |
+
fabric.controlsUtils.scaleSkewCursorStyleHandler,
|
754 |
+
actionHandler: fabric.controlsUtils.changeWidth,
|
755 |
+
actionName: 'resizing',
|
756 |
+
render: renderIcon,
|
757 |
+
});
|
758 |
+
|
759 |
+
// Get any object by ID
|
760 |
+
fabric.Canvas.prototype.getItemById = function (name) {
|
761 |
+
var object = null,
|
762 |
+
objects = this.getObjects();
|
763 |
+
for (var i = 0, len = this.size(); i < len; i++) {
|
764 |
+
if (objects[i].get('type') == 'group') {
|
765 |
+
if (objects[i].get('id') && objects[i].get('id') === name) {
|
766 |
+
object = objects[i];
|
767 |
+
break;
|
768 |
+
}
|
769 |
+
var wip = i;
|
770 |
+
for (var o = 0; o < objects[i]._objects.length; o++) {
|
771 |
+
if (
|
772 |
+
objects[wip]._objects[o].id &&
|
773 |
+
objects[wip]._objects[o].id === name
|
774 |
+
) {
|
775 |
+
object = objects[wip]._objects[o];
|
776 |
+
break;
|
777 |
+
}
|
778 |
+
}
|
779 |
+
} else if (objects[i].id && objects[i].id === name) {
|
780 |
+
object = objects[i];
|
781 |
+
break;
|
782 |
+
}
|
783 |
+
}
|
784 |
+
return object;
|
785 |
+
};
|
786 |
+
|
787 |
+
// Create the artboard
|
788 |
+
var a_width = 600;
|
789 |
+
var a_height = 500;
|
790 |
+
var artboard = new fabric.Rect({
|
791 |
+
left: canvas.get('width') / 2 - a_width / 2,
|
792 |
+
top: canvas.get('height') / 2 - a_height / 2,
|
793 |
+
width: a_width,
|
794 |
+
height: a_height,
|
795 |
+
absolutePositioned: true,
|
796 |
+
rx: 0,
|
797 |
+
ry: 0,
|
798 |
+
fill: '#FFF',
|
799 |
+
hasControls: true,
|
800 |
+
transparentCorners: false,
|
801 |
+
borderColor: '#0E98FC',
|
802 |
+
cornerColor: '#0E98FC',
|
803 |
+
cursorWidth: 1,
|
804 |
+
cursorDuration: 1,
|
805 |
+
cursorDelay: 250,
|
806 |
+
id: 'overlay',
|
807 |
+
});
|
808 |
+
canvas.renderAll();
|
809 |
+
|
810 |
+
// Clip canvas to the artboard
|
811 |
+
canvas.clipPath = artboard;
|
812 |
+
canvas.renderAll();
|
813 |
+
|
814 |
+
// Initialize color picker (fill)
|
815 |
+
var o_fill = Pickr.create({
|
816 |
+
el: '#color-picker-fill',
|
817 |
+
theme: 'nano',
|
818 |
+
inline: true,
|
819 |
+
useAsButton: true,
|
820 |
+
swatches: null,
|
821 |
+
default: '#FFFFFF',
|
822 |
+
showAlways: true,
|
823 |
+
components: {
|
824 |
+
preview: true,
|
825 |
+
opacity: true,
|
826 |
+
hue: true,
|
827 |
+
interaction: {
|
828 |
+
hex: true,
|
829 |
+
rgba: true,
|
830 |
+
hsla: false,
|
831 |
+
hsva: false,
|
832 |
+
cmyk: false,
|
833 |
+
input: true,
|
834 |
+
clear: false,
|
835 |
+
save: false,
|
836 |
+
},
|
837 |
+
},
|
838 |
+
});
|
839 |
+
|
840 |
+
// Color picker events
|
841 |
+
o_fill
|
842 |
+
.on('init', (instance) => {
|
843 |
+
o_fill.hide();
|
844 |
+
})
|
845 |
+
.on('change', (instance) => {
|
846 |
+
if (canvas.getActiveObject()) {
|
847 |
+
const object = canvas.getActiveObject();
|
848 |
+
if (colormode == 'fill') {
|
849 |
+
$('#object-color-fill input').val(
|
850 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
851 |
+
);
|
852 |
+
$('#object-color-fill-opacity input').val(
|
853 |
+
Math.round(o_fill.getColor().toRGBA()[3] * 100 * 100) / 100
|
854 |
+
);
|
855 |
+
$('#color-fill-side').css(
|
856 |
+
'background-color',
|
857 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
858 |
+
);
|
859 |
+
object.set('fill', o_fill.getColor().toRGBA().toString());
|
860 |
+
if (!seeking && !setting) {
|
861 |
+
newKeyframe(
|
862 |
+
'fill',
|
863 |
+
object,
|
864 |
+
currenttime,
|
865 |
+
object.get('fill'),
|
866 |
+
true
|
867 |
+
);
|
868 |
+
}
|
869 |
+
} else if (colormode == 'stroke') {
|
870 |
+
$('#object-color-stroke input').val(
|
871 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
872 |
+
);
|
873 |
+
$('#object-color-stroke-opacity input').val(
|
874 |
+
Math.round(o_fill.getColor().toRGBA()[3] * 100 * 100) / 100
|
875 |
+
);
|
876 |
+
$('#color-stroke-side').css(
|
877 |
+
'background-color',
|
878 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
879 |
+
);
|
880 |
+
object.set('stroke', o_fill.getColor().toRGBA().toString());
|
881 |
+
if (!seeking && !setting) {
|
882 |
+
newKeyframe(
|
883 |
+
'stroke',
|
884 |
+
object,
|
885 |
+
currenttime,
|
886 |
+
object.get('stroke'),
|
887 |
+
true
|
888 |
+
);
|
889 |
+
newKeyframe(
|
890 |
+
'strokeWidth',
|
891 |
+
object,
|
892 |
+
currenttime,
|
893 |
+
object.get('strokeWidth'),
|
894 |
+
true
|
895 |
+
);
|
896 |
+
}
|
897 |
+
} else if (colormode == 'shadow') {
|
898 |
+
$('#object-color-shadow input').val(
|
899 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
900 |
+
);
|
901 |
+
$('#object-color-shadow-opacity input').val(
|
902 |
+
Math.round(o_fill.getColor().toRGBA()[3] * 100 * 100) / 100
|
903 |
+
);
|
904 |
+
$('#color-shadow-side').css(
|
905 |
+
'background-color',
|
906 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
907 |
+
);
|
908 |
+
object.set(
|
909 |
+
'shadow',
|
910 |
+
new fabric.Shadow({
|
911 |
+
color: o_fill.getColor().toRGBA().toString(),
|
912 |
+
offsetX: object.shadow.offsetX,
|
913 |
+
offsetY: object.shadow.offsetY,
|
914 |
+
blur: object.shadow.blur,
|
915 |
+
opacity: object.shadow.opacity,
|
916 |
+
})
|
917 |
+
);
|
918 |
+
if (!seeking && !setting) {
|
919 |
+
newKeyframe(
|
920 |
+
'shadow.color',
|
921 |
+
object,
|
922 |
+
currenttime,
|
923 |
+
object.shadow.color,
|
924 |
+
true
|
925 |
+
);
|
926 |
+
}
|
927 |
+
} else if (colormode == 'chroma') {
|
928 |
+
var obj = canvas.getActiveObject();
|
929 |
+
$('#chroma-color input').val(
|
930 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
931 |
+
);
|
932 |
+
$('#color-chroma-side').css(
|
933 |
+
'background-color',
|
934 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
935 |
+
);
|
936 |
+
if (obj.filters.find((x) => x.type == 'RemoveColor')) {
|
937 |
+
obj.filters.find((x) => x.type == 'RemoveColor').color =
|
938 |
+
o_fill.getColor().toRGBA().toString();
|
939 |
+
}
|
940 |
+
updateChromaValues();
|
941 |
+
} else if (colormode == 'text') {
|
942 |
+
var obj = canvas.getActiveObject();
|
943 |
+
$('#text-color input').val(
|
944 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
945 |
+
);
|
946 |
+
$('#color-text-side').css(
|
947 |
+
'background-color',
|
948 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
949 |
+
);
|
950 |
+
animatedtext
|
951 |
+
.find((x) => x.id == obj.id)
|
952 |
+
.setProps(
|
953 |
+
{ fill: o_fill.getColor().toRGBA().toString() },
|
954 |
+
canvas
|
955 |
+
);
|
956 |
+
}
|
957 |
+
canvas.renderAll();
|
958 |
+
} else {
|
959 |
+
if (colormode == 'back') {
|
960 |
+
$('#canvas-color input').val(
|
961 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
962 |
+
);
|
963 |
+
$('#canvas-color-opacity input').val(
|
964 |
+
Math.round(o_fill.getColor().toRGBA()[3] * 100 * 100) / 100
|
965 |
+
);
|
966 |
+
$('#color-side').css(
|
967 |
+
'background-color',
|
968 |
+
o_fill.getColor().toHEXA().toString().substring(0, 7)
|
969 |
+
);
|
970 |
+
canvas.setBackgroundColor(
|
971 |
+
o_fill.getColor().toRGBA().toString()
|
972 |
+
);
|
973 |
+
canvas.renderAll();
|
974 |
+
}
|
975 |
+
}
|
976 |
+
})
|
977 |
+
.on('show', (instance) => {
|
978 |
+
$('.pcr-current-color').html(
|
979 |
+
"<img id='eyedropper' src='assets/eyedropper.svg'>"
|
980 |
+
);
|
981 |
+
});
|
982 |
+
|
983 |
+
var f = fabric.Image.filters;
|
984 |
+
|
985 |
+
// Canvas recorder initialization
|
986 |
+
var canvasrecord = new fabric.Canvas('canvasrecord', {
|
987 |
+
preserveObjectStacking: true,
|
988 |
+
backgroundColor: '#FFF',
|
989 |
+
width: artboard.width,
|
990 |
+
height: artboard.height,
|
991 |
+
});
|
992 |
+
|
993 |
+
var timelineslider = document.getElementById('timeline-zoom');
|
994 |
+
var t_slider = new RangeSlider(timelineslider, {
|
995 |
+
design: '2d',
|
996 |
+
theme: 'default',
|
997 |
+
handle: 'round',
|
998 |
+
popup: null,
|
999 |
+
showMinMaxLabels: false,
|
1000 |
+
unit: '%',
|
1001 |
+
min: 5,
|
1002 |
+
max: 47,
|
1003 |
+
value: 47,
|
1004 |
+
onmove: function (x) {
|
1005 |
+
setTimelineZoom(-1 * (x - 51));
|
1006 |
+
},
|
1007 |
+
onfinish: function (x) {
|
1008 |
+
setTimelineZoom(-1 * (x - 51));
|
1009 |
+
},
|
1010 |
+
onstart: function (x) {},
|
1011 |
+
});
|
1012 |
+
|
1013 |
+
const selectbox = new SelectionArea({
|
1014 |
+
class: 'selection-area',
|
1015 |
+
selectables: ['.keyframe'],
|
1016 |
+
container: '#timeline',
|
1017 |
+
// Query selectors for elements from where a selection can be started from.
|
1018 |
+
startareas: ['html'],
|
1019 |
+
|
1020 |
+
// Query selectors for elements which will be used as boundaries for the selection.
|
1021 |
+
boundaries: ['#timeline'],
|
1022 |
+
|
1023 |
+
startThreshold: 10,
|
1024 |
+
|
1025 |
+
allowTouch: true,
|
1026 |
+
|
1027 |
+
intersect: 'touch',
|
1028 |
+
|
1029 |
+
overlap: 'invert',
|
1030 |
+
|
1031 |
+
// Configuration in case a selectable gets just clicked.
|
1032 |
+
singleTap: {
|
1033 |
+
allow: false,
|
1034 |
+
intersect: 'native',
|
1035 |
+
},
|
1036 |
+
|
1037 |
+
// Scroll configuration.
|
1038 |
+
scrolling: {
|
1039 |
+
speedDivider: 10,
|
1040 |
+
manualSpeed: 750,
|
1041 |
+
},
|
1042 |
+
});
|
1043 |
+
|
1044 |
+
selectbox
|
1045 |
+
.on('beforestart', (evt) => {
|
1046 |
+
if (
|
1047 |
+
$(evt.event.target).hasClass('keyframe') ||
|
1048 |
+
$(evt.event.target).attr('id') == 'seekbar' ||
|
1049 |
+
$(evt.event.target).parent().hasClass('main-row') ||
|
1050 |
+
$(evt.event.target).hasClass('main-row') ||
|
1051 |
+
$(evt.event.target).hasClass('trim-row') ||
|
1052 |
+
evt.event.which === 3
|
1053 |
+
) {
|
1054 |
+
return false;
|
1055 |
+
}
|
1056 |
+
})
|
1057 |
+
.on('start', (evt) => {})
|
1058 |
+
.on('move', (evt) => {})
|
1059 |
+
.on('stop', (evt) => {
|
1060 |
+
$('.keyframe-selected').removeClass('keyframe-selected');
|
1061 |
+
shiftkeys = [];
|
1062 |
+
if (evt.store.selected.length == 0) {
|
1063 |
+
$('.keyframe-selected').removeClass('keyframe-selected');
|
1064 |
+
} else {
|
1065 |
+
canvas.discardActiveObject();
|
1066 |
+
canvas.renderAll();
|
1067 |
+
evt.store.selected.forEach(function (key) {
|
1068 |
+
shiftkeys.push({
|
1069 |
+
keyframe: key,
|
1070 |
+
offset: $(key).offset().left,
|
1071 |
+
});
|
1072 |
+
$(key).addClass('keyframe-selected');
|
1073 |
+
});
|
1074 |
+
}
|
1075 |
+
});
|
js/libraries/anime.min.js
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* anime.js v3.2.1
|
3 |
+
* (c) 2020 Julian Garnier
|
4 |
+
* Released under the MIT license
|
5 |
+
* animejs.com
|
6 |
+
*/
|
7 |
+
|
8 |
+
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):n.anime=e()}(this,function(){"use strict";var n={update:null,begin:null,loopBegin:null,changeBegin:null,change:null,changeComplete:null,loopComplete:null,complete:null,loop:1,direction:"normal",autoplay:!0,timelineOffset:0},e={duration:1e3,delay:0,endDelay:0,easing:"easeOutElastic(1, .5)",round:0},t=["translateX","translateY","translateZ","rotate","rotateX","rotateY","rotateZ","scale","scaleX","scaleY","scaleZ","skew","skewX","skewY","perspective","matrix","matrix3d"],r={CSS:{},springs:{}};function a(n,e,t){return Math.min(Math.max(n,e),t)}function o(n,e){return n.indexOf(e)>-1}function u(n,e){return n.apply(null,e)}var i={arr:function(n){return Array.isArray(n)},obj:function(n){return o(Object.prototype.toString.call(n),"Object")},pth:function(n){return i.obj(n)&&n.hasOwnProperty("totalLength")},svg:function(n){return n instanceof SVGElement},inp:function(n){return n instanceof HTMLInputElement},dom:function(n){return n.nodeType||i.svg(n)},str:function(n){return"string"==typeof n},fnc:function(n){return"function"==typeof n},und:function(n){return void 0===n},nil:function(n){return i.und(n)||null===n},hex:function(n){return/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(n)},rgb:function(n){return/^rgb/.test(n)},hsl:function(n){return/^hsl/.test(n)},col:function(n){return i.hex(n)||i.rgb(n)||i.hsl(n)},key:function(t){return!n.hasOwnProperty(t)&&!e.hasOwnProperty(t)&&"targets"!==t&&"keyframes"!==t}};function c(n){var e=/\(([^)]+)\)/.exec(n);return e?e[1].split(",").map(function(n){return parseFloat(n)}):[]}function s(n,e){var t=c(n),o=a(i.und(t[0])?1:t[0],.1,100),u=a(i.und(t[1])?100:t[1],.1,100),s=a(i.und(t[2])?10:t[2],.1,100),f=a(i.und(t[3])?0:t[3],.1,100),l=Math.sqrt(u/o),d=s/(2*Math.sqrt(u*o)),p=d<1?l*Math.sqrt(1-d*d):0,v=1,h=d<1?(d*l-f)/p:-f+l;function g(n){var t=e?e*n/1e3:n;return t=d<1?Math.exp(-t*d*l)*(v*Math.cos(p*t)+h*Math.sin(p*t)):(v+h*t)*Math.exp(-t*l),0===n||1===n?n:1-t}return e?g:function(){var e=r.springs[n];if(e)return e;for(var t=0,a=0;;)if(1===g(t+=1/6)){if(++a>=16)break}else a=0;var o=t*(1/6)*1e3;return r.springs[n]=o,o}}function f(n){return void 0===n&&(n=10),function(e){return Math.ceil(a(e,1e-6,1)*n)*(1/n)}}var l,d,p=function(){var n=11,e=1/(n-1);function t(n,e){return 1-3*e+3*n}function r(n,e){return 3*e-6*n}function a(n){return 3*n}function o(n,e,o){return((t(e,o)*n+r(e,o))*n+a(e))*n}function u(n,e,o){return 3*t(e,o)*n*n+2*r(e,o)*n+a(e)}return function(t,r,a,i){if(0<=t&&t<=1&&0<=a&&a<=1){var c=new Float32Array(n);if(t!==r||a!==i)for(var s=0;s<n;++s)c[s]=o(s*e,t,a);return function(n){return t===r&&a===i?n:0===n||1===n?n:o(f(n),r,i)}}function f(r){for(var i=0,s=1,f=n-1;s!==f&&c[s]<=r;++s)i+=e;var l=i+(r-c[--s])/(c[s+1]-c[s])*e,d=u(l,t,a);return d>=.001?function(n,e,t,r){for(var a=0;a<4;++a){var i=u(e,t,r);if(0===i)return e;e-=(o(e,t,r)-n)/i}return e}(r,l,t,a):0===d?l:function(n,e,t,r,a){for(var u,i,c=0;(u=o(i=e+(t-e)/2,r,a)-n)>0?t=i:e=i,Math.abs(u)>1e-7&&++c<10;);return i}(r,i,i+e,t,a)}}}(),v=(l={linear:function(){return function(n){return n}}},d={Sine:function(){return function(n){return 1-Math.cos(n*Math.PI/2)}},Circ:function(){return function(n){return 1-Math.sqrt(1-n*n)}},Back:function(){return function(n){return n*n*(3*n-2)}},Bounce:function(){return function(n){for(var e,t=4;n<((e=Math.pow(2,--t))-1)/11;);return 1/Math.pow(4,3-t)-7.5625*Math.pow((3*e-2)/22-n,2)}},Elastic:function(n,e){void 0===n&&(n=1),void 0===e&&(e=.5);var t=a(n,1,10),r=a(e,.1,2);return function(n){return 0===n||1===n?n:-t*Math.pow(2,10*(n-1))*Math.sin((n-1-r/(2*Math.PI)*Math.asin(1/t))*(2*Math.PI)/r)}}},["Quad","Cubic","Quart","Quint","Expo"].forEach(function(n,e){d[n]=function(){return function(n){return Math.pow(n,e+2)}}}),Object.keys(d).forEach(function(n){var e=d[n];l["easeIn"+n]=e,l["easeOut"+n]=function(n,t){return function(r){return 1-e(n,t)(1-r)}},l["easeInOut"+n]=function(n,t){return function(r){return r<.5?e(n,t)(2*r)/2:1-e(n,t)(-2*r+2)/2}},l["easeOutIn"+n]=function(n,t){return function(r){return r<.5?(1-e(n,t)(1-2*r))/2:(e(n,t)(2*r-1)+1)/2}}}),l);function h(n,e){if(i.fnc(n))return n;var t=n.split("(")[0],r=v[t],a=c(n);switch(t){case"spring":return s(n,e);case"cubicBezier":return u(p,a);case"steps":return u(f,a);default:return u(r,a)}}function g(n){try{return document.querySelectorAll(n)}catch(n){return}}function m(n,e){for(var t=n.length,r=arguments.length>=2?arguments[1]:void 0,a=[],o=0;o<t;o++)if(o in n){var u=n[o];e.call(r,u,o,n)&&a.push(u)}return a}function y(n){return n.reduce(function(n,e){return n.concat(i.arr(e)?y(e):e)},[])}function b(n){return i.arr(n)?n:(i.str(n)&&(n=g(n)||n),n instanceof NodeList||n instanceof HTMLCollection?[].slice.call(n):[n])}function M(n,e){return n.some(function(n){return n===e})}function x(n){var e={};for(var t in n)e[t]=n[t];return e}function w(n,e){var t=x(n);for(var r in n)t[r]=e.hasOwnProperty(r)?e[r]:n[r];return t}function k(n,e){var t=x(n);for(var r in e)t[r]=i.und(n[r])?e[r]:n[r];return t}function O(n){return i.rgb(n)?(t=/rgb\((\d+,\s*[\d]+,\s*[\d]+)\)/g.exec(e=n))?"rgba("+t[1]+",1)":e:i.hex(n)?(r=n.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,function(n,e,t,r){return e+e+t+t+r+r}),a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(r),"rgba("+parseInt(a[1],16)+","+parseInt(a[2],16)+","+parseInt(a[3],16)+",1)"):i.hsl(n)?function(n){var e,t,r,a=/hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(n)||/hsla\((\d+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)/g.exec(n),o=parseInt(a[1],10)/360,u=parseInt(a[2],10)/100,i=parseInt(a[3],10)/100,c=a[4]||1;function s(n,e,t){return t<0&&(t+=1),t>1&&(t-=1),t<1/6?n+6*(e-n)*t:t<.5?e:t<2/3?n+(e-n)*(2/3-t)*6:n}if(0==u)e=t=r=i;else{var f=i<.5?i*(1+u):i+u-i*u,l=2*i-f;e=s(l,f,o+1/3),t=s(l,f,o),r=s(l,f,o-1/3)}return"rgba("+255*e+","+255*t+","+255*r+","+c+")"}(n):void 0;var e,t,r,a}function C(n){var e=/[+-]?\d*\.?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?(%|px|pt|em|rem|in|cm|mm|ex|ch|pc|vw|vh|vmin|vmax|deg|rad|turn)?$/.exec(n);if(e)return e[1]}function P(n,e){return i.fnc(n)?n(e.target,e.id,e.total):n}function I(n,e){return n.getAttribute(e)}function D(n,e,t){if(M([t,"deg","rad","turn"],C(e)))return e;var a=r.CSS[e+t];if(!i.und(a))return a;var o=document.createElement(n.tagName),u=n.parentNode&&n.parentNode!==document?n.parentNode:document.body;u.appendChild(o),o.style.position="absolute",o.style.width=100+t;var c=100/o.offsetWidth;u.removeChild(o);var s=c*parseFloat(e);return r.CSS[e+t]=s,s}function B(n,e,t){if(e in n.style){var r=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),a=n.style[e]||getComputedStyle(n).getPropertyValue(r)||"0";return t?D(n,a,t):a}}function T(n,e){return i.dom(n)&&!i.inp(n)&&(!i.nil(I(n,e))||i.svg(n)&&n[e])?"attribute":i.dom(n)&&M(t,e)?"transform":i.dom(n)&&"transform"!==e&&B(n,e)?"css":null!=n[e]?"object":void 0}function E(n){if(i.dom(n)){for(var e,t=n.style.transform||"",r=/(\w+)\(([^)]*)\)/g,a=new Map;e=r.exec(t);)a.set(e[1],e[2]);return a}}function F(n,e,t,r){var a,u=o(e,"scale")?1:0+(o(a=e,"translate")||"perspective"===a?"px":o(a,"rotate")||o(a,"skew")?"deg":void 0),i=E(n).get(e)||u;return t&&(t.transforms.list.set(e,i),t.transforms.last=e),r?D(n,i,r):i}function A(n,e,t,r){switch(T(n,e)){case"transform":return F(n,e,r,t);case"css":return B(n,e,t);case"attribute":return I(n,e);default:return n[e]||0}}function N(n,e){var t=/^(\*=|\+=|-=)/.exec(n);if(!t)return n;var r=C(n)||0,a=parseFloat(e),o=parseFloat(n.replace(t[0],""));switch(t[0][0]){case"+":return a+o+r;case"-":return a-o+r;case"*":return a*o+r}}function S(n,e){if(i.col(n))return O(n);if(/\s/g.test(n))return n;var t=C(n),r=t?n.substr(0,n.length-t.length):n;return e?r+e:r}function L(n,e){return Math.sqrt(Math.pow(e.x-n.x,2)+Math.pow(e.y-n.y,2))}function j(n){for(var e,t=n.points,r=0,a=0;a<t.numberOfItems;a++){var o=t.getItem(a);a>0&&(r+=L(e,o)),e=o}return r}function q(n){if(n.getTotalLength)return n.getTotalLength();switch(n.tagName.toLowerCase()){case"circle":return o=n,2*Math.PI*I(o,"r");case"rect":return 2*I(a=n,"width")+2*I(a,"height");case"line":return L({x:I(r=n,"x1"),y:I(r,"y1")},{x:I(r,"x2"),y:I(r,"y2")});case"polyline":return j(n);case"polygon":return t=(e=n).points,j(e)+L(t.getItem(t.numberOfItems-1),t.getItem(0))}var e,t,r,a,o}function H(n,e){var t=e||{},r=t.el||function(n){for(var e=n.parentNode;i.svg(e)&&i.svg(e.parentNode);)e=e.parentNode;return e}(n),a=r.getBoundingClientRect(),o=I(r,"viewBox"),u=a.width,c=a.height,s=t.viewBox||(o?o.split(" "):[0,0,u,c]);return{el:r,viewBox:s,x:s[0]/1,y:s[1]/1,w:u,h:c,vW:s[2],vH:s[3]}}function V(n,e,t){function r(t){void 0===t&&(t=0);var r=e+t>=1?e+t:0;return n.el.getPointAtLength(r)}var a=H(n.el,n.svg),o=r(),u=r(-1),i=r(1),c=t?1:a.w/a.vW,s=t?1:a.h/a.vH;switch(n.property){case"x":return(o.x-a.x)*c;case"y":return(o.y-a.y)*s;case"angle":return 180*Math.atan2(i.y-u.y,i.x-u.x)/Math.PI}}function $(n,e){var t=/[+-]?\d*\.?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/g,r=S(i.pth(n)?n.totalLength:n,e)+"";return{original:r,numbers:r.match(t)?r.match(t).map(Number):[0],strings:i.str(n)||e?r.split(t):[]}}function W(n){return m(n?y(i.arr(n)?n.map(b):b(n)):[],function(n,e,t){return t.indexOf(n)===e})}function X(n){var e=W(n);return e.map(function(n,t){return{target:n,id:t,total:e.length,transforms:{list:E(n)}}})}function Y(n,e){var t=x(e);if(/^spring/.test(t.easing)&&(t.duration=s(t.easing)),i.arr(n)){var r=n.length;2===r&&!i.obj(n[0])?n={value:n}:i.fnc(e.duration)||(t.duration=e.duration/r)}var a=i.arr(n)?n:[n];return a.map(function(n,t){var r=i.obj(n)&&!i.pth(n)?n:{value:n};return i.und(r.delay)&&(r.delay=t?0:e.delay),i.und(r.endDelay)&&(r.endDelay=t===a.length-1?e.endDelay:0),r}).map(function(n){return k(n,t)})}function Z(n,e){var t=[],r=e.keyframes;for(var a in r&&(e=k(function(n){for(var e=m(y(n.map(function(n){return Object.keys(n)})),function(n){return i.key(n)}).reduce(function(n,e){return n.indexOf(e)<0&&n.push(e),n},[]),t={},r=function(r){var a=e[r];t[a]=n.map(function(n){var e={};for(var t in n)i.key(t)?t==a&&(e.value=n[t]):e[t]=n[t];return e})},a=0;a<e.length;a++)r(a);return t}(r),e)),e)i.key(a)&&t.push({name:a,tweens:Y(e[a],n)});return t}function G(n,e){var t;return n.tweens.map(function(r){var a=function(n,e){var t={};for(var r in n){var a=P(n[r],e);i.arr(a)&&1===(a=a.map(function(n){return P(n,e)})).length&&(a=a[0]),t[r]=a}return t.duration=parseFloat(t.duration),t.delay=parseFloat(t.delay),t}(r,e),o=a.value,u=i.arr(o)?o[1]:o,c=C(u),s=A(e.target,n.name,c,e),f=t?t.to.original:s,l=i.arr(o)?o[0]:f,d=C(l)||C(s),p=c||d;return i.und(u)&&(u=f),a.from=$(l,p),a.to=$(N(u,l),p),a.start=t?t.end:0,a.end=a.start+a.delay+a.duration+a.endDelay,a.easing=h(a.easing,a.duration),a.isPath=i.pth(o),a.isPathTargetInsideSVG=a.isPath&&i.svg(e.target),a.isColor=i.col(a.from.original),a.isColor&&(a.round=1),t=a,a})}var Q={css:function(n,e,t){return n.style[e]=t},attribute:function(n,e,t){return n.setAttribute(e,t)},object:function(n,e,t){return n[e]=t},transform:function(n,e,t,r,a){if(r.list.set(e,t),e===r.last||a){var o="";r.list.forEach(function(n,e){o+=e+"("+n+") "}),n.style.transform=o}}};function z(n,e){X(n).forEach(function(n){for(var t in e){var r=P(e[t],n),a=n.target,o=C(r),u=A(a,t,o,n),i=N(S(r,o||C(u)),u),c=T(a,t);Q[c](a,t,i,n.transforms,!0)}})}function _(n,e){return m(y(n.map(function(n){return e.map(function(e){return function(n,e){var t=T(n.target,e.name);if(t){var r=G(e,n),a=r[r.length-1];return{type:t,property:e.name,animatable:n,tweens:r,duration:a.end,delay:r[0].delay,endDelay:a.endDelay}}}(n,e)})})),function(n){return!i.und(n)})}function R(n,e){var t=n.length,r=function(n){return n.timelineOffset?n.timelineOffset:0},a={};return a.duration=t?Math.max.apply(Math,n.map(function(n){return r(n)+n.duration})):e.duration,a.delay=t?Math.min.apply(Math,n.map(function(n){return r(n)+n.delay})):e.delay,a.endDelay=t?a.duration-Math.max.apply(Math,n.map(function(n){return r(n)+n.duration-n.endDelay})):e.endDelay,a}var J=0;var K=[],U=function(){var n;function e(t){for(var r=K.length,a=0;a<r;){var o=K[a];o.paused?(K.splice(a,1),r--):(o.tick(t),a++)}n=a>0?requestAnimationFrame(e):void 0}return"undefined"!=typeof document&&document.addEventListener("visibilitychange",function(){en.suspendWhenDocumentHidden&&(nn()?n=cancelAnimationFrame(n):(K.forEach(function(n){return n._onDocumentVisibility()}),U()))}),function(){n||nn()&&en.suspendWhenDocumentHidden||!(K.length>0)||(n=requestAnimationFrame(e))}}();function nn(){return!!document&&document.hidden}function en(t){void 0===t&&(t={});var r,o=0,u=0,i=0,c=0,s=null;function f(n){var e=window.Promise&&new Promise(function(n){return s=n});return n.finished=e,e}var l,d,p,v,h,g,y,b,M=(d=w(n,l=t),p=w(e,l),v=Z(p,l),h=X(l.targets),g=_(h,v),y=R(g,p),b=J,J++,k(d,{id:b,children:[],animatables:h,animations:g,duration:y.duration,delay:y.delay,endDelay:y.endDelay}));f(M);function x(){var n=M.direction;"alternate"!==n&&(M.direction="normal"!==n?"normal":"reverse"),M.reversed=!M.reversed,r.forEach(function(n){return n.reversed=M.reversed})}function O(n){return M.reversed?M.duration-n:n}function C(){o=0,u=O(M.currentTime)*(1/en.speed)}function P(n,e){e&&e.seek(n-e.timelineOffset)}function I(n){for(var e=0,t=M.animations,r=t.length;e<r;){var o=t[e],u=o.animatable,i=o.tweens,c=i.length-1,s=i[c];c&&(s=m(i,function(e){return n<e.end})[0]||s);for(var f=a(n-s.start-s.delay,0,s.duration)/s.duration,l=isNaN(f)?1:s.easing(f),d=s.to.strings,p=s.round,v=[],h=s.to.numbers.length,g=void 0,y=0;y<h;y++){var b=void 0,x=s.to.numbers[y],w=s.from.numbers[y]||0;b=s.isPath?V(s.value,l*x,s.isPathTargetInsideSVG):w+l*(x-w),p&&(s.isColor&&y>2||(b=Math.round(b*p)/p)),v.push(b)}var k=d.length;if(k){g=d[0];for(var O=0;O<k;O++){d[O];var C=d[O+1],P=v[O];isNaN(P)||(g+=C?P+C:P+" ")}}else g=v[0];Q[o.type](u.target,o.property,g,u.transforms),o.currentValue=g,e++}}function D(n){M[n]&&!M.passThrough&&M[n](M)}function B(n){var e=M.duration,t=M.delay,l=e-M.endDelay,d=O(n);M.progress=a(d/e*100,0,100),M.reversePlayback=d<M.currentTime,r&&function(n){if(M.reversePlayback)for(var e=c;e--;)P(n,r[e]);else for(var t=0;t<c;t++)P(n,r[t])}(d),!M.began&&M.currentTime>0&&(M.began=!0,D("begin")),!M.loopBegan&&M.currentTime>0&&(M.loopBegan=!0,D("loopBegin")),d<=t&&0!==M.currentTime&&I(0),(d>=l&&M.currentTime!==e||!e)&&I(e),d>t&&d<l?(M.changeBegan||(M.changeBegan=!0,M.changeCompleted=!1,D("changeBegin")),D("change"),I(d)):M.changeBegan&&(M.changeCompleted=!0,M.changeBegan=!1,D("changeComplete")),M.currentTime=a(d,0,e),M.began&&D("update"),n>=e&&(u=0,M.remaining&&!0!==M.remaining&&M.remaining--,M.remaining?(o=i,D("loopComplete"),M.loopBegan=!1,"alternate"===M.direction&&x()):(M.paused=!0,M.completed||(M.completed=!0,D("loopComplete"),D("complete"),!M.passThrough&&"Promise"in window&&(s(),f(M)))))}return M.reset=function(){var n=M.direction;M.passThrough=!1,M.currentTime=0,M.progress=0,M.paused=!0,M.began=!1,M.loopBegan=!1,M.changeBegan=!1,M.completed=!1,M.changeCompleted=!1,M.reversePlayback=!1,M.reversed="reverse"===n,M.remaining=M.loop,r=M.children;for(var e=c=r.length;e--;)M.children[e].reset();(M.reversed&&!0!==M.loop||"alternate"===n&&1===M.loop)&&M.remaining++,I(M.reversed?M.duration:0)},M._onDocumentVisibility=C,M.set=function(n,e){return z(n,e),M},M.tick=function(n){i=n,o||(o=i),B((i+(u-o))*en.speed)},M.seek=function(n){B(O(n))},M.pause=function(){M.paused=!0,C()},M.play=function(){M.paused&&(M.completed&&M.reset(),M.paused=!1,K.push(M),C(),U())},M.reverse=function(){x(),M.completed=!M.reversed,C()},M.restart=function(){M.reset(),M.play()},M.remove=function(n){rn(W(n),M)},M.reset(),M.autoplay&&M.play(),M}function tn(n,e){for(var t=e.length;t--;)M(n,e[t].animatable.target)&&e.splice(t,1)}function rn(n,e){var t=e.animations,r=e.children;tn(n,t);for(var a=r.length;a--;){var o=r[a],u=o.animations;tn(n,u),u.length||o.children.length||r.splice(a,1)}t.length||r.length||e.pause()}return en.version="3.2.1",en.speed=1,en.suspendWhenDocumentHidden=!0,en.running=K,en.remove=function(n){for(var e=W(n),t=K.length;t--;)rn(e,K[t])},en.get=A,en.set=z,en.convertPx=D,en.path=function(n,e){var t=i.str(n)?g(n)[0]:n,r=e||100;return function(n){return{property:n,el:t,svg:H(t),totalLength:q(t)*(r/100)}}},en.setDashoffset=function(n){var e=q(n);return n.setAttribute("stroke-dasharray",e),e},en.stagger=function(n,e){void 0===e&&(e={});var t=e.direction||"normal",r=e.easing?h(e.easing):null,a=e.grid,o=e.axis,u=e.from||0,c="first"===u,s="center"===u,f="last"===u,l=i.arr(n),d=l?parseFloat(n[0]):parseFloat(n),p=l?parseFloat(n[1]):0,v=C(l?n[1]:n)||0,g=e.start||0+(l?d:0),m=[],y=0;return function(n,e,i){if(c&&(u=0),s&&(u=(i-1)/2),f&&(u=i-1),!m.length){for(var h=0;h<i;h++){if(a){var b=s?(a[0]-1)/2:u%a[0],M=s?(a[1]-1)/2:Math.floor(u/a[0]),x=b-h%a[0],w=M-Math.floor(h/a[0]),k=Math.sqrt(x*x+w*w);"x"===o&&(k=-x),"y"===o&&(k=-w),m.push(k)}else m.push(Math.abs(u-h));y=Math.max.apply(Math,m)}r&&(m=m.map(function(n){return r(n/y)*y})),"reverse"===t&&(m=m.map(function(n){return o?n<0?-1*n:-n:Math.abs(y-n)}))}return g+(l?(p-d)/y:d)*(Math.round(100*m[e])/100)+v}},en.timeline=function(n){void 0===n&&(n={});var t=en(n);return t.duration=0,t.add=function(r,a){var o=K.indexOf(t),u=t.children;function c(n){n.passThrough=!0}o>-1&&K.splice(o,1);for(var s=0;s<u.length;s++)c(u[s]);var f=k(r,w(e,n));f.targets=f.targets||n.targets;var l=t.duration;f.autoplay=!1,f.direction=t.direction,f.timelineOffset=i.und(a)?l:N(a,l),c(t),t.seek(f.timelineOffset);var d=en(f);c(d),u.push(d);var p=R(u,n);return t.delay=p.delay,t.endDelay=p.endDelay,t.duration=p.duration,t.seek(0),t.reset(),t.autoplay&&t.play(),t},t},en.easing=h,en.penner=v,en.random=function(n,e){return Math.floor(Math.random()*(e-n+1))+n},en});
|
js/libraries/fabric.min.js
ADDED
The diff for this file is too large to render.
See raw diff
|
|
js/libraries/ffmpeg.min.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FFmpeg=t():e.FFmpeg=t()}(self,(function(){return e={497:(e,t,r)=>{r(72);var n=r(306).devDependencies;e.exports={corePath:"https://unpkg.com/@ffmpeg/core@".concat(n["@ffmpeg/core"].substring(1),"/dist/ffmpeg-core.js")}},663:(e,t,r)=>{function n(e,t,r,n,o,i,a){try{var c=e[i](a),s=c.value}catch(e){return void r(e)}c.done?t(s):Promise.resolve(s).then(n,o)}var o=r(72),i=function(e){return new Promise((function(t,r){var n=new FileReader;n.onload=function(){t(n.result)},n.onerror=function(e){var t=e.target.error.code;r(Error("File could not be read! Code=".concat(t)))},n.readAsArrayBuffer(e)}))};e.exports=function(){var e,t=(e=regeneratorRuntime.mark((function e(t){var r,n;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(r=t,void 0!==t){e.next=3;break}return e.abrupt("return",new Uint8Array);case 3:if("string"!=typeof t){e.next=16;break}if(!/data:_data\/([a-zA-Z]*);base64,([^"]*)/.test(t)){e.next=8;break}r=atob(t.split(",")[1]).split("").map((function(e){return e.charCodeAt(0)})),e.next=14;break;case 8:return e.next=10,fetch(o(t));case 10:return n=e.sent,e.next=13,n.arrayBuffer();case 13:r=e.sent;case 14:e.next=20;break;case 16:if(!(t instanceof File||t instanceof Blob)){e.next=20;break}return e.next=19,i(t);case 19:r=e.sent;case 20:return e.abrupt("return",new Uint8Array(r));case 21:case"end":return e.stop()}}),e)})),function(){var t=this,r=arguments;return new Promise((function(o,i){var a=e.apply(t,r);function c(e){n(a,o,i,c,s,"next",e)}function s(e){n(a,o,i,c,s,"throw",e)}c(void 0)}))});return function(e){return t.apply(this,arguments)}}()},452:(e,t,r)=>{function n(e,t,r,n,o,i,a){try{var c=e[i](a),s=c.value}catch(e){return void r(e)}c.done?t(s):Promise.resolve(s).then(n,o)}function o(e){return function(){var t=this,r=arguments;return new Promise((function(o,i){var a=e.apply(t,r);function c(e){n(a,o,i,c,s,"next",e)}function s(e){n(a,o,i,c,s,"throw",e)}c(void 0)}))}}var i=r(72),a=r(185).log,c=function(){var e=o(regeneratorRuntime.mark((function e(t,r){var n,o,i;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a("info","fetch ".concat(t)),e.next=3,fetch(t);case 3:return e.next=5,e.sent.arrayBuffer();case 5:return n=e.sent,a("info","".concat(t," file size = ").concat(n.byteLength," bytes")),o=new Blob([n],{type:r}),i=URL.createObjectURL(o),a("info","".concat(t," blob URL = ").concat(i)),e.abrupt("return",i);case 11:case"end":return e.stop()}}),e)})));return function(t,r){return e.apply(this,arguments)}}();e.exports=function(){var e=o(regeneratorRuntime.mark((function e(t){var r,n,o,s,u;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if("string"==typeof(r=t.corePath)){e.next=3;break}throw Error("corePath should be a string!");case 3:return n=i(r),e.next=6,c(n,"application/javascript");case 6:return o=e.sent,e.next=9,c(n.replace("ffmpeg-core.js","ffmpeg-core.wasm"),"application/wasm");case 9:return s=e.sent,e.next=12,c(n.replace("ffmpeg-core.js","ffmpeg-core.worker.js"),"application/javascript");case 12:if(u=e.sent,"undefined"!=typeof createFFmpegCore){e.next=15;break}return e.abrupt("return",new Promise((function(e){var t=document.createElement("script");t.src=o,t.type="text/javascript",t.addEventListener("load",(function r(){t.removeEventListener("load",r),a("info","ffmpeg-core.js script loaded"),e({createFFmpegCore,corePath:o,wasmPath:s,workerPath:u})})),document.getElementsByTagName("head")[0].appendChild(t)})));case 15:return a("info","ffmpeg-core.js script is loaded already"),e.abrupt("return",Promise.resolve({createFFmpegCore,corePath:o,wasmPath:s,workerPath:u}));case 17:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()},698:(e,t,r)=>{var n=r(497),o=r(452),i=r(663);e.exports={defaultOptions:n,getCreateFFmpegCore:o,fetchFile:i}},500:e=>{e.exports={defaultArgs:["./ffmpeg","-nostdin","-y"],baseOptions:{log:!1,logger:function(){},progress:function(){},corePath:""}}},906:(e,t,r)=>{function n(e){return function(e){if(Array.isArray(e))return o(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return o(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?o(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function i(e,t,r,n,o,i,a){try{var c=e[i](a),s=c.value}catch(e){return void r(e)}c.done?t(s):Promise.resolve(s).then(n,o)}function a(e){return function(){var t=this,r=arguments;return new Promise((function(n,o){var a=e.apply(t,r);function c(e){i(a,n,o,c,s,"next",e)}function s(e){i(a,n,o,c,s,"throw",e)}c(void 0)}))}}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?c(Object(r),!0).forEach((function(t){u(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):c(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function u(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function f(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=r(500),p=l.defaultArgs,h=l.baseOptions,m=r(185),g=m.setLogging,d=m.setCustomLogger,y=m.log,v=r(583),b=r(319),w=r(698),x=w.defaultOptions,j=w.getCreateFFmpegCore,E=r(306).version,O=Error("ffmpeg.wasm is not ready, make sure you have completed load().");e.exports=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=s(s(s({},h),x),e),r=t.log,o=t.logger,i=t.progress,c=f(t,["log","logger","progress"]),u=null,l=null,m=null,w=!1,F=i,L=function(e){"FFMPEG_END"===e&&null!==m&&(m(),m=null,w=!1)},P=function(e){var t=e.type,r=e.message;y(t,r),v(r,F),L(r)},k=function(){var e=a(regeneratorRuntime.mark((function e(){var t,r,n,o,i;return regeneratorRuntime.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(y("info","load ffmpeg-core"),null!==u){e.next=17;break}return y("info","loading ffmpeg-core"),e.next=5,j(c);case 5:return t=e.sent,r=t.createFFmpegCore,n=t.corePath,o=t.workerPath,i=t.wasmPath,e.next=12,r({mainScriptUrlOrBlob:n,printErr:function(e){return P({type:"fferr",message:e})},print:function(e){return P({type:"ffout",message:e})},locateFile:function(e,t){if("undefined"!=typeof window){if(void 0!==i&&e.endsWith("ffmpeg-core.wasm"))return i;if(void 0!==o&&e.endsWith("ffmpeg-core.worker.js"))return o}return t+e}});case 12:u=e.sent,l=u.cwrap("proxy_main","number",["number","number"]),y("info","ffmpeg-core loaded"),e.next=18;break;case 17:throw Error("ffmpeg.wasm was loaded, you should not load it again, use ffmpeg.isLoaded() to check next time.");case 18:case"end":return e.stop()}}),e)})));return function(){return e.apply(this,arguments)}}(),S=function(){return null!==u},A=function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];if(y("info","run ffmpeg command: ".concat(t.join(" "))),null===u)throw O;if(w)throw Error("ffmpeg.wasm can only run one command at a time");return w=!0,new Promise((function(e){var r=[].concat(n(p),t).filter((function(e){return 0!==e.length}));m=e,l.apply(void 0,n(b(u,r)))}))},_=function(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];if(y("info","run FS.".concat(e," ").concat(r.map((function(e){return"string"==typeof e?e:"<".concat(e.length," bytes binary file>")})).join(" "))),null===u)throw O;var o=null;try{var i;o=(i=u.FS)[e].apply(i,r)}catch(t){throw"readdir"===e?Error("ffmpeg.FS('readdir', '".concat(r[0],"') error. Check if the path exists, ex: ffmpeg.FS('readdir', '/')")):"readFile"===e?Error("ffmpeg.FS('readFile', '".concat(r[0],"') error. Check if the path exists")):Error("Oops, something went wrong in FS operation.")}return o},C=function(){if(null===u)throw O;w=!1,u.exit(1),u=null,l=null,m=null},R=function(e){F=e},T=function(e){d(e)};return g(r),d(o),y("info","use ffmpeg.wasm v".concat(E)),{setProgress:R,setLogger:T,setLogging:g,load:k,isLoaded:S,run:A,exit:C,FS:_}}},352:(e,t,r)=>{r(666);var n=r(906),o=r(698).fetchFile;e.exports={createFFmpeg:n,fetchFile:o}},185:e=>{var t=!1,r=function(){};e.exports={logging:t,setLogging:function(e){t=e},setCustomLogger:function(e){r=e},log:function(e,n){r({type:e,message:n}),t&&console.log("[".concat(e,"] ").concat(n))}}},319:e=>{e.exports=function(e,t){var r=e._malloc(t.length*Uint32Array.BYTES_PER_ELEMENT);return t.forEach((function(t,n){var o=e._malloc(t.length+1);e.writeAsciiToMemory(t,o),e.setValue(r+Uint32Array.BYTES_PER_ELEMENT*n,o,"i32")})),[t.length,r]}},583:e=>{function t(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var r=0,n=0,o=function(e){var r,n,o=(r=e.split(":"),n=3,function(e){if(Array.isArray(e))return e}(r)||function(e,t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e)){var r=[],n=!0,o=!1,i=void 0;try{for(var a,c=e[Symbol.iterator]();!(n=(a=c.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){o=!0,i=e}finally{try{n||null==c.return||c.return()}finally{if(o)throw i}}return r}}(r,n)||function(e,r){if(e){if("string"==typeof e)return t(e,r);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?t(e,r):void 0}}(r,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),i=o[0],a=o[1],c=o[2];return 60*parseFloat(i)*60+60*parseFloat(a)+parseFloat(c)};e.exports=function(e,t){if("string"==typeof e)if(e.startsWith(" Duration")){var i=e.split(", ")[0].split(": ")[1],a=o(i);t({duration:a,ratio:n}),(0===r||r>a)&&(r=a)}else if(e.startsWith("frame")||e.startsWith("size")){var c=e.split("time=")[1].split(" ")[0],s=o(c);t({ratio:n=s/r,time:s})}else e.startsWith("video:")&&(t({ratio:1}),r=0)}},666:e=>{var t=function(e){"use strict";var t,r=Object.prototype,n=r.hasOwnProperty,o="function"==typeof Symbol?Symbol:{},i=o.iterator||"@@iterator",a=o.asyncIterator||"@@asyncIterator",c=o.toStringTag||"@@toStringTag";function s(e,t,r){return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{s({},"")}catch(e){s=function(e,t,r){return e[t]=r}}function u(e,t,r,n){var o=t&&t.prototype instanceof d?t:d,i=Object.create(o.prototype),a=new k(n||[]);return i._invoke=function(e,t,r){var n=l;return function(o,i){if(n===h)throw new Error("Generator is already running");if(n===m){if("throw"===o)throw i;return A()}for(r.method=o,r.arg=i;;){var a=r.delegate;if(a){var c=F(a,r);if(c){if(c===g)continue;return c}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if(n===l)throw n=m,r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);n=h;var s=f(e,t,r);if("normal"===s.type){if(n=r.done?m:p,s.arg===g)continue;return{value:s.arg,done:r.done}}"throw"===s.type&&(n=m,r.method="throw",r.arg=s.arg)}}}(e,r,a),i}function f(e,t,r){try{return{type:"normal",arg:e.call(t,r)}}catch(e){return{type:"throw",arg:e}}}e.wrap=u;var l="suspendedStart",p="suspendedYield",h="executing",m="completed",g={};function d(){}function y(){}function v(){}var b={};b[i]=function(){return this};var w=Object.getPrototypeOf,x=w&&w(w(S([])));x&&x!==r&&n.call(x,i)&&(b=x);var j=v.prototype=d.prototype=Object.create(b);function E(e){["next","throw","return"].forEach((function(t){s(e,t,(function(e){return this._invoke(t,e)}))}))}function O(e,t){function r(o,i,a,c){var s=f(e[o],e,i);if("throw"!==s.type){var u=s.arg,l=u.value;return l&&"object"==typeof l&&n.call(l,"__await")?t.resolve(l.__await).then((function(e){r("next",e,a,c)}),(function(e){r("throw",e,a,c)})):t.resolve(l).then((function(e){u.value=e,a(u)}),(function(e){return r("throw",e,a,c)}))}c(s.arg)}var o;this._invoke=function(e,n){function i(){return new t((function(t,o){r(e,n,t,o)}))}return o=o?o.then(i,i):i()}}function F(e,r){var n=e.iterator[r.method];if(n===t){if(r.delegate=null,"throw"===r.method){if(e.iterator.return&&(r.method="return",r.arg=t,F(e,r),"throw"===r.method))return g;r.method="throw",r.arg=new TypeError("The iterator does not provide a 'throw' method")}return g}var o=f(n,e.iterator,r.arg);if("throw"===o.type)return r.method="throw",r.arg=o.arg,r.delegate=null,g;var i=o.arg;return i?i.done?(r[e.resultName]=i.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=t),r.delegate=null,g):i:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,g)}function L(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function P(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function k(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(L,this),this.reset(!0)}function S(e){if(e){var r=e[i];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,a=function r(){for(;++o<e.length;)if(n.call(e,o))return r.value=e[o],r.done=!1,r;return r.value=t,r.done=!0,r};return a.next=a}}return{next:A}}function A(){return{value:t,done:!0}}return y.prototype=j.constructor=v,v.constructor=y,y.displayName=s(v,c,"GeneratorFunction"),e.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===y||"GeneratorFunction"===(t.displayName||t.name))},e.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,v):(e.__proto__=v,s(e,c,"GeneratorFunction")),e.prototype=Object.create(j),e},e.awrap=function(e){return{__await:e}},E(O.prototype),O.prototype[a]=function(){return this},e.AsyncIterator=O,e.async=function(t,r,n,o,i){void 0===i&&(i=Promise);var a=new O(u(t,r,n,o),i);return e.isGeneratorFunction(r)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},E(j),s(j,c,"Generator"),j[i]=function(){return this},j.toString=function(){return"[object Generator]"},e.keys=function(e){var t=[];for(var r in e)t.push(r);return t.reverse(),function r(){for(;t.length;){var n=t.pop();if(n in e)return r.value=n,r.done=!1,r}return r.done=!0,r}},e.values=S,k.prototype={constructor:k,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=t,this.done=!1,this.delegate=null,this.method="next",this.arg=t,this.tryEntries.forEach(P),!e)for(var r in this)"t"===r.charAt(0)&&n.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=t)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var r=this;function o(n,o){return c.type="throw",c.arg=e,r.next=n,o&&(r.method="next",r.arg=t),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],c=a.completion;if("root"===a.tryLoc)return o("end");if(a.tryLoc<=this.prev){var s=n.call(a,"catchLoc"),u=n.call(a,"finallyLoc");if(s&&u){if(this.prev<a.catchLoc)return o(a.catchLoc,!0);if(this.prev<a.finallyLoc)return o(a.finallyLoc)}else if(s){if(this.prev<a.catchLoc)return o(a.catchLoc,!0)}else{if(!u)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return o(a.finallyLoc)}}}},abrupt:function(e,t){for(var r=this.tryEntries.length-1;r>=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=e,a.arg=t,i?(this.method="next",this.next=i.finallyLoc,g):this.complete(a)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),g},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),P(r),g}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var o=n.arg;P(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:S(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),g}},e}(e.exports);try{regeneratorRuntime=t}catch(e){Function("r","regeneratorRuntime = r")(t)}},72:function(e,t,r){var n,o;void 0===(o="function"==typeof(n=function(){return function(){var e=arguments.length;if(0===e)throw new Error("resolveUrl requires at least one argument; got none.");var t=document.createElement("base");if(t.href=arguments[0],1===e)return t.href;var r=document.getElementsByTagName("head")[0];r.insertBefore(t,r.firstChild);for(var n,o=document.createElement("a"),i=1;i<e;i++)o.href=arguments[i],n=o.href,t.href=n;return r.removeChild(t),n}})?n.call(t,r,t,e):n)||(e.exports=o)},306:e=>{"use strict";e.exports=JSON.parse('{"name":"@ffmpeg/ffmpeg","version":"0.10.1","description":"FFmpeg WebAssembly version","main":"src/index.js","types":"src/index.d.ts","directories":{"example":"examples"},"scripts":{"start":"node scripts/server.js","build":"rimraf dist && webpack --config scripts/webpack.config.prod.js","prepublishOnly":"npm run build","lint":"eslint src","wait":"rimraf dist && wait-on http://localhost:3000/dist/ffmpeg.dev.js","test":"npm-run-all -p -r start test:all","test:all":"npm-run-all wait test:browser:ffmpeg test:node:all","test:node":"node --experimental-wasm-threads --experimental-wasm-bulk-memory node_modules/.bin/_mocha --exit --bail --require ./scripts/test-helper.js","test:node:all":"npm run test:node -- ./tests/*.test.js","test:browser":"mocha-headless-chrome -a allow-file-access-from-files -a incognito -a no-sandbox -a disable-setuid-sandbox -a disable-logging -t 300000","test:browser:ffmpeg":"npm run test:browser -- -f ./tests/ffmpeg.test.html"},"browser":{"./src/node/index.js":"./src/browser/index.js"},"repository":{"type":"git","url":"git+https://github.com/ffmpegwasm/ffmpeg.wasm.git"},"keywords":["ffmpeg","WebAssembly","video"],"author":"Jerome Wu <[email protected]>","license":"MIT","bugs":{"url":"https://github.com/ffmpegwasm/ffmpeg.wasm/issues"},"engines":{"node":">=12.16.1"},"homepage":"https://github.com/ffmpegwasm/ffmpeg.wasm#readme","dependencies":{"is-url":"^1.2.4","node-fetch":"^2.6.1","regenerator-runtime":"^0.13.7","resolve-url":"^0.2.1"},"devDependencies":{"@babel/core":"^7.12.3","@babel/preset-env":"^7.12.1","@ffmpeg/core":"^0.10.0","@types/emscripten":"^1.39.4","babel-loader":"^8.1.0","chai":"^4.2.0","cors":"^2.8.5","eslint":"^7.12.1","eslint-config-airbnb-base":"^14.1.0","eslint-plugin-import":"^2.22.1","express":"^4.17.1","mocha":"^8.2.1","mocha-headless-chrome":"^2.0.3","npm-run-all":"^4.1.5","wait-on":"^5.3.0","webpack":"^5.3.2","webpack-cli":"^4.1.0","webpack-dev-middleware":"^4.0.0"}}')}},t={},function r(n){if(t[n])return t[n].exports;var o=t[n]={exports:{}};return e[n].call(o.exports,o,o.exports,r),o.exports}(352);var e,t}));
|
2 |
+
//# sourceMappingURL=ffmpeg.min.js.map
|
js/libraries/jquery.nice-select.min.js
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* jQuery Nice Select - v1.0
|
2 |
+
https://github.com/hernansartorio/jquery-nice-select
|
3 |
+
Made by Hernán Sartorio */
|
4 |
+
!function(e){e.fn.niceSelect=function(t){function s(t){t.after(e("<div></div>").addClass("nice-select").addClass(t.attr("class")||"").addClass(t.attr("disabled")?"disabled":"").attr("tabindex",t.attr("disabled")?null:"0").html('<span class="current"></span><ul class="list"></ul>'));var s=t.next(),n=t.find("option"),i=t.find("option:selected");s.find(".current").html(i.data("display")||i.text()),n.each(function(t){var n=e(this),i=n.data("display");s.find("ul").append(e("<li></li>").attr("data-value",n.val()).attr("data-display",i||null).addClass("option"+(n.is(":selected")?" selected":"")+(n.is(":disabled")?" disabled":"")).html(n.text()))})}if("string"==typeof t)return"update"==t?this.each(function(){var t=e(this),n=e(this).next(".nice-select"),i=n.hasClass("open");n.length&&(n.remove(),s(t),i&&t.next().trigger("click"))}):"destroy"==t?(this.each(function(){var t=e(this),s=e(this).next(".nice-select");s.length&&(s.remove(),t.css("display",""))}),0==e(".nice-select").length&&e(document).off(".nice_select")):console.log('Method "'+t+'" does not exist.'),this;this.hide(),this.each(function(){var t=e(this);t.next().hasClass("nice-select")||s(t)}),e(document).off(".nice_select"),e(document).on("click.nice_select",".nice-select",function(t){var s=e(this);e(".nice-select").not(s).removeClass("open"),s.toggleClass("open"),s.hasClass("open")?(s.find(".option"),s.find(".focus").removeClass("focus"),s.find(".selected").addClass("focus")):s.focus()}),e(document).on("click.nice_select",function(t){0===e(t.target).closest(".nice-select").length&&e(".nice-select").removeClass("open").find(".option")}),e(document).on("click.nice_select",".nice-select .option:not(.disabled)",function(t){var s=e(this),n=s.closest(".nice-select");n.find(".selected").removeClass("selected"),s.addClass("selected");var i=s.data("display")||s.text();n.find(".current").text(i),n.prev("select").val(s.data("value")).trigger("change")}),e(document).on("keydown.nice_select",".nice-select",function(t){var s=e(this),n=e(s.find(".focus")||s.find(".list .option.selected"));if(32==t.keyCode||13==t.keyCode)return s.hasClass("open")?n.trigger("click"):s.trigger("click"),!1;if(40==t.keyCode){if(s.hasClass("open")){var i=n.nextAll(".option:not(.disabled)").first();i.length>0&&(s.find(".focus").removeClass("focus"),i.addClass("focus"))}else s.trigger("click");return!1}if(38==t.keyCode){if(s.hasClass("open")){var l=n.prevAll(".option:not(.disabled)").first();l.length>0&&(s.find(".focus").removeClass("focus"),l.addClass("focus"))}else s.trigger("click");return!1}if(27==t.keyCode)s.hasClass("open")&&s.trigger("click");else if(9==t.keyCode&&s.hasClass("open"))return!1});var n=document.createElement("a").style;return n.cssText="pointer-events:auto","auto"!==n.pointerEvents&&e("html").addClass("no-csspointerevents"),this}}(jQuery);
|
js/libraries/localbase.js
ADDED
The diff for this file is too large to render.
See raw diff
|
|
js/libraries/pickr.min.js
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*! Pickr 1.7.2 MIT | https://github.com/Simonwep/pickr */
|
2 |
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Pickr=e():t.Pickr=e()}(window,(function(){return function(t){var e={};function o(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,o),i.l=!0,i.exports}return o.m=t,o.c=e,o.d=function(t,e,n){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)o.d(n,i,function(e){return t[e]}.bind(null,i));return n},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=1)}([function(t){t.exports=JSON.parse('{"a":"1.7.2"}')},function(t,e,o){"use strict";o.r(e);var n={};function i(t,e,o,n,i={}){e instanceof HTMLCollection||e instanceof NodeList?e=Array.from(e):Array.isArray(e)||(e=[e]),Array.isArray(o)||(o=[o]);for(const r of e)for(const e of o)r[t](e,n,{capture:!1,...i});return Array.prototype.slice.call(arguments,1)}o.r(n),o.d(n,"on",(function(){return r})),o.d(n,"off",(function(){return s})),o.d(n,"createElementFromString",(function(){return a})),o.d(n,"createFromTemplate",(function(){return c})),o.d(n,"eventPath",(function(){return l})),o.d(n,"resolveElement",(function(){return p})),o.d(n,"adjustableInputNumbers",(function(){return u}));const r=i.bind(null,"addEventListener"),s=i.bind(null,"removeEventListener");function a(t){const e=document.createElement("div");return e.innerHTML=t.trim(),e.firstElementChild}function c(t){const e=(t,e)=>{const o=t.getAttribute(e);return t.removeAttribute(e),o},o=(t,n={})=>{const i=e(t,":obj"),r=e(t,":ref"),s=i?n[i]={}:n;r&&(n[r]=t);for(const n of Array.from(t.children)){const t=e(n,":arr"),i=o(n,t?{}:s);t&&(s[t]||(s[t]=[])).push(Object.keys(i).length?i:n)}return n};return o(a(t))}function l(t){let e=t.path||t.composedPath&&t.composedPath();if(e)return e;let o=t.target.parentElement;for(e=[t.target,o];o=o.parentElement;)e.push(o);return e.push(document,window),e}function p(t){return t instanceof Element?t:"string"==typeof t?t.split(/>>/g).reduce((t,e,o,n)=>(t=t.querySelector(e),o<n.length-1?t.shadowRoot:t),document):null}function u(t,e=(t=>t)){function o(o){const n=[.001,.01,.1][Number(o.shiftKey||2*o.ctrlKey)]*(o.deltaY<0?1:-1);let i=0,r=t.selectionStart;t.value=t.value.replace(/[\d.]+/g,(t,o)=>o<=r&&o+t.length>=r?(r=o,e(Number(t),n,i)):(i++,t)),t.focus(),t.setSelectionRange(r,r),o.preventDefault(),t.dispatchEvent(new Event("input"))}r(t,"focus",()=>r(window,"wheel",o,{passive:!1})),r(t,"blur",()=>s(window,"wheel",o))}var h=o(0);const{min:d,max:f,floor:m,round:v}=Math;function b(t,e,o){e/=100,o/=100;const n=m(t=t/360*6),i=t-n,r=o*(1-e),s=o*(1-i*e),a=o*(1-(1-i)*e),c=n%6;return[255*[o,s,r,r,a,o][c],255*[a,o,o,s,r,r][c],255*[r,r,a,o,o,s][c]]}function g(t,e,o){const n=(2-(e/=100))*(o/=100)/2;return 0!==n&&(e=1===n?0:n<.5?e*o/(2*n):e*o/(2-2*n)),[t,100*e,100*n]}function y(t,e,o){const n=d(t/=255,e/=255,o/=255),i=f(t,e,o),r=i-n;let s,a;if(0===r)s=a=0;else{a=r/i;const n=((i-t)/6+r/2)/r,c=((i-e)/6+r/2)/r,l=((i-o)/6+r/2)/r;t===i?s=l-c:e===i?s=1/3+n-l:o===i&&(s=2/3+c-n),s<0?s+=1:s>1&&(s-=1)}return[360*s,100*a,100*i]}function _(t,e,o,n){return e/=100,o/=100,[...y(255*(1-d(1,(t/=100)*(1-(n/=100))+n)),255*(1-d(1,e*(1-n)+n)),255*(1-d(1,o*(1-n)+n)))]}function w(t,e,o){e/=100;const n=2*(e*=(o/=100)<.5?o:1-o)/(o+e)*100,i=100*(o+e);return[t,isNaN(n)?0:n,i]}function A(t){return y(...t.match(/.{2}/g).map(t=>parseInt(t,16)))}function C(t){t=t.match(/^[a-zA-Z]+$/)?function(t){if("black"===t.toLowerCase())return"#000";const e=document.createElement("canvas").getContext("2d");return e.fillStyle=t,"#000"===e.fillStyle?null:e.fillStyle}(t):t;const e={cmyk:/^cmyk[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)/i,rgba:/^((rgba)|rgb)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hsla:/^((hsla)|hsl)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hsva:/^((hsva)|hsv)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hexa:/^#?(([\dA-Fa-f]{3,4})|([\dA-Fa-f]{6})|([\dA-Fa-f]{8}))$/i},o=t=>t.map(t=>/^(|\d+)\.\d+|\d+$/.test(t)?Number(t):void 0);let n;t:for(const i in e){if(!(n=e[i].exec(t)))continue;const r=t=>!!n[2]==("number"==typeof t);switch(i){case"cmyk":{const[,t,e,r,s]=o(n);if(t>100||e>100||r>100||s>100)break t;return{values:_(t,e,r,s),type:i}}case"rgba":{const[,,,t,e,s,a]=o(n);if(t>255||e>255||s>255||a<0||a>1||!r(a))break t;return{values:[...y(t,e,s),a],a:a,type:i}}case"hexa":{let[,t]=n;4!==t.length&&3!==t.length||(t=t.split("").map(t=>t+t).join(""));const e=t.substring(0,6);let o=t.substring(6);return o=o?parseInt(o,16)/255:void 0,{values:[...A(e),o],a:o,type:i}}case"hsla":{const[,,,t,e,s,a]=o(n);if(t>360||e>100||s>100||a<0||a>1||!r(a))break t;return{values:[...w(t,e,s),a],a:a,type:i}}case"hsva":{const[,,,t,e,s,a]=o(n);if(t>360||e>100||s>100||a<0||a>1||!r(a))break t;return{values:[t,e,s,a],a:a,type:i}}}}return{values:null,type:null}}function k(t=0,e=0,o=0,n=1){const i=(t,e)=>(o=-1)=>e(~o?t.map(t=>Number(t.toFixed(o))):t),r={h:t,s:e,v:o,a:n,toHSVA(){const t=[r.h,r.s,r.v,r.a];return t.toString=i(t,t=>"hsva(".concat(t[0],", ").concat(t[1],"%, ").concat(t[2],"%, ").concat(r.a,")")),t},toHSLA(){const t=[...g(r.h,r.s,r.v),r.a];return t.toString=i(t,t=>"hsla(".concat(t[0],", ").concat(t[1],"%, ").concat(t[2],"%, ").concat(r.a,")")),t},toRGBA(){const t=[...b(r.h,r.s,r.v),r.a];return t.toString=i(t,t=>"rgba(".concat(t[0],", ").concat(t[1],", ").concat(t[2],", ").concat(r.a,")")),t},toCMYK(){const t=function(t,e,o){const n=b(t,e,o),i=n[0]/255,r=n[1]/255,s=n[2]/255,a=d(1-i,1-r,1-s);return[100*(1===a?0:(1-i-a)/(1-a)),100*(1===a?0:(1-r-a)/(1-a)),100*(1===a?0:(1-s-a)/(1-a)),100*a]}(r.h,r.s,r.v);return t.toString=i(t,t=>"cmyk(".concat(t[0],"%, ").concat(t[1],"%, ").concat(t[2],"%, ").concat(t[3],"%)")),t},toHEXA(){const t=function(t,e,o){return b(t,e,o).map(t=>v(t).toString(16).padStart(2,"0"))}(r.h,r.s,r.v),e=r.a>=1?"":Number((255*r.a).toFixed(0)).toString(16).toUpperCase().padStart(2,"0");return e&&t.push(e),t.toString=()=>"#".concat(t.join("").toUpperCase()),t},clone:()=>k(r.h,r.s,r.v,r.a)};return r}const S=t=>Math.max(Math.min(t,1),0);function O(t){const e={options:Object.assign({lock:null,onchange:()=>0,onstop:()=>0},t),_keyboard(t){const{options:o}=e,{type:n,key:i}=t;if(document.activeElement===o.wrapper){const{lock:o}=e.options,r="ArrowUp"===i,s="ArrowRight"===i,a="ArrowDown"===i,c="ArrowLeft"===i;if("keydown"===n&&(r||s||a||c)){let n=0,i=0;"v"===o?n=r||s?1:-1:"h"===o?n=r||s?-1:1:(i=r?-1:a?1:0,n=c?-1:s?1:0),e.update(S(e.cache.x+.01*n),S(e.cache.y+.01*i)),t.preventDefault()}else i.startsWith("Arrow")&&(e.options.onstop(),t.preventDefault())}},_tapstart(t){r(document,["mouseup","touchend","touchcancel"],e._tapstop),r(document,["mousemove","touchmove"],e._tapmove),t.cancelable&&t.preventDefault(),e._tapmove(t)},_tapmove(t){const{options:o,cache:n}=e,{lock:i,element:r,wrapper:s}=o,a=s.getBoundingClientRect();let c=0,l=0;if(t){const e=t&&t.touches&&t.touches[0];c=t?(e||t).clientX:0,l=t?(e||t).clientY:0,c<a.left?c=a.left:c>a.left+a.width&&(c=a.left+a.width),l<a.top?l=a.top:l>a.top+a.height&&(l=a.top+a.height),c-=a.left,l-=a.top}else n&&(c=n.x*a.width,l=n.y*a.height);"h"!==i&&(r.style.left="calc(".concat(c/a.width*100,"% - ").concat(r.offsetWidth/2,"px)")),"v"!==i&&(r.style.top="calc(".concat(l/a.height*100,"% - ").concat(r.offsetHeight/2,"px)")),e.cache={x:c/a.width,y:l/a.height};const p=S(c/a.width),u=S(l/a.height);switch(i){case"v":return o.onchange(p);case"h":return o.onchange(u);default:return o.onchange(p,u)}},_tapstop(){e.options.onstop(),s(document,["mouseup","touchend","touchcancel"],e._tapstop),s(document,["mousemove","touchmove"],e._tapmove)},trigger(){e._tapmove()},update(t=0,o=0){const{left:n,top:i,width:r,height:s}=e.options.wrapper.getBoundingClientRect();"h"===e.options.lock&&(o=t),e._tapmove({clientX:n+r*t,clientY:i+s*o})},destroy(){const{options:t,_tapstart:o,_keyboard:n}=e;s(document,["keydown","keyup"],n),s([t.wrapper,t.element],"mousedown",o),s([t.wrapper,t.element],"touchstart",o,{passive:!1})}},{options:o,_tapstart:n,_keyboard:i}=e;return r([o.wrapper,o.element],"mousedown",n),r([o.wrapper,o.element],"touchstart",n,{passive:!1}),r(document,["keydown","keyup"],i),e}function E(t={}){t=Object.assign({onchange:()=>0,className:"",elements:[]},t);const e=r(t.elements,"click",e=>{t.elements.forEach(o=>o.classList[e.target===o?"add":"remove"](t.className)),t.onchange(e)});return{destroy:()=>s(...e)}}
|
3 |
+
/*! NanoPop 1.3.0 MIT | https://github.com/Simonwep/nanopop */
|
4 |
+
let x=(()=>{class t{constructor(e,o,{positionFlipOrder:n=t.defaultPositionFlipOrder,variantFlipOrder:i=t.defaultVariantFlipOrder,container:r=document.documentElement.getBoundingClientRect(),forceApplyOnFailure:s=!1,margin:a=8,position:c="bottom-start"}={}){this.o={positionFlipOrder:n,variantFlipOrder:i,reference:e,popper:o,position:c,container:r,forceApplyOnFailure:s,margin:a}}update(t=this.o,e=!1){const{container:o,reference:n,popper:i,margin:r,position:s,forceApplyOnFailure:a,variantFlipOrder:c,positionFlipOrder:l}=this.o={...this.o,...t};i.style.left="0",i.style.top="0";const p=n.getBoundingClientRect(),u=i.getBoundingClientRect(),h={t:p.top-u.height-r,b:p.bottom+r,r:p.right+r,l:p.left-u.width-r},d={vm:-u.width/2+(p.left+p.width/2),vs:p.left,ve:p.left+p.width-u.width,hs:p.bottom-p.height,he:p.bottom-u.height,hm:p.bottom-p.height/2-u.height/2},[f,m="middle"]=s.split("-"),v=l[f],b=c[m],{top:g,left:y,bottom:_,right:w}=o;for(const t of v){const o="t"===t||"b"===t,n=h[t],[r,s]=o?["top","left"]:["left","top"],[a,c]=o?[u.height,u.width]:[u.width,u.height],[l,p]=o?[_,w]:[w,_],[f,m]=o?[g,y]:[y,g];if(e||!(n<f||n+a>l))for(const a of b){const l=d[(o?"v":"h")+a];if(e||!(l<m||l+c>p))return i.style[s]=l-u[s]+"px",i.style[r]=n-u[r]+"px",t+a}}return a?this.update(void 0,!0):null}}return t.version="1.3.0",t.defaultVariantFlipOrder={start:"sme",middle:"mse",end:"ems"},t.defaultPositionFlipOrder={top:"tbrl",right:"rltb",bottom:"btrl",left:"lrbt"},t})();function L(t,e,o){return e in t?Object.defineProperty(t,e,{value:o,enumerable:!0,configurable:!0,writable:!0}):t[e]=o,t}class B{constructor(t){L(this,"_initializingActive",!0),L(this,"_recalc",!0),L(this,"_nanopop",null),L(this,"_root",null),L(this,"_color",k()),L(this,"_lastColor",k()),L(this,"_swatchColors",[]),L(this,"_eventListener",{init:[],save:[],hide:[],show:[],clear:[],change:[],changestop:[],cancel:[],swatchselect:[]}),this.options=t=Object.assign({...B.DEFAULT_OPTIONS},t);const{swatches:e,components:o,theme:n,sliders:i,lockOpacity:r,padding:s}=t;["nano","monolith"].includes(n)&&!i&&(t.sliders="h"),o.interaction||(o.interaction={});const{preview:a,opacity:c,hue:l,palette:p}=o;o.opacity=!r&&c,o.palette=p||a||c||l,this._preBuild(),this._buildComponents(),this._bindEvents(),this._finalBuild(),e&&e.length&&e.forEach(t=>this.addSwatch(t));const{button:u,app:h}=this._root;this._nanopop=new x(u,h,{margin:s}),u.setAttribute("role","button"),u.setAttribute("aria-label",this._t("btn:toggle"));const d=this;requestAnimationFrame((function e(){if(!h.offsetWidth)return requestAnimationFrame(e);d.setColor(t.default),d._rePositioningPicker(),t.defaultRepresentation&&(d._representation=t.defaultRepresentation,d.setColorRepresentation(d._representation)),t.showAlways&&d.show(),d._initializingActive=!1,d._emit("init")}))}_preBuild(){const{options:t}=this;for(const e of["el","container"])t[e]=p(t[e]);this._root=(t=>{const{components:e,useAsButton:o,inline:n,appClass:i,theme:r,lockOpacity:s}=t.options,a=t=>t?"":'style="display:none" hidden',l=e=>t._t(e),p=c('\n <div :ref="root" class="pickr">\n\n '.concat(o?"":'<button type="button" :ref="button" class="pcr-button"></button>','\n\n <div :ref="app" class="pcr-app ').concat(i||"",'" data-theme="').concat(r,'" ').concat(n?'style="position: unset"':"",' aria-label="').concat(l("ui:dialog"),'" role="window">\n <div class="pcr-selection" ').concat(a(e.palette),'>\n <div :obj="preview" class="pcr-color-preview" ').concat(a(e.preview),'>\n <button type="button" :ref="lastColor" class="pcr-last-color" aria-label="').concat(l("btn:last-color"),'"></button>\n <div :ref="currentColor" class="pcr-current-color"></div>\n </div>\n\n <div :obj="palette" class="pcr-color-palette">\n <div :ref="picker" class="pcr-picker"></div>\n <div :ref="palette" class="pcr-palette" tabindex="0" aria-label="').concat(l("aria:palette"),'" role="listbox"></div>\n </div>\n\n <div :obj="hue" class="pcr-color-chooser" ').concat(a(e.hue),'>\n <div :ref="picker" class="pcr-picker"></div>\n <div :ref="slider" class="pcr-hue pcr-slider" tabindex="0" aria-label="').concat(l("aria:hue"),'" role="slider"></div>\n </div>\n\n <div :obj="opacity" class="pcr-color-opacity" ').concat(a(e.opacity),'>\n <div :ref="picker" class="pcr-picker"></div>\n <div :ref="slider" class="pcr-opacity pcr-slider" tabindex="0" aria-label="').concat(l("aria:opacity"),'" role="slider"></div>\n </div>\n </div>\n\n <div class="pcr-swatches ').concat(e.palette?"":"pcr-last",'" :ref="swatches"></div>\n\n <div :obj="interaction" class="pcr-interaction" ').concat(a(Object.keys(e.interaction).length),'>\n <input :ref="result" class="pcr-result" type="text" spellcheck="false" ').concat(a(e.interaction.input),' aria-label="').concat(l("aria:input"),'">\n\n <input :arr="options" class="pcr-type" data-type="HEXA" value="').concat(s?"HEX":"HEXA",'" type="button" ').concat(a(e.interaction.hex),'>\n <input :arr="options" class="pcr-type" data-type="RGBA" value="').concat(s?"RGB":"RGBA",'" type="button" ').concat(a(e.interaction.rgba),'>\n <input :arr="options" class="pcr-type" data-type="HSLA" value="').concat(s?"HSL":"HSLA",'" type="button" ').concat(a(e.interaction.hsla),'>\n <input :arr="options" class="pcr-type" data-type="HSVA" value="').concat(s?"HSV":"HSVA",'" type="button" ').concat(a(e.interaction.hsva),'>\n <input :arr="options" class="pcr-type" data-type="CMYK" value="CMYK" type="button" ').concat(a(e.interaction.cmyk),'>\n\n <input :ref="save" class="pcr-save" value="').concat(l("btn:save"),'" type="button" ').concat(a(e.interaction.save),' aria-label="').concat(l("aria:btn:save"),'">\n <input :ref="cancel" class="pcr-cancel" value="').concat(l("btn:cancel"),'" type="button" ').concat(a(e.interaction.cancel),' aria-label="').concat(l("aria:btn:cancel"),'">\n <input :ref="clear" class="pcr-clear" value="').concat(l("btn:clear"),'" type="button" ').concat(a(e.interaction.clear),' aria-label="').concat(l("aria:btn:clear"),'">\n </div>\n </div>\n </div>\n ')),u=p.interaction;return u.options.find(t=>!t.hidden&&!t.classList.add("active")),u.type=()=>u.options.find(t=>t.classList.contains("active")),p})(this),t.useAsButton&&(this._root.button=t.el),t.container.appendChild(this._root.root)}_finalBuild(){const t=this.options,e=this._root;if(t.container.removeChild(e.root),t.inline){const o=t.el.parentElement;t.el.nextSibling?o.insertBefore(e.app,t.el.nextSibling):o.appendChild(e.app)}else t.container.appendChild(e.app);t.useAsButton?t.inline&&t.el.remove():t.el.parentNode.replaceChild(e.root,t.el),t.disabled&&this.disable(),t.comparison||(e.button.style.transition="none",t.useAsButton||(e.preview.lastColor.style.transition="none")),this.hide()}_buildComponents(){const t=this,e=this.options.components,o=(t.options.sliders||"v").repeat(2),[n,i]=o.match(/^[vh]+$/g)?o:[],r=()=>this._color||(this._color=this._lastColor.clone()),s={palette:O({element:t._root.palette.picker,wrapper:t._root.palette.palette,onstop:()=>t._emit("changestop",t),onchange(o,n){if(!e.palette)return;const i=r(),{_root:s,options:a}=t,{lastColor:c,currentColor:l}=s.preview;t._recalc&&(i.s=100*o,i.v=100-100*n,i.v<0&&(i.v=0),t._updateOutput());const p=i.toRGBA().toString(0);this.element.style.background=p,this.wrapper.style.background="\n linear-gradient(to top, rgba(0, 0, 0, ".concat(i.a,"), transparent),\n linear-gradient(to left, hsla(").concat(i.h,", 100%, 50%, ").concat(i.a,"), rgba(255, 255, 255, ").concat(i.a,"))\n "),a.comparison?a.useAsButton||t._lastColor||(c.style.color=p):(s.button.style.color=p,s.button.classList.remove("clear"));const u=i.toHEXA().toString();for(const{el:e,color:o}of t._swatchColors)e.classList[u===o.toHEXA().toString()?"add":"remove"]("pcr-active");l.style.color=p}}),hue:O({lock:"v"===i?"h":"v",element:t._root.hue.picker,wrapper:t._root.hue.slider,onstop:()=>t._emit("changestop",t),onchange(o){if(!e.hue||!e.palette)return;const n=r();t._recalc&&(n.h=360*o),this.element.style.backgroundColor="hsl(".concat(n.h,", 100%, 50%)"),s.palette.trigger()}}),opacity:O({lock:"v"===n?"h":"v",element:t._root.opacity.picker,wrapper:t._root.opacity.slider,onstop:()=>t._emit("changestop",t),onchange(o){if(!e.opacity||!e.palette)return;const n=r();t._recalc&&(n.a=Math.round(100*o)/100),this.element.style.background="rgba(0, 0, 0, ".concat(n.a,")"),s.palette.trigger()}}),selectable:E({elements:t._root.interaction.options,className:"active",onchange(e){t._representation=e.target.getAttribute("data-type").toUpperCase(),t._recalc&&t._updateOutput()}})};this._components=s}_bindEvents(){const{_root:t,options:e}=this,o=[r(t.interaction.clear,"click",()=>this._clearColor()),r([t.interaction.cancel,t.preview.lastColor],"click",()=>{this._emit("cancel",this),this.setHSVA(...(this._lastColor||this._color).toHSVA(),!0)}),r(t.interaction.save,"click",()=>{!this.applyColor()&&!e.showAlways&&this.hide()}),r(t.interaction.result,["keyup","input"],t=>{this.setColor(t.target.value,!0)&&!this._initializingActive&&this._emit("change",this._color),t.stopImmediatePropagation()}),r(t.interaction.result,["focus","blur"],t=>{this._recalc="blur"===t.type,this._recalc&&this._updateOutput()}),r([t.palette.palette,t.palette.picker,t.hue.slider,t.hue.picker,t.opacity.slider,t.opacity.picker],["mousedown","touchstart"],()=>this._recalc=!0,{passive:!0})];if(!e.showAlways){const n=e.closeWithKey;o.push(r(t.button,"click",()=>this.isOpen()?this.hide():this.show()),r(document,"keyup",t=>this.isOpen()&&(t.key===n||t.code===n)&&this.hide()),r(document,["touchstart","mousedown"],e=>{this.isOpen()&&!l(e).some(e=>e===t.app||e===t.button)&&this.hide()},{capture:!0}))}if(e.adjustableNumbers){const e={rgba:[255,255,255,1],hsva:[360,100,100,1],hsla:[360,100,100,1],cmyk:[100,100,100,100]};u(t.interaction.result,(t,o,n)=>{const i=e[this.getColorRepresentation().toLowerCase()];if(i){const e=i[n],r=t+(e>=100?1e3*o:o);return r<=0?0:Number((r<e?r:e).toPrecision(3))}return t})}if(e.autoReposition&&!e.inline){let t=null;const n=this;o.push(r(window,["scroll","resize"],()=>{n.isOpen()&&(e.closeOnScroll&&n.hide(),null===t?(t=setTimeout(()=>t=null,100),requestAnimationFrame((function e(){null!==t&&requestAnimationFrame(e)}))):(clearTimeout(t),t=setTimeout(()=>t=null,100)))},{capture:!0}))}this._eventBindings=o}_rePositioningPicker(){const{options:t}=this;if(!t.inline){if(!this._nanopop.update({container:document.body.getBoundingClientRect(),position:t.position,forceApplyOnFailure:!this._recalc})){const t=this._root.app,e=t.getBoundingClientRect();t.style.top="".concat((window.innerHeight-e.height)/2,"px"),t.style.left="".concat((window.innerWidth-e.width)/2,"px")}}}_updateOutput(){const{_root:t,_color:e,options:o}=this;if(t.interaction.type()){const n="to".concat(t.interaction.type().getAttribute("data-type"));t.interaction.result.value="function"==typeof e[n]?e[n]().toString(o.outputPrecision):""}!this._initializingActive&&this._recalc&&this._emit("change",e)}_clearColor(t=!1){const{_root:e,options:o}=this;o.useAsButton||(e.button.style.color="rgba(0, 0, 0, 0.15)"),e.button.classList.add("clear"),o.showAlways||this.hide(),this._lastColor=null,this._initializingActive||t||(this._emit("save",null),this._emit("clear",this))}_parseLocalColor(t){const{values:e,type:o,a:n}=C(t),{lockOpacity:i}=this.options,r=void 0!==n&&1!==n;return e&&3===e.length&&(e[3]=void 0),{values:!e||i&&r?null:e,type:o}}_t(t){return this.options.i18n[t]||B.I18N_DEFAULTS[t]}_emit(t,...e){this._eventListener[t].forEach(t=>t(...e,this))}on(t,e){return this._eventListener[t].push(e),this}off(t,e){const o=this._eventListener[t]||[],n=o.indexOf(e);return~n&&o.splice(n,1),this}addSwatch(t){const{values:e}=this._parseLocalColor(t);if(e){const{_swatchColors:t,_root:o}=this,n=k(...e),i=a('<button type="button" style="color: '.concat(n.toRGBA().toString(0),'" aria-label="').concat(this._t("btn:swatch"),'"/>'));return o.swatches.appendChild(i),t.push({el:i,color:n}),this._eventBindings.push(r(i,"click",()=>{this.setHSVA(...n.toHSVA(),!0),this._emit("swatchselect",n),this._emit("change",n)})),!0}return!1}removeSwatch(t){const e=this._swatchColors[t];if(e){const{el:o}=e;return this._root.swatches.removeChild(o),this._swatchColors.splice(t,1),!0}return!1}applyColor(t=!1){const{preview:e,button:o}=this._root,n=this._color.toRGBA().toString(0);return e.lastColor.style.color=n,this.options.useAsButton||(o.style.color=n),o.classList.remove("clear"),this._lastColor=this._color.clone(),this._initializingActive||t||this._emit("save",this._color),this}destroy(){this._eventBindings.forEach(t=>s(...t)),Object.keys(this._components).forEach(t=>this._components[t].destroy())}destroyAndRemove(){this.destroy();const{root:t,app:e}=this._root;t.parentElement&&t.parentElement.removeChild(t),e.parentElement.removeChild(e),Object.keys(this).forEach(t=>this[t]=null)}hide(){return this._root.app.classList.remove("visible"),this._emit("hide",this),this}show(){return this.options.disabled||(this._root.app.classList.add("visible"),this._emit("show",this)),this}isOpen(){return this._root.app.classList.contains("visible")}setHSVA(t=360,e=0,o=0,n=1,i=!1){const r=this._recalc;if(this._recalc=!1,t<0||t>360||e<0||e>100||o<0||o>100||n<0||n>1)return!1;this._color=k(t,e,o,n);const{hue:s,opacity:a,palette:c}=this._components;return s.update(t/360),a.update(n),c.update(e/100,1-o/100),i||this.applyColor(),r&&this._updateOutput(),this._recalc=r,!0}setColor(t,e=!1){if(null===t)return this._clearColor(e),!0;const{values:o,type:n}=this._parseLocalColor(t);if(o){const t=n.toUpperCase(),{options:i}=this._root.interaction,r=i.find(e=>e.getAttribute("data-type")===t);if(r&&!r.hidden)for(const t of i)t.classList[t===r?"add":"remove"]("active");return!!this.setHSVA(...o,e)&&this.setColorRepresentation(t)}return!1}setColorRepresentation(t){return t=t.toUpperCase(),!!this._root.interaction.options.find(e=>e.getAttribute("data-type").startsWith(t)&&!e.click())}getColorRepresentation(){return this._representation}getColor(){return this._color}getSelectedColor(){return this._lastColor}getRoot(){return this._root}disable(){return this.hide(),this.options.disabled=!0,this._root.button.classList.add("disabled"),this}enable(){return this.options.disabled=!1,this._root.button.classList.remove("disabled"),this}}L(B,"utils",n),L(B,"version",h.a),L(B,"I18N_DEFAULTS",{"ui:dialog":"color picker dialog","btn:toggle":"toggle color picker dialog","btn:swatch":"color swatch","btn:last-color":"use previous color","btn:save":"Save","btn:cancel":"Cancel","btn:clear":"Clear","aria:btn:save":"save and close","aria:btn:cancel":"cancel and close","aria:btn:clear":"clear and close","aria:input":"color input field","aria:palette":"color selection area","aria:hue":"hue selection slider","aria:opacity":"selection slider"}),L(B,"DEFAULT_OPTIONS",{appClass:null,theme:"classic",useAsButton:!1,padding:8,disabled:!1,comparison:!0,closeOnScroll:!1,outputPrecision:0,lockOpacity:!1,autoReposition:!0,container:"body",components:{interaction:{}},i18n:{},swatches:null,inline:!1,sliders:null,default:"#42445a",defaultRepresentation:null,position:"bottom-middle",adjustableNumbers:!0,showAlways:!1,closeWithKey:"Escape"}),L(B,"create",t=>new B(t));e.default=B}]).default}));
|
5 |
+
//# sourceMappingURL=pickr.min.js.map
|
js/libraries/range-slider.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
!function(e,t){"use strict";function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=function(){function e(e,t){for(var s=0;s<t.length;s++){var i=t[s];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,s,i){return s&&e(t.prototype,s),i&&e(t,i),t}}();/*!
|
2 |
+
* Range-slider 1.0.0
|
3 |
+
* Customizable slider (range) component for JavaScript.
|
4 |
+
*
|
5 |
+
* Copyright: Alexey Grinko, 2017
|
6 |
+
* Git repository: https://github.com/agrinko/range-slider.git
|
7 |
+
*
|
8 |
+
* @license MIT - https://opensource.org/licenses/MIT
|
9 |
+
*/
|
10 |
+
!function(e){var t={value:0,min:0,max:100,step:1,unit:null,width:null,design:"3d",theme:"default",size:"medium",handle:"square",popup:"top",showMinMaxLabels:!0,showCurrentValueLabel:!1,labelsPosition:"top",onstart:function(){},onmove:function(){},onfinish:function(){}},n=function(){function e(i,n){s(this,e),i instanceof HTMLElement||(i=e._el(),n||(n=i)),this.el=i,this.s=a({},t,n),this._validateSettings(),this._buildDOM(),this._bindEvents(),this.initialValue=this.s.value,this.value=null,this.setValue(this.s.value)}return i(e,[{key:"getValue",value:function(){return this.value}},{key:"getElement",value:function(){return this.el}},{key:"labelValue",value:function(){return(arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.value)+" "+(this.s.unit||"")}},{key:"setValue",value:function(e){(e=this._normalize(e))<this.s.min||e>this.s.max||(null===this.value||e!=this.value&&this.s.onmove.call(this,e)!==!1)&&(this.value=e,this._updatePopup(),this._updateLabel(),this._moveToValue(e))}},{key:"setWidth",value:function(e){arguments.length&&("number"==typeof e&&(e+="px"),this.el.style.width=e)}},{key:"_validateSettings",value:function(){this.s.value=e.toNumber(this.s.value,t.value),this.s.min=e.toNumber(this.s.min,t.min),this.s.max=e.toNumber(this.s.max,t.max),this.s.step=e.toNumber(this.s.step,t.step)}},{key:"_buildDOM",value:function(){this._setClasses(),this._createBar(),this.setWidth(this.s.width),(this.s.showMinMaxLabels||this.s.showCurrentValueLabel)&&this._createLabels(),this.s.popup&&this._createPopup()}},{key:"_setClasses",value:function(){var e=this;["range-slider","rs-theme-"+this.s.theme,"rs-size-"+this.s.size,"rs-design-"+this.s.design,"rs-handle-"+this.s.handle,this.s.showMinMaxLabels||this.s.showCurrentValueLabel?"rs-labels-"+this.s.labelsPosition:null].forEach(function(t){t&&(e.el.className+=" "+t)})}},{key:"_createBar",value:function(){var t=e._el(),s=e._el(),i=e._el(),n=e._el();t.className="rs-bar",s.className="rs-progress",i.className="rs-wrap",n.className="rs-handle",t.appendChild(i),i.appendChild(s),i.appendChild(n),this.el.appendChild(t),this.bar=t,this.progressBar=s,this.range=i,this.handle=n}},{key:"_createLabels",value:function(){var t=e._el(),s=e._el(),i=e._el(),n=e._el(),a=e._el();t.className="rs-labels",s.className="rs-wrap",i.className="rs-label-left",n.className="rs-label-middle",a.className="rs-label-right",t.appendChild(i),t.appendChild(a),t.appendChild(s),s.appendChild(n),this.el.appendChild(t),this.labels={left:i,right:a,middle:n},this._updateLabels()}},{key:"_updateLabels",value:function(){this.s.showMinMaxLabels&&(this.labels.left.innerText=this.labelValue(this.s.min),this.labels.right.innerText=this.labelValue(this.s.max))}},{key:"_updateLabel",value:function(){this.s.showCurrentValueLabel&&(this.labels.middle.innerText=this.labelValue(this.value))}},{key:"_createPopup",value:function(){var t=e._el();t.className="rs-popup rs-hidden rs-popup-"+this.s.popup,this.handle.appendChild(t),this.popup=t}},{key:"_updatePopup",value:function(){this.s.popup&&(this.popup.innerText=this.labelValue(this.value))}},{key:"_togglePopup",value:function(e){this.s.popup&&(e?(this.popup.className=this.popup.className.replace("rs-hidden",""),this.s.showCurrentValueLabel&&(this.labels.middle.className+=" rs-hidden")):(this.popup.className+=" rs-hidden",this.s.showCurrentValueLabel&&(this.labels.middle.className=this.labels.middle.className.replace("rs-hidden",""))))}},{key:"_bindEvents",value:function(){var e=this;this.bar.addEventListener("mousedown",function(t){0==t.button&&(t.preventDefault(),e._begin(t.clientX,t.target))}),this.bar.addEventListener("touchstart",function(t){t.changedTouches&&t.changedTouches[0]&&(t.preventDefault(),e._begin(t.changedTouches[0].clientX,t.target))})}},{key:"_begin",value:function(e,t){this.s.onstart.call(this,this.value)!==!1&&(this.prevValue=this.value,this.el.className+=" rs-active",this._togglePopup(!0),t!=this.handle?this._move(e):this._ensureNoElementsIntersection(),this._initHandle(e))}},{key:"_initHandle",value:function(e){var t=this,s=this.handle.getBoundingClientRect(),i=e-(s.left+s.width/2),n=function(e){var s=e.changedTouches?e.changedTouches[0].clientX:e.clientX;t._move(s-i),e.preventDefault()},a=function e(){document.removeEventListener("mousemove",n),document.removeEventListener("touchmove",n),document.removeEventListener("mouseup",e),document.removeEventListener("touchend",e),document.removeEventListener("touchcancel",e),t._end()};document.addEventListener("mousemove",n),document.addEventListener("touchmove",n),document.addEventListener("mouseup",a),document.addEventListener("touchend",a),document.addEventListener("touchcancel",a)}},{key:"_end",value:function(){this.value!=this.prevValue&&this.s.onfinish.call(this,this.value),this.el.className=this.el.className.replace("rs-active",""),this._togglePopup(!1),this._ensureNoElementsIntersection()}},{key:"_move",value:function(e){var t=this._getRelX(e),s=this._toValue(t);this.setValue(s)}},{key:"_moveToValue",value:function(e){e=100*this._toFraction(e),this.progressBar.style.width=this.handle.style.left=e+"%",this._moveLabel(e)}},{key:"_moveLabel",value:function(e){this.s.showCurrentValueLabel&&(this.labels.middle.style.left=e+"%"),this._ensureNoElementsIntersection()}},{key:"_ensureNoElementsIntersection",value:function(){this.s.showMinMaxLabels&&(this.s.popup&&this.popup.className.indexOf("rs-hidden")==-1&&(e.ensureNoIntersection(this.popup,this.labels.left),e.ensureNoIntersection(this.popup,this.labels.right)),this.s.showCurrentValueLabel&&this.labels.middle.className.indexOf("rs-hidden")==-1&&(e.ensureNoIntersection(this.labels.middle,this.labels.left),e.ensureNoIntersection(this.labels.middle,this.labels.right)))}},{key:"_normalize",value:function(e){e=Math.round(Math.min(Math.max(e,this.s.min),this.s.max));var t=(e-this.initialValue)%this.s.step;return t>=this.s.step/2&&(e+=this.s.step),e-=t}},{key:"_getRelX",value:function(e){var t=this.range.getBoundingClientRect(),s=(e-t.left)/t.width;return Math.min(Math.max(s,0),1)}},{key:"_toValue",value:function(e){return this.s.min+(this.s.max-this.s.min)*e}},{key:"_toFraction",value:function(e){return(e-this.s.min)/(this.s.max-this.s.min)}}],[{key:"_el",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"DIV";return document.createElement(e)}},{key:"ensureNoIntersection",value:function(t,s){s.className=s.className.replace("rs-hidden",""),t.className.indexOf("rs-hidden")==-1&&e.intersects(t,s)&&(s.className+=" rs-hidden")}},{key:"toNumber",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e=+e,e||0===e||(e=t),e}},{key:"intersects",value:function(e,t){var s=e.getBoundingClientRect(),i=t.getBoundingClientRect();return(this._intersectsRectH(s,i)||this._intersectsRectH(i,s))&&(this._intersectsRectV(s,i)||this._intersectsRectV(i,s))}},{key:"_intersectsRectH",value:function(e,t){return e.left<=t.right&&(e.left>=t.left||e.right>=t.left)}},{key:"_intersectsRectV",value:function(e,t){return e.top<=t.bottom&&(e.top>=t.top||e.bottom>=t.top)}}]),e}(),a=Object.assign||function(e){for(var t=1;t<arguments.length;t++)for(var s in arguments[t])arguments[t].hasOwnProperty(s)&&(e[s]=arguments[t][s]);return e};"function"==typeof define&&define.amd?define(function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:e.RangeSlider=n}(window),t.true=e}({},function(){return this}());
|
js/libraries/sortable.min.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
var sortable=function(){"use strict";function c(e,t,n){if(void 0===n)return e&&e.h5s&&e.h5s.data&&e.h5s.data[t];e.h5s=e.h5s||{},e.h5s.data=e.h5s.data||{},e.h5s.data[t]=n}var v=function(e,t){if(!(e instanceof NodeList||e instanceof HTMLCollection||e instanceof Array))throw new Error("You must provide a nodeList/HTMLCollection/Array of elements to be filtered.");return"string"!=typeof t?Array.from(e):Array.from(e).filter(function(e){return 1===e.nodeType&&e.matches(t)})},y=new Map,t=function(){function e(){this._config=new Map,this._placeholder=void 0,this._data=new Map}return Object.defineProperty(e.prototype,"config",{get:function(){var n={};return this._config.forEach(function(e,t){n[t]=e}),n},set:function(e){if("object"!=typeof e)throw new Error("You must provide a valid configuration object to the config setter.");var t=Object.assign({},e);this._config=new Map(Object.entries(t))},enumerable:!1,configurable:!0}),e.prototype.setConfig=function(e,t){if(!this._config.has(e))throw new Error("Trying to set invalid configuration item: "+e);this._config.set(e,t)},e.prototype.getConfig=function(e){if(!this._config.has(e))throw new Error("Invalid configuration item requested: "+e);return this._config.get(e)},Object.defineProperty(e.prototype,"placeholder",{get:function(){return this._placeholder},set:function(e){if(!(e instanceof HTMLElement)&&null!==e)throw new Error("A placeholder must be an html element or null.");this._placeholder=e},enumerable:!1,configurable:!0}),e.prototype.setData=function(e,t){if("string"!=typeof e)throw new Error("The key must be a string.");this._data.set(e,t)},e.prototype.getData=function(e){if("string"!=typeof e)throw new Error("The key must be a string.");return this._data.get(e)},e.prototype.deleteData=function(e){if("string"!=typeof e)throw new Error("The key must be a string.");return this._data.delete(e)},e}(),E=function(e){if(!(e instanceof HTMLElement))throw new Error("Please provide a sortable to the store function.");return y.has(e)||y.set(e,new t),y.get(e)};function i(e,t,n){if(e instanceof Array)for(var r=0;r<e.length;++r)i(e[r],t,n);else e.addEventListener(t,n),E(e).setData("event"+t,n)}function a(e,t){if(e instanceof Array)for(var n=0;n<e.length;++n)a(e[n],t);else e.removeEventListener(t,E(e).getData("event"+t)),E(e).deleteData("event"+t)}function l(e,t,n){if(e instanceof Array)for(var r=0;r<e.length;++r)l(e[r],t,n);else e.setAttribute(t,n)}function r(e,t){if(e instanceof Array)for(var n=0;n<e.length;++n)r(e[n],t);else e.removeAttribute(t)}var w=function(e){if(!e.parentElement||0===e.getClientRects().length)throw new Error("target element must be part of the dom");var t=e.getClientRects()[0];return{left:t.left+window.pageXOffset,right:t.right+window.pageXOffset,top:t.top+window.pageYOffset,bottom:t.bottom+window.pageYOffset}},d=function(n,r){var o;return void 0===r&&(r=0),function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];clearTimeout(o),o=setTimeout(function(){n.apply(void 0,e)},r)}},b=function(e,t){if(!(e instanceof HTMLElement&&(t instanceof NodeList||t instanceof HTMLCollection||t instanceof Array)))throw new Error("You must provide an element and a list of elements.");return Array.from(t).indexOf(e)},f=function(e){if(!(e instanceof HTMLElement))throw new Error("Element is not a node element.");return null!==e.parentNode},n=function(e,t,n){if(!(e instanceof HTMLElement&&e.parentElement instanceof HTMLElement))throw new Error("target and element must be a node");e.parentElement.insertBefore(t,"before"===n?e:e.nextElementSibling)},T=function(e,t){return n(e,t,"before")},C=function(e,t){return n(e,t,"after")},o=function(t,n,e){if(void 0===n&&(n=function(e,t){return e}),void 0===e&&(e=function(e){return e}),!(t instanceof HTMLElement)||!0==!t.isSortable)throw new Error("You need to provide a sortableContainer to be serialized.");if("function"!=typeof n||"function"!=typeof e)throw new Error("You need to provide a valid serializer for items and the container.");var r=c(t,"opts").items,o=v(t.children,r),a=o.map(function(e){return{parent:t,node:e,html:e.outerHTML,index:b(e,o)}});return{container:e({node:t,itemCount:a.length}),items:a.map(function(e){return n(e,t)})}},u=function(e,t,n){var r;if(void 0===n&&(n="sortable-placeholder"),!(e instanceof HTMLElement))throw new Error("You must provide a valid element as a sortable.");if(!(t instanceof HTMLElement)&&void 0!==t)throw new Error("You must provide a valid element as a placeholder or set ot to undefined.");return void 0===t&&(["UL","OL"].includes(e.tagName)?t=document.createElement("li"):["TABLE","TBODY"].includes(e.tagName)?(t=document.createElement("tr")).innerHTML='<td colspan="100"></td>':t=document.createElement("div")),"string"==typeof n&&(r=t.classList).add.apply(r,n.split(" ")),t},L=function(e){if(!(e instanceof HTMLElement))throw new Error("You must provide a valid dom element");var n=window.getComputedStyle(e);return"border-box"===n.getPropertyValue("box-sizing")?parseInt(n.getPropertyValue("height"),10):["height","padding-top","padding-bottom"].map(function(e){var t=parseInt(n.getPropertyValue(e),10);return isNaN(t)?0:t}).reduce(function(e,t){return e+t})},x=function(e){if(!(e instanceof HTMLElement))throw new Error("You must provide a valid dom element");var n=window.getComputedStyle(e);return["width","padding-left","padding-right"].map(function(e){var t=parseInt(n.getPropertyValue(e),10);return isNaN(t)?0:t}).reduce(function(e,t){return e+t})},s=function(e,t){if(!(e instanceof Array))throw new Error("You must provide a Array of HTMLElements to be filtered.");return"string"!=typeof t?e:e.filter(function(e){return e.querySelector(t)instanceof HTMLElement||e.shadowRoot&&e.shadowRoot.querySelector(t)instanceof HTMLElement}).map(function(e){return e.querySelector(t)||e.shadowRoot&&e.shadowRoot.querySelector(t)})},p=function(e){return e.composedPath&&e.composedPath()[0]||e.target},m=function(e,t,n){return{element:e,posX:n.pageX-t.left,posY:n.pageY-t.top}},g=function(e,t,n){if(!(e instanceof Event))throw new Error("setDragImage requires a DragEvent as the first argument.");if(!(t instanceof HTMLElement))throw new Error("setDragImage requires the dragged element as the second argument.");if(n||(n=m),e.dataTransfer&&e.dataTransfer.setDragImage){var r=n(t,w(t),e);if(!(r.element instanceof HTMLElement)||"number"!=typeof r.posX||"number"!=typeof r.posY)throw new Error("The customDragImage function you provided must return and object with the properties element[string], posX[integer], posY[integer].");e.dataTransfer.effectAllowed="copyMove",e.dataTransfer.setData("text/plain",p(e).id),e.dataTransfer.setDragImage(r.element,r.posX,r.posY)}},M=function(e,t){if(!0===e.isSortable){var n=E(e).getConfig("acceptFrom");if(null!==n&&!1!==n&&"string"!=typeof n)throw new Error('HTML5Sortable: Wrong argument, "acceptFrom" must be "null", "false", or a valid selector string.');if(null!==n)return!1!==n&&0<n.split(",").filter(function(e){return 0<e.length&&t.matches(e)}).length;if(e===t)return!0;if(void 0!==E(e).getConfig("connectWith")&&null!==E(e).getConfig("connectWith"))return E(e).getConfig("connectWith")===E(t).getConfig("connectWith")}return!1},D={items:null,connectWith:null,disableIEFix:null,acceptFrom:null,copy:!1,placeholder:null,placeholderClass:"sortable-placeholder",draggingClass:"sortable-dragging",hoverClass:!1,dropTargetContainerClass:!1,debounce:0,throttleTime:100,maxItems:0,itemSerializer:void 0,containerSerializer:void 0,customDragImage:null,orientation:"vertical"};var H,I,A,S,_,Y,O,P,z,N=function(e,t){if("string"==typeof E(e).getConfig("hoverClass")){var o=E(e).getConfig("hoverClass").split(" ");!0===t?(i(e,"mousemove",function(r,o){var a=this;if(void 0===o&&(o=250),"function"!=typeof r)throw new Error("You must provide a function as the first argument for throttle.");if("number"!=typeof o)throw new Error("You must provide a number as the second argument for throttle.");var i=null;return function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];var n=Date.now();(null===i||o<=n-i)&&(i=n,r.apply(a,e))}}(function(r){0===r.buttons&&v(e.children,E(e).getConfig("items")).forEach(function(e){var t,n;e!==r.target?(t=e.classList).remove.apply(t,o):(n=e.classList).add.apply(n,o)})},E(e).getConfig("throttleTime"))),i(e,"mouseleave",function(){v(e.children,E(e).getConfig("items")).forEach(function(e){var t;(t=e.classList).remove.apply(t,o)})})):(a(e,"mousemove"),a(e,"mouseleave"))}},h=function(e){a(e,"dragstart"),a(e,"dragend"),a(e,"dragover"),a(e,"dragenter"),a(e,"drop"),a(e,"mouseenter"),a(e,"mouseleave")},W=function(e,t){e&&a(e,"dragleave"),t&&t!==e&&a(t,"dragleave")},j=function(e,t){var n=e;return!0===E(t).getConfig("copy")&&(l(n=e.cloneNode(!0),"aria-copied","true"),e.parentElement.appendChild(n),n.style.display="none",n.oldDisplay=e.style.display),n},F=function(e){var t;(t=e).h5s&&delete t.h5s.data,r(e,"aria-dropeffect")},q=function(e){r(e,"aria-grabbed"),r(e,"aria-copied"),r(e,"draggable"),r(e,"role")};function R(e,t){if(t.composedPath)return t.composedPath().find(function(e){return e.isSortable});for(;!0!==e.isSortable;)e=e.parentElement;return e}function X(e,t){var n=c(e,"opts"),r=v(e.children,n.items).filter(function(e){return e.contains(t)||e.shadowRoot&&e.shadowRoot.contains(t)});return 0<r.length?r[0]:t}var B=function(e){var t=c(e,"opts"),n=v(e.children,t.items),r=s(n,t.handle);(l(e,"aria-dropeffect","move"),c(e,"_disabled","false"),l(r,"draggable","true"),!1===t.disableIEFix)&&("function"==typeof(document||window.document).createElement("span").dragDrop&&i(r,"mousedown",function(){if(-1!==n.indexOf(this))this.dragDrop();else{for(var e=this.parentElement;-1===n.indexOf(e);)e=e.parentElement;e.dragDrop()}}))},k=function(e){var t=c(e,"opts"),n=v(e.children,t.items),r=s(n,t.handle);c(e,"_disabled","false"),h(n),W(),a(r,"mousedown"),a(e,"dragover"),a(e,"dragenter"),a(e,"drop")};function U(e,h){var a=String(h);return h=h||{},"string"==typeof e&&(e=document.querySelectorAll(e)),e instanceof HTMLElement&&(e=[e]),e=Array.prototype.slice.call(e),/serialize/.test(a)?e.map(function(e){var t=c(e,"opts");return o(e,t.itemSerializer,t.containerSerializer)}):(e.forEach(function(s){if(/enable|disable|destroy/.test(a))return U[a](s);["connectWith","disableIEFix"].forEach(function(e){Object.prototype.hasOwnProperty.call(h,e)&&null!==h[e]&&console.warn('HTML5Sortable: You are using the deprecated configuration "'+e+'". This will be removed in an upcoming version, make sure to migrate to the new options when updating.')}),h=Object.assign({},D,E(s).config,h),E(s).config=h,c(s,"opts",h),s.isSortable=!0,k(s);var e,t=v(s.children,h.items);if(null!==h.placeholder&&void 0!==h.placeholder){var n=document.createElement(s.tagName);h.placeholder instanceof HTMLElement?n.appendChild(h.placeholder):n.innerHTML=h.placeholder,e=n.children[0]}E(s).placeholder=u(s,e,h.placeholderClass),c(s,"items",h.items),h.acceptFrom?c(s,"acceptFrom",h.acceptFrom):h.connectWith&&c(s,"connectWith",h.connectWith),B(s),l(t,"role","option"),l(t,"aria-grabbed","false"),N(s,!0),i(s,"dragstart",function(e){var t=p(e);if(!0!==t.isSortable&&(e.stopImmediatePropagation(),(!h.handle||t.matches(h.handle))&&"false"!==t.getAttribute("draggable"))){var n=R(t,e),r=X(n,t);O=v(n.children,h.items),_=O.indexOf(r),Y=b(r,n.children),S=n,g(e,r,h.customDragImage),I=L(r),A=x(r),r.classList.add(h.draggingClass),l(H=j(r,n),"aria-grabbed","true"),n.dispatchEvent(new CustomEvent("sortstart",{detail:{origin:{elementIndex:Y,index:_,container:S},item:H,originalTarget:t}}))}}),i(s,"dragenter",function(e){var n=p(e),r=R(n,e);r&&r!==P&&(z=v(r.children,c(r,"items")).filter(function(e){return e!==E(s).placeholder}),h.dropTargetContainerClass&&r.classList.add(h.dropTargetContainerClass),r.dispatchEvent(new CustomEvent("sortenter",{detail:{origin:{elementIndex:Y,index:_,container:S},destination:{container:r,itemsBeforeUpdate:z},item:H,originalTarget:n}})),i(r,"dragleave",function(e){var t=e.relatedTarget||e.fromElement;e.currentTarget.contains(t)||(h.dropTargetContainerClass&&r.classList.remove(h.dropTargetContainerClass),r.dispatchEvent(new CustomEvent("sortleave",{detail:{origin:{elementIndex:Y,index:_,container:r},item:H,originalTarget:n}})))})),P=r}),i(s,"dragend",function(e){if(H){H.classList.remove(h.draggingClass),l(H,"aria-grabbed","false"),"true"===H.getAttribute("aria-copied")&&"true"!==c(H,"dropped")&&H.remove(),H.style.display=H.oldDisplay,delete H.oldDisplay;var t=Array.from(y.values()).map(function(e){return e.placeholder}).filter(function(e){return e instanceof HTMLElement}).filter(f)[0];t&&t.remove(),s.dispatchEvent(new CustomEvent("sortstop",{detail:{origin:{elementIndex:Y,index:_,container:S},item:H}})),A=I=H=P=null}}),i(s,"drop",function(e){if(M(s,H.parentElement)){e.preventDefault(),e.stopPropagation(),c(H,"dropped","true");var t=Array.from(y.values()).map(function(e){return e.placeholder}).filter(function(e){return e instanceof HTMLElement}).filter(f)[0];C(t,H),t.remove(),s.dispatchEvent(new CustomEvent("sortstop",{detail:{origin:{elementIndex:Y,index:_,container:S},item:H}}));var n=E(s).placeholder,r=v(S.children,h.items).filter(function(e){return e!==n}),o=!0===this.isSortable?this:this.parentElement,a=v(o.children,c(o,"items")).filter(function(e){return e!==n}),i=b(H,Array.from(H.parentElement.children).filter(function(e){return e!==n})),l=b(H,a);h.dropTargetContainerClass&&o.classList.remove(h.dropTargetContainerClass),Y===i&&S===o||s.dispatchEvent(new CustomEvent("sortupdate",{detail:{origin:{elementIndex:Y,index:_,container:S,itemsBeforeUpdate:O,items:r},destination:{index:l,elementIndex:i,container:o,itemsBeforeUpdate:z,items:a},item:H}}))}});var o=d(function(t,e,n,r){if(H)if(h.forcePlaceholderSize&&(E(t).placeholder.style.height=I+"px",E(t).placeholder.style.width=A+"px"),-1<Array.from(t.children).indexOf(e)){var o=L(e),a=x(e),i=b(E(t).placeholder,e.parentElement.children),l=b(e,e.parentElement.children);if(I<o||A<a){var s=o-I,c=a-A,d=w(e).top,f=w(e).left;if(i<l&&("vertical"===h.orientation&&r<d||"horizontal"===h.orientation&&n<f))return;if(l<i&&("vertical"===h.orientation&&d+o-s<r||"horizontal"===h.orientation&&f+a-c<n))return}void 0===H.oldDisplay&&(H.oldDisplay=H.style.display),"none"!==H.style.display&&(H.style.display="none");var u=!1;try{var p=w(e).top+e.offsetHeight/2,m=w(e).left+e.offsetWidth/2;u="vertical"===h.orientation&&p<=r||"horizontal"===h.orientation&&m<=n}catch(e){u=i<l}u?C(e,E(t).placeholder):T(e,E(t).placeholder),Array.from(y.values()).filter(function(e){return void 0!==e.placeholder}).forEach(function(e){e.placeholder!==E(t).placeholder&&e.placeholder.remove()})}else{var g=Array.from(y.values()).filter(function(e){return void 0!==e.placeholder}).map(function(e){return e.placeholder});-1!==g.indexOf(e)||t!==e||v(e.children,h.items).length||(g.forEach(function(e){return e.remove()}),e.appendChild(E(t).placeholder))}},h.debounce),r=function(e){var t=e.target,n=!0===t.isSortable?t:R(t,e);if(t=X(n,t),H&&M(n,H.parentElement)&&"true"!==c(n,"_disabled")){var r=c(n,"opts");parseInt(r.maxItems)&&v(n.children,c(n,"items")).length>=parseInt(r.maxItems)&&H.parentElement!==n||(e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect=!0===E(n).getConfig("copy")?"copy":"move",o(n,t,e.pageX,e.pageY))}};i(t.concat(s),"dragover",r),i(t.concat(s),"dragenter",r)}),e)}return U.destroy=function(e){var t,n,r,o;n=c(t=e,"opts")||{},r=v(t.children,n.items),o=s(r,n.handle),a(t,"dragover"),a(t,"dragenter"),a(t,"dragstart"),a(t,"dragend"),a(t,"drop"),F(t),a(o,"mousedown"),h(r),q(r),W(S,P),t.isSortable=!1},U.enable=function(e){B(e)},U.disable=function(e){var t,n,r,o;n=c(t=e,"opts"),r=v(t.children,n.items),o=s(r,n.handle),l(t,"aria-dropeffect","none"),c(t,"_disabled","true"),l(o,"draggable","false"),a(o,"mousedown")},U.__testing={_data:c,_removeItemEvents:h,_removeItemData:q,_removeSortableData:F,_removeContainerEvents:W},U}();
|
2 |
+
//# sourceMappingURL=html5sortable.min.js.map
|
js/lottie.js
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
async function newLottieAnimation(x, y, json) {
|
2 |
+
const newlottie = new fabric.Lottie(json, {
|
3 |
+
left: x,
|
4 |
+
top: y,
|
5 |
+
width: 500,
|
6 |
+
height: 500,
|
7 |
+
originX: 'center',
|
8 |
+
originY: 'center',
|
9 |
+
backgroundColor: 'rgba(255,255,255,0)',
|
10 |
+
cursorWidth: 1,
|
11 |
+
stroke: '#000',
|
12 |
+
strokeUniform: true,
|
13 |
+
paintFirst: 'stroke',
|
14 |
+
strokeWidth: 0,
|
15 |
+
cursorDuration: 1,
|
16 |
+
cursorDelay: 250,
|
17 |
+
duration: duration * 1000,
|
18 |
+
assetType: 'sprite',
|
19 |
+
id: 'Sprite' + layer_count,
|
20 |
+
objectCaching: false,
|
21 |
+
strokeDashArray: false,
|
22 |
+
inGroup: false,
|
23 |
+
shadow: {
|
24 |
+
color: '#000',
|
25 |
+
offsetX: 0,
|
26 |
+
offsetY: 0,
|
27 |
+
blur: 0,
|
28 |
+
opacity: 0,
|
29 |
+
},
|
30 |
+
});
|
31 |
+
canvas.add(newlottie);
|
32 |
+
canvas.requestRenderAll();
|
33 |
+
newlottie.duration = newlottie.getDuration() * 1000;
|
34 |
+
newlottie.goToSeconds(0);
|
35 |
+
canvas.renderAll();
|
36 |
+
newLayer(newlottie);
|
37 |
+
canvas.setActiveObject(newlottie);
|
38 |
+
canvas.bringToFront(newlottie);
|
39 |
+
}
|
js/recorder.js
ADDED
@@ -0,0 +1,362 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
const FPS = 30;
|
2 |
+
let frame = 0;
|
3 |
+
var chunks = [];
|
4 |
+
var stream;
|
5 |
+
var rec;
|
6 |
+
var track;
|
7 |
+
|
8 |
+
function timeout(ms) {
|
9 |
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
10 |
+
}
|
11 |
+
|
12 |
+
function initRecorder() {
|
13 |
+
stream = document.getElementById('canvasrecord').captureStream(0);
|
14 |
+
track = stream.getVideoTracks()[0];
|
15 |
+
|
16 |
+
if (!track.requestFrame) {
|
17 |
+
track.requestFrame = () => stream.requestFrame();
|
18 |
+
}
|
19 |
+
|
20 |
+
rec = new MediaRecorder(stream, {
|
21 |
+
bitsPerSecond: 3200000,
|
22 |
+
});
|
23 |
+
|
24 |
+
rec.ondataavailable = function (evt) {
|
25 |
+
console.log('chunky');
|
26 |
+
chunks.push(evt.data);
|
27 |
+
};
|
28 |
+
|
29 |
+
rec.start();
|
30 |
+
|
31 |
+
console.log('Recorder has been started');
|
32 |
+
|
33 |
+
rec.onstart = function () {
|
34 |
+
rec.pause();
|
35 |
+
console.log('start!');
|
36 |
+
};
|
37 |
+
}
|
38 |
+
|
39 |
+
async function recordFrame() {
|
40 |
+
console.log(frame);
|
41 |
+
|
42 |
+
waitForEvent(rec, 'pause');
|
43 |
+
|
44 |
+
//rec.onpause = async function(e) {
|
45 |
+
|
46 |
+
// wake up the recorder
|
47 |
+
rec.resume();
|
48 |
+
recordAnimate(false, (frame / FPS) * 1000);
|
49 |
+
//animate(false, (frame/FPS)*1000)
|
50 |
+
// force write the frame
|
51 |
+
track.requestFrame();
|
52 |
+
|
53 |
+
// wait until our frame-time elapsed
|
54 |
+
await timeout(1000 / FPS);
|
55 |
+
|
56 |
+
// sleep recorder
|
57 |
+
rec.pause();
|
58 |
+
//}
|
59 |
+
}
|
60 |
+
|
61 |
+
async function exportRecording() {
|
62 |
+
rec.stop();
|
63 |
+
stream.getTracks().forEach((track) => track.stop());
|
64 |
+
await waitForEvent(rec, 'stop');
|
65 |
+
return new Blob(chunks);
|
66 |
+
}
|
67 |
+
|
68 |
+
// Record canvas
|
69 |
+
async function record() {
|
70 |
+
updateRecordCanvas();
|
71 |
+
if ($('input[name=radio]:checked').val() == 'image') {
|
72 |
+
recording = true;
|
73 |
+
paused = true;
|
74 |
+
animate(false, currenttime);
|
75 |
+
const dataURL = canvasrecord.toDataURL({
|
76 |
+
format: 'png',
|
77 |
+
});
|
78 |
+
const link = document.createElement('a');
|
79 |
+
link.download = 'image.png';
|
80 |
+
link.href = dataURL;
|
81 |
+
document.body.appendChild(link);
|
82 |
+
link.click();
|
83 |
+
document.body.removeChild(link);
|
84 |
+
recording = false;
|
85 |
+
} else {
|
86 |
+
if (!recording) {
|
87 |
+
recording = true;
|
88 |
+
paused = true;
|
89 |
+
recordAnimate(false, (frame / FPS) * 1000);
|
90 |
+
recording = true;
|
91 |
+
$('#download-real').html('Rendering...');
|
92 |
+
$('#download-real').addClass('downloading');
|
93 |
+
var fps = 60;
|
94 |
+
var aCtx = new AudioContext();
|
95 |
+
function audioTimerLoop(callback, frequency) {
|
96 |
+
var freq = frequency / 1000;
|
97 |
+
var silence = aCtx.createGain();
|
98 |
+
silence.gain.value = 0;
|
99 |
+
silence.connect(aCtx.destination);
|
100 |
+
onOSCend();
|
101 |
+
var stopped = false;
|
102 |
+
function onOSCend() {
|
103 |
+
osc = aCtx.createOscillator();
|
104 |
+
osc.onended = onOSCend;
|
105 |
+
osc.connect(silence);
|
106 |
+
osc.start(0);
|
107 |
+
osc.stop(aCtx.currentTime + freq);
|
108 |
+
callback(aCtx.currentTime);
|
109 |
+
if (stopped) {
|
110 |
+
osc.onended = function () {
|
111 |
+
return;
|
112 |
+
};
|
113 |
+
}
|
114 |
+
}
|
115 |
+
return function () {
|
116 |
+
stopped = true;
|
117 |
+
};
|
118 |
+
}
|
119 |
+
var stopAnim = audioTimerLoop(renderAnim, 1000 / fps);
|
120 |
+
var stream = document
|
121 |
+
.getElementById('canvasrecord')
|
122 |
+
.captureStream(fps);
|
123 |
+
objects.forEach(function (object) {
|
124 |
+
if (
|
125 |
+
canvasrecord.getItemById(object.id).get('assetType') &&
|
126 |
+
canvasrecord.getItemById(object.id).get('assetType') ==
|
127 |
+
'video'
|
128 |
+
) {
|
129 |
+
var audio = $(
|
130 |
+
canvasrecord.getItemById(object.id).getElement()
|
131 |
+
)[0];
|
132 |
+
var audioContext = new AudioContext();
|
133 |
+
var audioSource =
|
134 |
+
audioContext.createMediaElementSource(audio);
|
135 |
+
var audioDestination =
|
136 |
+
audioContext.createMediaStreamDestination();
|
137 |
+
audioSource.connect(audioDestination);
|
138 |
+
stream.addTrack(
|
139 |
+
audioDestination.stream.getAudioTracks()[0]
|
140 |
+
);
|
141 |
+
}
|
142 |
+
});
|
143 |
+
if (background_audio != false) {
|
144 |
+
var audioContext = new AudioContext();
|
145 |
+
var audioSource =
|
146 |
+
audioContext.createMediaElementSource(background_audio);
|
147 |
+
var audioDestination =
|
148 |
+
audioContext.createMediaStreamDestination();
|
149 |
+
audioSource.connect(audioDestination);
|
150 |
+
stream.addTrack(audioDestination.stream.getAudioTracks()[0]);
|
151 |
+
background_audio.currentTime = 0;
|
152 |
+
background_audio.play();
|
153 |
+
}
|
154 |
+
let chunks = [];
|
155 |
+
var recorder = new MediaRecorder(stream, {
|
156 |
+
bitsPerSecond: 3200000,
|
157 |
+
});
|
158 |
+
recorder.ondataavailable = (e) => chunks.push(e.data);
|
159 |
+
recorder.onstop = (e) => {
|
160 |
+
stopAnim();
|
161 |
+
downloadRecording(chunks);
|
162 |
+
animate(false, 0);
|
163 |
+
$('#seekbar').offset({
|
164 |
+
left:
|
165 |
+
offset_left +
|
166 |
+
$('#inner-timeline').offset().left +
|
167 |
+
currenttime / timelinetime,
|
168 |
+
});
|
169 |
+
canvas.renderAll();
|
170 |
+
console.log('Finished rendering');
|
171 |
+
};
|
172 |
+
recorder.start();
|
173 |
+
|
174 |
+
setTimeout(function () {
|
175 |
+
recorder.stop();
|
176 |
+
}, duration);
|
177 |
+
|
178 |
+
async function renderAnim(time) {
|
179 |
+
await recordAnimate(time * 1000);
|
180 |
+
}
|
181 |
+
}
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
/*
|
186 |
+
|
187 |
+
initRecorder();
|
188 |
+
|
189 |
+
//await timeout(2000)
|
190 |
+
|
191 |
+
// draw one frame at a time
|
192 |
+
while (frame++ < FPS * (duration/1000)) {
|
193 |
+
await longDraw(); // do the long drawing
|
194 |
+
await recordFrame(); // record at constant FPS
|
195 |
+
}
|
196 |
+
// now all the frames have been drawn
|
197 |
+
const recorded = await exportRecording(); // we can get our final video file
|
198 |
+
const a = document.createElement('a');
|
199 |
+
a.style.display = 'none';
|
200 |
+
a.href = URL.createObjectURL(recorded);
|
201 |
+
a.download = "test.webm";
|
202 |
+
document.body.appendChild(a);
|
203 |
+
a.click();
|
204 |
+
recording = false;
|
205 |
+
currenttime = 0;
|
206 |
+
animate(false, 0);
|
207 |
+
$("#seekbar").offset({left:offset_left+$("#inner-timeline").offset().left+(currenttime/timelinetime)});
|
208 |
+
canvas.renderAll();
|
209 |
+
resizeCanvas();
|
210 |
+
if (background_audio != false) {
|
211 |
+
background_audio.pause();
|
212 |
+
background_audio = new Audio(background_audio.src)
|
213 |
+
}
|
214 |
+
$("#download-real").html("Download");
|
215 |
+
$("#download-real").removeClass("downloading");
|
216 |
+
updateRecordCanvas();
|
217 |
+
|
218 |
+
// Fake long drawing operations that make real-time recording impossible
|
219 |
+
function longDraw() {
|
220 |
+
recordAnimate((frame/FPS)*1000)
|
221 |
+
return wait(Math.random() * 300)
|
222 |
+
.then(recordAnimate((frame/FPS)*1000));
|
223 |
+
}*/
|
224 |
+
|
225 |
+
/*
|
226 |
+
paused = true;
|
227 |
+
recording = true;
|
228 |
+
$("#download-real").html("Rendering...");
|
229 |
+
$("#download-real").addClass("downloading");
|
230 |
+
var fps = 60;
|
231 |
+
var aCtx = new AudioContext();
|
232 |
+
function audioTimerLoop(callback, frequency) {
|
233 |
+
var freq = frequency / 1000;
|
234 |
+
var silence = aCtx.createGain();
|
235 |
+
silence.gain.value = 0;
|
236 |
+
silence.connect(aCtx.destination);
|
237 |
+
onOSCend();
|
238 |
+
var stopped = false;
|
239 |
+
function onOSCend() {
|
240 |
+
osc = aCtx.createOscillator();
|
241 |
+
osc.onended = onOSCend;
|
242 |
+
osc.connect(silence);
|
243 |
+
osc.start(0);
|
244 |
+
osc.stop(aCtx.currentTime + freq);
|
245 |
+
callback(aCtx.currentTime);
|
246 |
+
if (stopped) {
|
247 |
+
osc.onended = function() {
|
248 |
+
return;
|
249 |
+
};
|
250 |
+
}
|
251 |
+
};
|
252 |
+
return function() {
|
253 |
+
stopped = true;
|
254 |
+
};
|
255 |
+
}
|
256 |
+
var stopAnim = audioTimerLoop(renderAnim, 1000/(fps));
|
257 |
+
var stream = document.getElementById("canvasrecord").captureStream(fps);
|
258 |
+
objects.forEach(function(object){
|
259 |
+
if (canvasrecord.getItemById(object.id).get("assetType") && canvasrecord.getItemById(object.id).get("assetType") == "video") {
|
260 |
+
var audio = $(canvasrecord.getItemById(object.id).getElement())[0];
|
261 |
+
var audioContext = new AudioContext();
|
262 |
+
var audioSource = audioContext.createMediaElementSource(audio);
|
263 |
+
var audioDestination = audioContext.createMediaStreamDestination();
|
264 |
+
audioSource.connect(audioDestination);
|
265 |
+
stream.addTrack(audioDestination.stream.getAudioTracks()[0]);
|
266 |
+
}
|
267 |
+
})
|
268 |
+
if (background_audio != false) {
|
269 |
+
var audioContext = new AudioContext();
|
270 |
+
var audioSource = audioContext.createMediaElementSource(background_audio);
|
271 |
+
var audioDestination = audioContext.createMediaStreamDestination();
|
272 |
+
audioSource.connect(audioDestination);
|
273 |
+
stream.addTrack(audioDestination.stream.getAudioTracks()[0]);
|
274 |
+
background_audio.currentTime = 0;
|
275 |
+
background_audio.play();
|
276 |
+
}
|
277 |
+
let chunks = [];
|
278 |
+
var recorder = new MediaRecorder(stream, {
|
279 |
+
bitsPerSecond : 3200000,
|
280 |
+
});
|
281 |
+
recorder.ondataavailable = e => chunks.push(e.data);
|
282 |
+
recorder.onstop = e => {
|
283 |
+
stopAnim();
|
284 |
+
downloadRecording(chunks);
|
285 |
+
animate(false, 0);
|
286 |
+
$("#seekbar").offset({left:offset_left+$("#inner-timeline").offset().left+(currenttime/timelinetime)});
|
287 |
+
canvas.renderAll();
|
288 |
+
console.log("Finished rendering")
|
289 |
+
}
|
290 |
+
recorder.start();
|
291 |
+
|
292 |
+
setTimeout(function() {
|
293 |
+
recorder.stop();
|
294 |
+
}, duration)
|
295 |
+
|
296 |
+
async function renderAnim(time) {
|
297 |
+
await animate(false, time*1000);
|
298 |
+
}
|
299 |
+
|
300 |
+
*/
|
301 |
+
|
302 |
+
/*
|
303 |
+
$("#download-real").html("Rendering...");
|
304 |
+
$("#download-real").addClass("downloading");
|
305 |
+
|
306 |
+
// browser check
|
307 |
+
if (typeof MediaStreamTrackGenerator === undefined || typeof MediaStream === undefined || typeof VideoFrame === undefined) {
|
308 |
+
console.log('Your browser does not support the web APIs used in this demo');
|
309 |
+
return;
|
310 |
+
}
|
311 |
+
|
312 |
+
// recording setup
|
313 |
+
const fps = 60;
|
314 |
+
const generator = new MediaStreamTrackGenerator({ kind: "video" });
|
315 |
+
const writer = generator.writable.getWriter();
|
316 |
+
const stream = new MediaStream();
|
317 |
+
stream.addTrack(generator);
|
318 |
+
const recorder = new MediaRecorder(stream, { mimeType: "video/webm" });
|
319 |
+
recorder.start();
|
320 |
+
|
321 |
+
function timeout(ms) {
|
322 |
+
return new Promise(resolve => setTimeout(resolve, ms));
|
323 |
+
}
|
324 |
+
|
325 |
+
// animate stuff
|
326 |
+
console.log('rendering...')
|
327 |
+
console.log(duration);
|
328 |
+
for (let i = 0; i < (duration/1000)*fps; i++) {
|
329 |
+
animate(false, (i/fps)*1000);
|
330 |
+
const frame = new VideoFrame(document.getElementById("canvasrecord"), {
|
331 |
+
timestamp: (i / fps)*1000
|
332 |
+
});
|
333 |
+
await writer.write(frame);
|
334 |
+
await timeout(100)
|
335 |
+
console.log("frame "+(i/fps)*1000);
|
336 |
+
}
|
337 |
+
console.log('rendering done');
|
338 |
+
|
339 |
+
// stop recording and
|
340 |
+
recorder.addEventListener("dataavailable", (evt) => {
|
341 |
+
const a = document.createElement('a');
|
342 |
+
a.style.display = 'none';
|
343 |
+
a.href = URL.createObjectURL(evt.data);
|
344 |
+
a.download = "test.webm";
|
345 |
+
document.body.appendChild(a);
|
346 |
+
a.click();
|
347 |
+
recording = false;
|
348 |
+
currenttime = 0;
|
349 |
+
animate(false, 0);
|
350 |
+
$("#seekbar").offset({left:offset_left+$("#inner-timeline").offset().left+(currenttime/timelinetime)});
|
351 |
+
canvas.renderAll();
|
352 |
+
resizeCanvas();
|
353 |
+
if (background_audio != false) {
|
354 |
+
background_audio.pause();
|
355 |
+
background_audio = new Audio(background_audio.src)
|
356 |
+
}
|
357 |
+
$("#download-real").html("Download");
|
358 |
+
$("#download-real").removeClass("downloading");
|
359 |
+
updateRecordCanvas();
|
360 |
+
});
|
361 |
+
recorder.stop();
|
362 |
+
*/
|
js/text.js
ADDED
@@ -0,0 +1,269 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function animateText(group, ms, play, props, cv, id) {
|
2 |
+
var starttime = p_keyframes.find((x) => x.id == id).start;
|
3 |
+
ms -= starttime;
|
4 |
+
var length = group._objects.length;
|
5 |
+
var globaldelay = 0;
|
6 |
+
for (var i = 0; i < length; i++) {
|
7 |
+
var index = i;
|
8 |
+
if (props.order == 'backward') {
|
9 |
+
index = length - i - 1;
|
10 |
+
}
|
11 |
+
let left = group.item(index).defaultLeft;
|
12 |
+
let top = group.item(index).defaultTop;
|
13 |
+
let scaleX = group.item(index).defaultScaleX;
|
14 |
+
let scaleY = group.item(index).defaultScaleY;
|
15 |
+
var delay = i * duration;
|
16 |
+
var duration = props.duration / length;
|
17 |
+
var animation = {
|
18 |
+
opacity: 0,
|
19 |
+
top: top,
|
20 |
+
left: left,
|
21 |
+
scaleX: scaleX,
|
22 |
+
scaleY: scaleY,
|
23 |
+
};
|
24 |
+
if (props.typeAnim == 'letter') {
|
25 |
+
delay = i * duration - 100;
|
26 |
+
} else if (props.typeAnim == 'word') {
|
27 |
+
if (group.item(index).text == ' ') {
|
28 |
+
globaldelay += 500;
|
29 |
+
}
|
30 |
+
delay = globaldelay;
|
31 |
+
}
|
32 |
+
if (props.preset == 'typewriter') {
|
33 |
+
delay = i * duration;
|
34 |
+
duration = 20;
|
35 |
+
} else if (props.preset == 'fade in') {
|
36 |
+
} else if (props.preset == 'slide top') {
|
37 |
+
animation.top += 20;
|
38 |
+
} else if (props.preset == 'slide bottom') {
|
39 |
+
animation.top -= 20;
|
40 |
+
} else if (props.preset == 'slide left') {
|
41 |
+
animation.left += 20;
|
42 |
+
} else if (props.preset == 'slide right') {
|
43 |
+
animation.left -= 20;
|
44 |
+
} else if (props.preset == 'scale') {
|
45 |
+
animation.scaleX = 0;
|
46 |
+
animation.scaleY = 0;
|
47 |
+
} else if (props.preset == 'shrink') {
|
48 |
+
animation.scaleX = 1.5;
|
49 |
+
animation.scaleY = 1.5;
|
50 |
+
}
|
51 |
+
if (delay < 0) {
|
52 |
+
delay = 0;
|
53 |
+
}
|
54 |
+
if (duration < 20) {
|
55 |
+
duration = 20;
|
56 |
+
}
|
57 |
+
var start = false;
|
58 |
+
var instance = anime({
|
59 |
+
targets: animation,
|
60 |
+
delay: delay,
|
61 |
+
opacity: 1,
|
62 |
+
left: left,
|
63 |
+
top: top,
|
64 |
+
scaleX: scaleX,
|
65 |
+
scaleY: scaleY,
|
66 |
+
duration: duration,
|
67 |
+
easing: props.easing,
|
68 |
+
autoplay: play,
|
69 |
+
update: function () {
|
70 |
+
if (start && play) {
|
71 |
+
group.item(index).set({
|
72 |
+
opacity: animation.opacity,
|
73 |
+
left: animation.left,
|
74 |
+
top: animation.top,
|
75 |
+
scaleX: animation.scaleX,
|
76 |
+
scaleY: animation.scaleY,
|
77 |
+
});
|
78 |
+
cv.renderAll();
|
79 |
+
}
|
80 |
+
},
|
81 |
+
changeBegin: function () {
|
82 |
+
start = true;
|
83 |
+
},
|
84 |
+
});
|
85 |
+
instance.seek(ms);
|
86 |
+
if (!play) {
|
87 |
+
group.item(index).set({
|
88 |
+
opacity: animation.opacity,
|
89 |
+
left: animation.left,
|
90 |
+
top: animation.top,
|
91 |
+
scaleX: animation.scaleX,
|
92 |
+
scaleY: animation.scaleY,
|
93 |
+
});
|
94 |
+
cv.renderAll();
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
function setText(group, props, cv) {
|
100 |
+
var length = group._objects.length;
|
101 |
+
for (var i = 0; i < length; i++) {
|
102 |
+
group.item(i).set({
|
103 |
+
fill: props.fill,
|
104 |
+
fontFamily: props.fontFamily,
|
105 |
+
});
|
106 |
+
cv.renderAll();
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
function renderText(string, props, x, y, cv, id, isnew, start) {
|
111 |
+
var textOffset = 0;
|
112 |
+
var group = [];
|
113 |
+
function renderLetter(letter) {
|
114 |
+
var text = new fabric.Text(letter, {
|
115 |
+
left: textOffset,
|
116 |
+
top: 0,
|
117 |
+
fill: props.fill,
|
118 |
+
fontFamily: props.fontFamily,
|
119 |
+
opacity: 1,
|
120 |
+
});
|
121 |
+
text.set({
|
122 |
+
defaultLeft: text.left,
|
123 |
+
defaultTop: text.top,
|
124 |
+
defaultScaleX: 1,
|
125 |
+
defaultScaleY: 1,
|
126 |
+
});
|
127 |
+
textOffset += text.get('width');
|
128 |
+
return text;
|
129 |
+
}
|
130 |
+
for (var i = 0; i < string.length; i++) {
|
131 |
+
group.push(renderLetter(string.charAt(i)));
|
132 |
+
}
|
133 |
+
var result = new fabric.Group(group, {
|
134 |
+
cursorWidth: 1,
|
135 |
+
stroke: '#000',
|
136 |
+
strokeUniform: true,
|
137 |
+
paintFirst: 'stroke',
|
138 |
+
strokeWidth: 0,
|
139 |
+
originX: 'center',
|
140 |
+
originY: 'center',
|
141 |
+
left: x - artboard.left,
|
142 |
+
top: y - artboard.top,
|
143 |
+
cursorDuration: 1,
|
144 |
+
cursorDelay: 250,
|
145 |
+
assetType: 'animatedText',
|
146 |
+
id: id,
|
147 |
+
strokeDashArray: false,
|
148 |
+
inGroup: false,
|
149 |
+
});
|
150 |
+
if (isnew) {
|
151 |
+
result.set({
|
152 |
+
notnew: true,
|
153 |
+
starttime: start,
|
154 |
+
});
|
155 |
+
}
|
156 |
+
result.objectCaching = false;
|
157 |
+
cv.add(result);
|
158 |
+
cv.renderAll();
|
159 |
+
newLayer(result);
|
160 |
+
result._objects.forEach(function (object, index) {
|
161 |
+
result.item(index).set({
|
162 |
+
defaultLeft: result.item(index).defaultLeft - result.width / 2,
|
163 |
+
defaultTop: result.item(index).defaultTop - result.height / 2,
|
164 |
+
});
|
165 |
+
});
|
166 |
+
cv.setActiveObject(result);
|
167 |
+
cv.bringToFront(result);
|
168 |
+
return result.id;
|
169 |
+
}
|
170 |
+
|
171 |
+
class AnimatedText {
|
172 |
+
constructor(text, props) {
|
173 |
+
this.text = text;
|
174 |
+
this.props = props;
|
175 |
+
this.id = 'Text' + layer_count;
|
176 |
+
}
|
177 |
+
render(cv) {
|
178 |
+
this.id = renderText(
|
179 |
+
this.text,
|
180 |
+
this.props,
|
181 |
+
this.props.left,
|
182 |
+
this.props.top,
|
183 |
+
cv,
|
184 |
+
this.id,
|
185 |
+
false,
|
186 |
+
0
|
187 |
+
);
|
188 |
+
animateText(
|
189 |
+
cv.getItemById(this.id),
|
190 |
+
currenttime,
|
191 |
+
false,
|
192 |
+
this.props,
|
193 |
+
cv,
|
194 |
+
this.id
|
195 |
+
);
|
196 |
+
}
|
197 |
+
seek(ms, cv) {
|
198 |
+
animateText(
|
199 |
+
cv.getItemById(this.id),
|
200 |
+
ms,
|
201 |
+
false,
|
202 |
+
this.props,
|
203 |
+
cv,
|
204 |
+
this.id
|
205 |
+
);
|
206 |
+
}
|
207 |
+
play(cv) {
|
208 |
+
animateText(
|
209 |
+
cv.getItemById(this.id),
|
210 |
+
0,
|
211 |
+
true,
|
212 |
+
this.props,
|
213 |
+
cv,
|
214 |
+
this.id
|
215 |
+
);
|
216 |
+
}
|
217 |
+
getObject(cv) {
|
218 |
+
return cv.getItemById(this.id);
|
219 |
+
}
|
220 |
+
setProps(newprops, cv) {
|
221 |
+
this.props = $.extend(this.props, newprops);
|
222 |
+
setText(cv.getItemById(this.id), this.props, cv);
|
223 |
+
}
|
224 |
+
setProp(newprop) {
|
225 |
+
$.extend(this.props, newprop);
|
226 |
+
}
|
227 |
+
reset(text, newprops, cv) {
|
228 |
+
var obj = cv.getItemById(this.id);
|
229 |
+
var left = obj.left;
|
230 |
+
var top = obj.top;
|
231 |
+
var scaleX = obj,
|
232 |
+
scaleX;
|
233 |
+
var scaleY = obj.scaleY;
|
234 |
+
var angle = obj.angle;
|
235 |
+
var start = p_keyframes.find((x) => x.id == this.id).start;
|
236 |
+
deleteObject(obj, false);
|
237 |
+
this.text = text;
|
238 |
+
this.props = newprops;
|
239 |
+
this.inst = renderText(
|
240 |
+
text,
|
241 |
+
this.props,
|
242 |
+
left,
|
243 |
+
top,
|
244 |
+
cv,
|
245 |
+
this.id,
|
246 |
+
true,
|
247 |
+
start
|
248 |
+
);
|
249 |
+
cv.getItemById(this.id).set({
|
250 |
+
angle: angle,
|
251 |
+
scaleX: scaleX,
|
252 |
+
scaleY: scaleY,
|
253 |
+
});
|
254 |
+
cv.renderAll();
|
255 |
+
animateText(
|
256 |
+
cv.getItemById(this.id),
|
257 |
+
currenttime,
|
258 |
+
false,
|
259 |
+
this.props,
|
260 |
+
cv,
|
261 |
+
this.id
|
262 |
+
);
|
263 |
+
animate(currenttime, false);
|
264 |
+
save();
|
265 |
+
}
|
266 |
+
assignTo(id, text, props) {
|
267 |
+
this.id = id;
|
268 |
+
}
|
269 |
+
}
|
js/ui.js
ADDED
@@ -0,0 +1,2369 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Update panel (when selecting / de-selecting objects)
|
2 |
+
function updatePanel(selection) {
|
3 |
+
if (!selection) {
|
4 |
+
$('#align').addClass('align-off');
|
5 |
+
$('#object-specific').html(canvas_panel);
|
6 |
+
$('#preset').append("<option value='custom'>Custom</option>");
|
7 |
+
presets.forEach(function (preset) {
|
8 |
+
$('#preset').append(
|
9 |
+
"<option value='" +
|
10 |
+
preset.id +
|
11 |
+
"'>" +
|
12 |
+
preset.name +
|
13 |
+
'</option>'
|
14 |
+
);
|
15 |
+
});
|
16 |
+
$('#preset').val(activepreset);
|
17 |
+
$('#canvas-duration input').val(duration / 1000);
|
18 |
+
$('#preset').niceSelect();
|
19 |
+
updatePanelValues();
|
20 |
+
colormode = 'back';
|
21 |
+
o_fill.setColor(canvas.backgroundColor);
|
22 |
+
} else if (
|
23 |
+
selection &&
|
24 |
+
canvas.getActiveObjects().length == 1 &&
|
25 |
+
canvas.getActiveObject().get('assetType') == 'audio'
|
26 |
+
) {
|
27 |
+
$('#object-specific').html(audio_panel);
|
28 |
+
$('#object-volume input').val(
|
29 |
+
canvas.getActiveObject().get('volume') * 200
|
30 |
+
);
|
31 |
+
} else if (
|
32 |
+
selection &&
|
33 |
+
canvas.getActiveObjects().length == 1 &&
|
34 |
+
canvas.getActiveObject().get('type') != 'group'
|
35 |
+
) {
|
36 |
+
if (!cropping) {
|
37 |
+
updateChromaUI();
|
38 |
+
checkFilter();
|
39 |
+
}
|
40 |
+
$('#align').removeClass('align-off');
|
41 |
+
$('#object-specific').html(object_panel);
|
42 |
+
if (
|
43 |
+
canvas.getActiveObject().get('type') == 'image' &&
|
44 |
+
!canvas.getActiveObject().get('assetType')
|
45 |
+
) {
|
46 |
+
$('#object-specific').append(image_panel);
|
47 |
+
$('#object-specific').append(image_more_panel);
|
48 |
+
} else if (
|
49 |
+
canvas.getActiveObject().get('id').indexOf('Video') >= 0
|
50 |
+
) {
|
51 |
+
$('#object-specific').append(image_panel);
|
52 |
+
$('#object-specific').append(video_more_panel);
|
53 |
+
} else {
|
54 |
+
$('#object-specific').append(back_panel);
|
55 |
+
}
|
56 |
+
objects.forEach(function (object) {
|
57 |
+
if (object.id != canvas.getActiveObject().get('id')) {
|
58 |
+
$('#masks').append(
|
59 |
+
"<option value='" +
|
60 |
+
object.id +
|
61 |
+
"'>" +
|
62 |
+
object.id +
|
63 |
+
'</option>'
|
64 |
+
);
|
65 |
+
}
|
66 |
+
});
|
67 |
+
$('#masks').niceSelect();
|
68 |
+
var selectme = document.getElementById('select-opacity');
|
69 |
+
o_slider = new RangeSlider(selectme, {
|
70 |
+
design: '2d',
|
71 |
+
theme: 'default',
|
72 |
+
handle: 'round',
|
73 |
+
popup: null,
|
74 |
+
showMinMaxLabels: false,
|
75 |
+
unit: '%',
|
76 |
+
min: 0,
|
77 |
+
max: 100,
|
78 |
+
value: 100,
|
79 |
+
onmove: function (x) {
|
80 |
+
document
|
81 |
+
.getElementById('object-o')
|
82 |
+
.getElementsByTagName('input')[0].value = x;
|
83 |
+
canvas.getActiveObject().set({
|
84 |
+
opacity: x / 100,
|
85 |
+
});
|
86 |
+
canvas.renderAll();
|
87 |
+
},
|
88 |
+
onfinish: function (x) {
|
89 |
+
document
|
90 |
+
.getElementById('object-o')
|
91 |
+
.getElementsByTagName('input')[0].value = x;
|
92 |
+
updateObjectValues('opacity');
|
93 |
+
},
|
94 |
+
onstart: function (x) {
|
95 |
+
document
|
96 |
+
.getElementById('object-o')
|
97 |
+
.getElementsByTagName('input')[0].value = x;
|
98 |
+
},
|
99 |
+
});
|
100 |
+
if (canvas.getActiveObject().get('type') == 'rect') {
|
101 |
+
$('#object-specific').append(shape_panel);
|
102 |
+
} else if (
|
103 |
+
canvas.getActiveObject().get('type') == 'path' ||
|
104 |
+
canvas.getActiveObject().get('type') == 'circle'
|
105 |
+
) {
|
106 |
+
$('#object-specific').append(path_panel);
|
107 |
+
} else if (canvas.getActiveObject().get('type') == 'textbox') {
|
108 |
+
$('#object-specific').append(text_panel);
|
109 |
+
selectme = document.getElementById('select-letter');
|
110 |
+
o_letter_slider = new RangeSlider(selectme, {
|
111 |
+
design: '2d',
|
112 |
+
theme: 'default',
|
113 |
+
handle: 'round',
|
114 |
+
popup: null,
|
115 |
+
showMinMaxLabels: false,
|
116 |
+
unit: '%',
|
117 |
+
min: -200,
|
118 |
+
max: 200,
|
119 |
+
value: parseFloat(
|
120 |
+
(canvas.getActiveObject().get('charSpacing') / 10).toFixed(
|
121 |
+
2
|
122 |
+
)
|
123 |
+
),
|
124 |
+
onmove: function (x) {
|
125 |
+
document
|
126 |
+
.getElementById('text-h')
|
127 |
+
.getElementsByTagName('input')[0].value = x;
|
128 |
+
canvas.getActiveObject().set({ charSpacing: x * 10 });
|
129 |
+
canvas.renderAll();
|
130 |
+
updatePanelValues();
|
131 |
+
},
|
132 |
+
onfinish: function (x) {
|
133 |
+
document
|
134 |
+
.getElementById('text-h')
|
135 |
+
.getElementsByTagName('input')[0].value = x;
|
136 |
+
updateObjectValues('opacity3');
|
137 |
+
},
|
138 |
+
onstart: function (x) {
|
139 |
+
document
|
140 |
+
.getElementById('text-h')
|
141 |
+
.getElementsByTagName('input')[0].value = x;
|
142 |
+
},
|
143 |
+
});
|
144 |
+
selectme = document.getElementById('select-line');
|
145 |
+
o_line_slider = new RangeSlider(selectme, {
|
146 |
+
design: '2d',
|
147 |
+
theme: 'default',
|
148 |
+
handle: 'round',
|
149 |
+
popup: null,
|
150 |
+
showMinMaxLabels: false,
|
151 |
+
unit: '%',
|
152 |
+
min: 1,
|
153 |
+
max: 500,
|
154 |
+
value: parseFloat(
|
155 |
+
(canvas.getActiveObject().get('lineHeight') * 100).toFixed(
|
156 |
+
2
|
157 |
+
)
|
158 |
+
),
|
159 |
+
onmove: function (x) {
|
160 |
+
document
|
161 |
+
.getElementById('text-v')
|
162 |
+
.getElementsByTagName('input')[0].value = x;
|
163 |
+
canvas
|
164 |
+
.getActiveObject()
|
165 |
+
.set({ lineHeight: parseFloat(x / 100) });
|
166 |
+
canvas.renderAll();
|
167 |
+
},
|
168 |
+
onfinish: function (x) {
|
169 |
+
document
|
170 |
+
.getElementById('text-v')
|
171 |
+
.getElementsByTagName('input')[0].value = x;
|
172 |
+
updateObjectValues('opacity3');
|
173 |
+
},
|
174 |
+
onstart: function (x) {
|
175 |
+
document
|
176 |
+
.getElementById('text-v')
|
177 |
+
.getElementsByTagName('input')[0].value = x;
|
178 |
+
},
|
179 |
+
});
|
180 |
+
updateTextValues();
|
181 |
+
}
|
182 |
+
$('#object-specific').append(stroke_panel);
|
183 |
+
$('#object-specific').append(shadow_panel);
|
184 |
+
$('#line-cap').niceSelect();
|
185 |
+
updatePanelValues();
|
186 |
+
} else if (
|
187 |
+
canvas.getActiveObjects().length > 1 ||
|
188 |
+
canvas.getActiveObject().get('type') == 'group'
|
189 |
+
) {
|
190 |
+
$('#align').removeClass('align-off');
|
191 |
+
$('#object-specific').html(object_panel);
|
192 |
+
if (canvas.getActiveObject().get('type') == 'group') {
|
193 |
+
if (
|
194 |
+
canvas.getActiveObject().get('assetType') == 'animatedText'
|
195 |
+
) {
|
196 |
+
$('#object-specific').append(other_panel);
|
197 |
+
$('#object-specific').append(animated_text_panel);
|
198 |
+
$('#object-specific').append(start_animation_panel);
|
199 |
+
fonts.forEach(function (font) {
|
200 |
+
$('#font-picker').append(
|
201 |
+
"<option value='" + font + "'>" + font + '</option>'
|
202 |
+
);
|
203 |
+
});
|
204 |
+
$('#font-picker').val(
|
205 |
+
animatedtext.find(
|
206 |
+
(x) => x.id == canvas.getActiveObject().id
|
207 |
+
).props.fontFamily
|
208 |
+
);
|
209 |
+
$('#font-picker').niceSelect();
|
210 |
+
$('#text-color input').val(
|
211 |
+
convertToHex(
|
212 |
+
animatedtext.find(
|
213 |
+
(x) => x.id == canvas.getActiveObject().id
|
214 |
+
).props.fill
|
215 |
+
)
|
216 |
+
);
|
217 |
+
$('#color-text-side').css(
|
218 |
+
'background-color',
|
219 |
+
animatedtext.find(
|
220 |
+
(x) => x.id == canvas.getActiveObject().id
|
221 |
+
).props.fill
|
222 |
+
);
|
223 |
+
text_animation_list.forEach(function (preset) {
|
224 |
+
$('#preset-picker').append(
|
225 |
+
"<option value='" +
|
226 |
+
preset.name +
|
227 |
+
"'>" +
|
228 |
+
preset.label +
|
229 |
+
'</option>'
|
230 |
+
);
|
231 |
+
});
|
232 |
+
$('#preset-picker').val(
|
233 |
+
animatedtext.find(
|
234 |
+
(x) => x.id == canvas.getActiveObject().id
|
235 |
+
).props.preset
|
236 |
+
);
|
237 |
+
$('#preset-picker').niceSelect();
|
238 |
+
$('.order-toggle-item-active').removeClass(
|
239 |
+
'order-toggle-item-active'
|
240 |
+
);
|
241 |
+
$('.order-toggle-item-active-2').removeClass(
|
242 |
+
'order-toggle-item-active-2'
|
243 |
+
);
|
244 |
+
if (
|
245 |
+
animatedtext.find(
|
246 |
+
(x) => x.id == canvas.getActiveObject().id
|
247 |
+
).props.order == 'backward'
|
248 |
+
) {
|
249 |
+
$('#order-backward').addClass('order-toggle-item-active');
|
250 |
+
} else {
|
251 |
+
$('#order-forward').addClass('order-toggle-item-active');
|
252 |
+
}
|
253 |
+
if (
|
254 |
+
animatedtext.find(
|
255 |
+
(x) => x.id == canvas.getActiveObject().id
|
256 |
+
).props.typeAnim == 'letter'
|
257 |
+
) {
|
258 |
+
$('#type-letters').addClass('order-toggle-item-active-2');
|
259 |
+
} else {
|
260 |
+
$('#type-words').addClass('order-toggle-item-active-2');
|
261 |
+
}
|
262 |
+
$('#easing-picker').val(
|
263 |
+
animatedtext.find(
|
264 |
+
(x) => x.id == canvas.getActiveObject().id
|
265 |
+
).props.easing
|
266 |
+
);
|
267 |
+
$('#easing-picker').niceSelect();
|
268 |
+
$('#durationinput').val(
|
269 |
+
animatedtext.find(
|
270 |
+
(x) => x.id == canvas.getActiveObject().id
|
271 |
+
).props.duration / 1000
|
272 |
+
);
|
273 |
+
$('#masks').niceSelect();
|
274 |
+
}
|
275 |
+
/*
|
276 |
+
if (canvas.getActiveObject().isGroup) {
|
277 |
+
$("#object-specific").append(group_panel);
|
278 |
+
} else {
|
279 |
+
$("#object-specific").append(other_panel);
|
280 |
+
}
|
281 |
+
objects.forEach(function(object){
|
282 |
+
if (object.id != canvas.getActiveObject().get("id")) {
|
283 |
+
$("#masks").append("<option value='"+object.id+"'>"+object.id+"</option>");
|
284 |
+
}
|
285 |
+
});
|
286 |
+
$("#masks").niceSelect();
|
287 |
+
*/
|
288 |
+
} else {
|
289 |
+
$('#object-specific').append(selection_panel);
|
290 |
+
}
|
291 |
+
var selectme = document.getElementById('select-opacity');
|
292 |
+
o_slider = new RangeSlider(selectme, {
|
293 |
+
design: '2d',
|
294 |
+
theme: 'default',
|
295 |
+
handle: 'round',
|
296 |
+
popup: null,
|
297 |
+
showMinMaxLabels: false,
|
298 |
+
unit: '%',
|
299 |
+
min: 0,
|
300 |
+
max: 100,
|
301 |
+
value: 100,
|
302 |
+
onmove: function (x) {
|
303 |
+
document
|
304 |
+
.getElementById('object-o')
|
305 |
+
.getElementsByTagName('input')[0].value = x;
|
306 |
+
canvas.getActiveObject().set({ opacity: x / 100 });
|
307 |
+
canvas.renderAll();
|
308 |
+
},
|
309 |
+
onfinish: function (x) {
|
310 |
+
document
|
311 |
+
.getElementById('object-o')
|
312 |
+
.getElementsByTagName('input')[0].value = x;
|
313 |
+
updateObjectValues('opacity');
|
314 |
+
},
|
315 |
+
onstart: function (x) {
|
316 |
+
document
|
317 |
+
.getElementById('object-o')
|
318 |
+
.getElementsByTagName('input')[0].value = x;
|
319 |
+
},
|
320 |
+
});
|
321 |
+
updatePanelValues();
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
function convertToHex(nonHexColorString) {
|
326 |
+
var ctx = document.createElement('canvas').getContext('2d');
|
327 |
+
ctx.fillStyle = nonHexColorString;
|
328 |
+
return ctx.fillStyle.toUpperCase();
|
329 |
+
}
|
330 |
+
|
331 |
+
function updateStrokeValues() {
|
332 |
+
const object = canvas.getActiveObject();
|
333 |
+
$('.line-join-active').removeClass('line-join-active');
|
334 |
+
if (
|
335 |
+
object.get('strokeDashArray') == false &&
|
336 |
+
object.get('strokeWidth') == 0
|
337 |
+
) {
|
338 |
+
$('#miter').addClass('line-join-active');
|
339 |
+
$('#miter img').attr('src', 'assets/miter-active.svg');
|
340 |
+
} else if (object.get('strokeDashArray') == false) {
|
341 |
+
$('#bevel').addClass('line-join-active');
|
342 |
+
$('#bevel img').attr('src', 'assets/bevel-active.svg');
|
343 |
+
} else if (object.get('strokeDashArray') == [10, 5]) {
|
344 |
+
$('#round').addClass('line-join-active');
|
345 |
+
$('#round img').attr('src', 'assets/round-active.svg');
|
346 |
+
} else {
|
347 |
+
$('#small-dash').addClass('line-join-active');
|
348 |
+
$('#small-dash img').attr('src', 'assets/dash2-active.svg');
|
349 |
+
}
|
350 |
+
}
|
351 |
+
|
352 |
+
function toggleAnimationOrder() {
|
353 |
+
var object = canvas.getActiveObject();
|
354 |
+
$('.order-toggle-item-active').removeClass(
|
355 |
+
'order-toggle-item-active'
|
356 |
+
);
|
357 |
+
if ($(this).attr('id') == 'order-backward') {
|
358 |
+
animatedtext
|
359 |
+
.find((x) => x.id == object.id)
|
360 |
+
.setProp({ order: 'backward' }, canvas);
|
361 |
+
} else if ($(this).attr('id') == 'order-forward') {
|
362 |
+
animatedtext
|
363 |
+
.find((x) => x.id == object.id)
|
364 |
+
.setProp({ order: 'forward' }, canvas);
|
365 |
+
}
|
366 |
+
$(this).addClass('order-toggle-item-active');
|
367 |
+
animate(currenttime, false);
|
368 |
+
save();
|
369 |
+
}
|
370 |
+
function toggleAnimationType() {
|
371 |
+
var object = canvas.getActiveObject();
|
372 |
+
$('.order-toggle-item-active-2').removeClass(
|
373 |
+
'order-toggle-item-active-2'
|
374 |
+
);
|
375 |
+
if ($(this).attr('id') == 'type-words') {
|
376 |
+
animatedtext
|
377 |
+
.find((x) => x.id == object.id)
|
378 |
+
.setProp({ typeAnim: 'word' }, canvas);
|
379 |
+
} else if ($(this).attr('id') == 'type-letters') {
|
380 |
+
animatedtext
|
381 |
+
.find((x) => x.id == object.id)
|
382 |
+
.setProp({ typeAnim: 'letter' }, canvas);
|
383 |
+
}
|
384 |
+
$(this).addClass('order-toggle-item-active-2');
|
385 |
+
animate(currenttime, false);
|
386 |
+
save();
|
387 |
+
}
|
388 |
+
$(document).on(
|
389 |
+
'click',
|
390 |
+
'.order-toggle-item:not(.order-toggle-item-active)',
|
391 |
+
toggleAnimationOrder
|
392 |
+
);
|
393 |
+
$(document).on(
|
394 |
+
'click',
|
395 |
+
'.order-toggle-item-2:not(.order-toggle-item-active-2)',
|
396 |
+
toggleAnimationType
|
397 |
+
);
|
398 |
+
|
399 |
+
function updateTextValues() {
|
400 |
+
const object = canvas.getActiveObject();
|
401 |
+
fonts.forEach(function (font) {
|
402 |
+
$('#font-picker').append(
|
403 |
+
"<option value='" + font + "'>" + font + '</option>'
|
404 |
+
);
|
405 |
+
});
|
406 |
+
$('#font-picker').val(object.get('fontFamily'));
|
407 |
+
$('#font-picker').niceSelect();
|
408 |
+
$('#text-h input').val(
|
409 |
+
parseFloat((object.get('charSpacing') / 10).toFixed(2))
|
410 |
+
);
|
411 |
+
$('#text-v input').val(
|
412 |
+
parseFloat((object.get('lineHeight') * 100).toFixed(2))
|
413 |
+
);
|
414 |
+
if (object.get('textAlign') == 'left') {
|
415 |
+
$('#align-text-left').addClass('align-text-active');
|
416 |
+
$('#align-text-left img').attr(
|
417 |
+
'src',
|
418 |
+
'assets/align-text-left-active.svg'
|
419 |
+
);
|
420 |
+
} else if (object.get('textAlign') == 'center') {
|
421 |
+
$('#align-text-center').addClass('align-text-active');
|
422 |
+
$('#align-text-center img').attr(
|
423 |
+
'src',
|
424 |
+
'assets/align-text-center-active.svg'
|
425 |
+
);
|
426 |
+
} else if (object.get('textAlign') == 'right') {
|
427 |
+
$('#align-text-right').addClass('align-text-right-active');
|
428 |
+
$('#align-text-right img').attr(
|
429 |
+
'src',
|
430 |
+
'assets/align-text-right-active.svg'
|
431 |
+
);
|
432 |
+
} else {
|
433 |
+
$('#align-text-justify').addClass('align-text-justify-active');
|
434 |
+
$('#align-text-justify img').attr(
|
435 |
+
'src',
|
436 |
+
'assets/align-text-justify-active.svg'
|
437 |
+
);
|
438 |
+
}
|
439 |
+
if (
|
440 |
+
object.get('fontWeight') == 'bold' ||
|
441 |
+
object.get('fontWeight') == 700
|
442 |
+
) {
|
443 |
+
$('#format-bold').addClass('format-text-active');
|
444 |
+
$('#format-bold img').attr('src', 'assets/bold-active.svg');
|
445 |
+
}
|
446 |
+
if (object.get('fontStyle') == 'italic') {
|
447 |
+
$('#format-italic').addClass('format-text-active');
|
448 |
+
$('#format-italic img').attr('src', 'assets/italic-active.svg');
|
449 |
+
}
|
450 |
+
if (object.get('underline') == true) {
|
451 |
+
$('#format-underline').addClass('format-text-active');
|
452 |
+
$('#format-underline img').attr(
|
453 |
+
'src',
|
454 |
+
'assets/underline-active.svg'
|
455 |
+
);
|
456 |
+
}
|
457 |
+
if (object.get('linethrough') == true) {
|
458 |
+
$('#format-strike').addClass('format-text-active');
|
459 |
+
$('#format-strike img').attr('src', 'assets/strike-active.svg');
|
460 |
+
}
|
461 |
+
}
|
462 |
+
|
463 |
+
// Update panel inputs based on object values
|
464 |
+
function updatePanelValues() {
|
465 |
+
if (canvas.getActiveObject()) {
|
466 |
+
if (canvas.getActiveObject().get('assetType') == 'audio') {
|
467 |
+
$('#object-volume input').val(
|
468 |
+
canvas.getActiveObject().get('volume') * 200
|
469 |
+
);
|
470 |
+
return false;
|
471 |
+
}
|
472 |
+
setting = true;
|
473 |
+
var tempstore = false;
|
474 |
+
var object = canvas.getActiveObject();
|
475 |
+
if (
|
476 |
+
canvas.getActiveObjects.length > 1 ||
|
477 |
+
object.get('type') == 'activeSelection'
|
478 |
+
) {
|
479 |
+
object = object.toGroup();
|
480 |
+
object.set({
|
481 |
+
shadow: {
|
482 |
+
blur: 0,
|
483 |
+
color: 'black',
|
484 |
+
offsetX: 0,
|
485 |
+
offsetY: 0,
|
486 |
+
opacity: 0,
|
487 |
+
},
|
488 |
+
});
|
489 |
+
tempstore = true;
|
490 |
+
}
|
491 |
+
if (object.get('assetType') == 'animatedText') {
|
492 |
+
$('#animated-text input').val(
|
493 |
+
animatedtext.find((x) => x.id == object.id).text
|
494 |
+
);
|
495 |
+
}
|
496 |
+
if (objects.find((x) => x.id == object.get('id'))) {
|
497 |
+
if (
|
498 |
+
$(
|
499 |
+
"#masks option[value='" +
|
500 |
+
objects.find((x) => x.id == object.get('id')).mask +
|
501 |
+
"']"
|
502 |
+
).length == 0
|
503 |
+
) {
|
504 |
+
$('#masks').val('none');
|
505 |
+
objects.find((x) => x.id == object.get('id')).mask = 'none';
|
506 |
+
object.clipPath = null;
|
507 |
+
canvas.renderAll();
|
508 |
+
} else {
|
509 |
+
$('#masks').val(
|
510 |
+
objects.find((x) => x.id == object.get('id')).mask
|
511 |
+
);
|
512 |
+
}
|
513 |
+
$('#masks').niceSelect('update');
|
514 |
+
}
|
515 |
+
updateStrokeValues();
|
516 |
+
$('#object-x input').val(
|
517 |
+
parseFloat(
|
518 |
+
(
|
519 |
+
object.get('left') -
|
520 |
+
artboard.get('left') -
|
521 |
+
(object.get('width') * object.get('scaleX')) / 2
|
522 |
+
).toFixed(2)
|
523 |
+
)
|
524 |
+
);
|
525 |
+
$('#object-y input').val(
|
526 |
+
parseFloat(
|
527 |
+
(
|
528 |
+
object.get('top') -
|
529 |
+
artboard.get('top') -
|
530 |
+
(object.get('height') * object.get('scaleY')) / 2
|
531 |
+
).toFixed(2)
|
532 |
+
)
|
533 |
+
);
|
534 |
+
$('#object-w input').val(
|
535 |
+
parseFloat(
|
536 |
+
(object.get('width') * object.get('scaleX')).toFixed(2)
|
537 |
+
)
|
538 |
+
);
|
539 |
+
$('#object-h input').val(
|
540 |
+
parseFloat(
|
541 |
+
(object.get('height') * object.get('scaleY')).toFixed(2)
|
542 |
+
)
|
543 |
+
);
|
544 |
+
$('#object-r input').val(
|
545 |
+
parseFloat(object.get('angle').toFixed(2))
|
546 |
+
);
|
547 |
+
$('#object-stroke input').val(
|
548 |
+
parseFloat(object.get('strokeWidth').toFixed(2))
|
549 |
+
);
|
550 |
+
if (object.get('type') != 'group') {
|
551 |
+
$('#object-shadow-x input').val(
|
552 |
+
parseFloat(object.shadow.offsetX.toFixed(2))
|
553 |
+
);
|
554 |
+
$('#object-shadow-y input').val(
|
555 |
+
parseFloat(object.shadow.offsetY.toFixed(2))
|
556 |
+
);
|
557 |
+
$('#object-blur input').val(
|
558 |
+
parseFloat(object.shadow.blur.toFixed(2))
|
559 |
+
);
|
560 |
+
colormode = 'stroke';
|
561 |
+
o_fill.setColor(object.get('stroke'));
|
562 |
+
colormode = 'shadow';
|
563 |
+
o_fill.setColor(object.shadow.color);
|
564 |
+
}
|
565 |
+
o_slider.setValue(object.get('opacity') * 100);
|
566 |
+
if (object.get('type') == 'rect') {
|
567 |
+
$('#object-corners input').val(
|
568 |
+
parseFloat(object.get('rx').toFixed(2))
|
569 |
+
);
|
570 |
+
colormode = 'fill';
|
571 |
+
o_fill.setColor(object.get('fill'));
|
572 |
+
} else if (
|
573 |
+
object.get('type') == 'path' ||
|
574 |
+
object.get('type') == 'circle' ||
|
575 |
+
object.get('type') == 'textbox'
|
576 |
+
) {
|
577 |
+
colormode = 'fill';
|
578 |
+
o_fill.setColor(object.get('fill'));
|
579 |
+
}
|
580 |
+
if (tempstore) {
|
581 |
+
object.toActiveSelection();
|
582 |
+
canvas.renderAll();
|
583 |
+
}
|
584 |
+
setting = false;
|
585 |
+
} else {
|
586 |
+
$('#canvas-w input').val(artboard.get('width'));
|
587 |
+
$('#canvas-h input').val(artboard.get('height'));
|
588 |
+
}
|
589 |
+
}
|
590 |
+
|
591 |
+
// Update opacity input
|
592 |
+
function updateInputs(id) {
|
593 |
+
if (canvas.getActiveObject().get('assetType') == 'audio') {
|
594 |
+
return false;
|
595 |
+
}
|
596 |
+
if ($('#object-o input').val() > 100) {
|
597 |
+
$('#object-o input').val(100);
|
598 |
+
} else if ($('#object-o input').val() < 0) {
|
599 |
+
$('#object-o input').val(0);
|
600 |
+
}
|
601 |
+
o_slider.setValue($('#object-o input').val());
|
602 |
+
if (
|
603 |
+
!isNaN(parseFloat($('#object-color-fill-opacity input').val())) &&
|
604 |
+
id == 'object-color-fill-opacity'
|
605 |
+
) {
|
606 |
+
if ($('#object-color-fill-opacity input').val() > 100) {
|
607 |
+
$('#object-color-fill-opacity').val(100);
|
608 |
+
} else if ($('#object-color-fill-opacity input').val() < 0) {
|
609 |
+
$('#object-color-fill-opacity input').val(0);
|
610 |
+
}
|
611 |
+
colormode = 'fill';
|
612 |
+
o_fill.setColor(
|
613 |
+
'rgba(' +
|
614 |
+
o_fill.getColor().toRGBA()[0] +
|
615 |
+
',' +
|
616 |
+
o_fill.getColor().toRGBA()[1] +
|
617 |
+
',' +
|
618 |
+
o_fill.getColor().toRGBA()[2] +
|
619 |
+
',' +
|
620 |
+
$('#object-color-fill-opacity input').val() / 100 +
|
621 |
+
')'
|
622 |
+
);
|
623 |
+
}
|
624 |
+
if (
|
625 |
+
!isNaN(
|
626 |
+
parseFloat($('#object-color-stroke-opacity input').val())
|
627 |
+
) &&
|
628 |
+
id == 'object-color-stroke-opacity'
|
629 |
+
) {
|
630 |
+
if ($('#object-color-stroke-opacity input').val() > 100) {
|
631 |
+
$('#object-color-stroke-opacity').val(100);
|
632 |
+
} else if ($('#object-color-stroke-opacity input').val() < 0) {
|
633 |
+
$('#object-color-stroke-opacity input').val(0);
|
634 |
+
}
|
635 |
+
colormode = 'stroke';
|
636 |
+
o_fill.setColor(
|
637 |
+
'rgba(' +
|
638 |
+
o_fill.getColor().toRGBA()[0] +
|
639 |
+
',' +
|
640 |
+
o_fill.getColor().toRGBA()[1] +
|
641 |
+
',' +
|
642 |
+
o_fill.getColor().toRGBA()[2] +
|
643 |
+
',' +
|
644 |
+
$('#object-color-stroke-opacity input').val() / 100 +
|
645 |
+
')'
|
646 |
+
);
|
647 |
+
}
|
648 |
+
if (
|
649 |
+
!isNaN(
|
650 |
+
parseFloat($('#object-color-shadow-opacity input').val())
|
651 |
+
) &&
|
652 |
+
id == 'object-color-shadow-opacity'
|
653 |
+
) {
|
654 |
+
if ($('#object-color-shadow-opacity input').val() > 100) {
|
655 |
+
$('#object-color-shadow-opacity').val(100);
|
656 |
+
} else if ($('#object-color-shadow-opacity input').val() < 0) {
|
657 |
+
$('#object-color-shadow-opacity input').val(0);
|
658 |
+
}
|
659 |
+
colormode = 'shadow';
|
660 |
+
o_fill.setColor(
|
661 |
+
'rgba(' +
|
662 |
+
o_fill.getColor().toRGBA()[0] +
|
663 |
+
',' +
|
664 |
+
o_fill.getColor().toRGBA()[1] +
|
665 |
+
',' +
|
666 |
+
o_fill.getColor().toRGBA()[2] +
|
667 |
+
',' +
|
668 |
+
$('#object-color-shadow-opacity input').val() / 100 +
|
669 |
+
')'
|
670 |
+
);
|
671 |
+
}
|
672 |
+
}
|
673 |
+
|
674 |
+
// Update object position based on panel input values
|
675 |
+
function updateObjectValues(type) {
|
676 |
+
autoSave();
|
677 |
+
if (canvas.getActiveObjects().length > 0) {
|
678 |
+
if ($(this).find('input').val() || type) {
|
679 |
+
var object = canvas.getActiveObject();
|
680 |
+
if ($(this).attr('id') == 'animated-text') {
|
681 |
+
return false;
|
682 |
+
}
|
683 |
+
if ($(this).attr('id') == 'animated-text-duration') {
|
684 |
+
var obj = p_keyframes.find((x) => x.id == object.id);
|
685 |
+
var length = obj.end - obj.start;
|
686 |
+
if ($(this).find('input').val() * 1000 > length) {
|
687 |
+
$(this)
|
688 |
+
.find('input')
|
689 |
+
.val(length / 1000);
|
690 |
+
}
|
691 |
+
animatedtext
|
692 |
+
.find((x) => x.id == object.id)
|
693 |
+
.setProp(
|
694 |
+
{ duration: $(this).find('input').val() * 1000 },
|
695 |
+
canvas
|
696 |
+
);
|
697 |
+
save();
|
698 |
+
return false;
|
699 |
+
}
|
700 |
+
if ($(this).attr('id') == 'object-volume') {
|
701 |
+
newKeyframe(
|
702 |
+
'volume',
|
703 |
+
canvas.getActiveObject(),
|
704 |
+
currenttime,
|
705 |
+
parseFloat($(this).find('input').val()) / 200,
|
706 |
+
true
|
707 |
+
);
|
708 |
+
canvas
|
709 |
+
.getActiveObject()
|
710 |
+
.set(
|
711 |
+
'volume',
|
712 |
+
parseFloat($(this).find('input').val()) / 200
|
713 |
+
);
|
714 |
+
}
|
715 |
+
editingpanel = true;
|
716 |
+
var selection = false;
|
717 |
+
const tempselection = canvas.getActiveObjects();
|
718 |
+
const id = $(this).attr('id');
|
719 |
+
updateInputs(id);
|
720 |
+
if (tempselection.length > 1) {
|
721 |
+
object = object.toGroup();
|
722 |
+
selection = true;
|
723 |
+
}
|
724 |
+
if (objects.find((x) => x.id == object.get('id'))) {
|
725 |
+
objects.find((x) => x.id == object.get('id')).mask =
|
726 |
+
$('#masks').val();
|
727 |
+
if ($('#masks').val() == 'none') {
|
728 |
+
object.clipPath = null;
|
729 |
+
canvas.renderAll();
|
730 |
+
} else {
|
731 |
+
object.clipPath = canvas.getItemById($('#masks').val());
|
732 |
+
canvas.renderAll();
|
733 |
+
}
|
734 |
+
}
|
735 |
+
object.set({
|
736 |
+
left:
|
737 |
+
parseFloat($('#object-x input').val()) +
|
738 |
+
artboard.get('left') +
|
739 |
+
(object.get('width') * object.get('scaleX')) / 2,
|
740 |
+
top:
|
741 |
+
parseFloat($('#object-y input').val()) +
|
742 |
+
artboard.get('top') +
|
743 |
+
(object.get('height') * object.get('scaleY')) / 2,
|
744 |
+
scaleX: parseFloat(
|
745 |
+
$('#object-w input').val() / object.get('width')
|
746 |
+
),
|
747 |
+
scaleY: parseFloat(
|
748 |
+
$('#object-h input').val() / object.get('height')
|
749 |
+
),
|
750 |
+
angle: parseFloat($('#object-r input').val()),
|
751 |
+
opacity: parseFloat($('#object-o input').val() / 100),
|
752 |
+
strokeWidth: parseFloat($('#object-stroke input').val()),
|
753 |
+
});
|
754 |
+
if (object.get('type') != 'group') {
|
755 |
+
object.set({
|
756 |
+
shadow: {
|
757 |
+
color: object.shadow.color,
|
758 |
+
offsetX: parseFloat($('#object-shadow-x input').val()),
|
759 |
+
offsetY: parseFloat($('#object-shadow-y input').val()),
|
760 |
+
opacity: 1,
|
761 |
+
blur: parseFloat($('#object-blur input').val()),
|
762 |
+
},
|
763 |
+
});
|
764 |
+
}
|
765 |
+
canvas.renderAll();
|
766 |
+
if (tempselection.length > 1) {
|
767 |
+
object.toActiveSelection();
|
768 |
+
object = canvas.getActiveObject();
|
769 |
+
}
|
770 |
+
canvas.discardActiveObject();
|
771 |
+
tempselection.forEach(function (obj) {
|
772 |
+
keyframeChanges(obj, type, id, selection);
|
773 |
+
});
|
774 |
+
if (object) {
|
775 |
+
reselect(object);
|
776 |
+
editingpanel = false;
|
777 |
+
}
|
778 |
+
$('#' + id + ' input').focus();
|
779 |
+
save();
|
780 |
+
if (type) {
|
781 |
+
updatePanelValues();
|
782 |
+
} else if ($(this).find('input').val().length > 0) {
|
783 |
+
updatePanelValues();
|
784 |
+
}
|
785 |
+
}
|
786 |
+
} else {
|
787 |
+
if (
|
788 |
+
$(this).attr('id') == 'canvas-w' ||
|
789 |
+
$(this).attr('id') == 'canvas-h'
|
790 |
+
) {
|
791 |
+
artboard.set({
|
792 |
+
width: parseFloat($('#canvas-w input').val()),
|
793 |
+
height: parseFloat($('#canvas-h input').val()),
|
794 |
+
});
|
795 |
+
canvas.renderAll();
|
796 |
+
resizeCanvas();
|
797 |
+
if (activepreset != 'custom') {
|
798 |
+
if (
|
799 |
+
presets.find((x) => x.id == activepreset).width !=
|
800 |
+
$('#canvas-w input').val() ||
|
801 |
+
presets.find((x) => x.id == activepreset).height !=
|
802 |
+
$('#canvas-h input').val()
|
803 |
+
) {
|
804 |
+
activepreset = 'custom';
|
805 |
+
updatePanel();
|
806 |
+
}
|
807 |
+
}
|
808 |
+
} else if ($(this).attr('id') == 'canvas-duration') {
|
809 |
+
if (!isNaN(parseFloat($(this).find('input').val()))) {
|
810 |
+
setDuration(parseFloat($(this).find('input').val()) * 1000);
|
811 |
+
}
|
812 |
+
}
|
813 |
+
if (!isNaN(parseFloat($('#canvas-color-opacity input').val()))) {
|
814 |
+
if ($('#canvas-color-opacity input').val() > 100) {
|
815 |
+
$('#canvas-color-opacity input').val(100);
|
816 |
+
} else if ($('#canvas-color-opacity input').val() < 0) {
|
817 |
+
$('#canvas-color-opacity input').val(0);
|
818 |
+
}
|
819 |
+
colormode = 'back';
|
820 |
+
o_fill.setColor(
|
821 |
+
'rgba(' +
|
822 |
+
o_fill.getColor().toRGBA()[0] +
|
823 |
+
',' +
|
824 |
+
o_fill.getColor().toRGBA()[1] +
|
825 |
+
',' +
|
826 |
+
o_fill.getColor().toRGBA()[2] +
|
827 |
+
',' +
|
828 |
+
$('#canvas-color-opacity input').val() / 100 +
|
829 |
+
')'
|
830 |
+
);
|
831 |
+
}
|
832 |
+
}
|
833 |
+
}
|
834 |
+
function setTextAnimation() {
|
835 |
+
var object = canvas.getActiveObject();
|
836 |
+
animatedtext
|
837 |
+
.find((x) => x.id == object.id)
|
838 |
+
.reset(
|
839 |
+
$(this).parent().find('input').val(),
|
840 |
+
animatedtext.find((x) => x.id == object.id).props,
|
841 |
+
canvas
|
842 |
+
);
|
843 |
+
}
|
844 |
+
|
845 |
+
$(document).on('input', '.property-input', updateObjectValues);
|
846 |
+
$(document).on('change', '.property-input', updateObjectValues);
|
847 |
+
$(document).on('change', '#masks', updateObjectValues);
|
848 |
+
$(document).on('click', '#animatedset', setTextAnimation);
|
849 |
+
|
850 |
+
// Toggle picker (maybe it could be condensed?)
|
851 |
+
function togglePicker() {
|
852 |
+
const object = canvas.getActiveObject();
|
853 |
+
if (!o_fill.isOpen()) {
|
854 |
+
newcolorkeyframe = true;
|
855 |
+
if ($(this).attr('id') == 'object-color-fill') {
|
856 |
+
colormode = 'fill';
|
857 |
+
o_fill.setColor(object.get('fill'));
|
858 |
+
} else if ($(this).attr('id') == 'object-color-stroke') {
|
859 |
+
colormode = 'stroke';
|
860 |
+
o_fill.setColor(object.get('stroke'));
|
861 |
+
} else if ($(this).attr('id') == 'canvas-color') {
|
862 |
+
colormode = 'back';
|
863 |
+
o_fill.setColor(canvas.backgroundColor);
|
864 |
+
} else if ($(this).attr('id') == 'chroma-color') {
|
865 |
+
colormode = 'chroma';
|
866 |
+
if (object.filters.find((x) => x.type == 'RemoveColor')) {
|
867 |
+
o_fill.setColor(
|
868 |
+
object.filters.find((x) => x.type == 'RemoveColor').color
|
869 |
+
);
|
870 |
+
} else {
|
871 |
+
o_fill.setColor('#FFF');
|
872 |
+
}
|
873 |
+
} else if ($(this).attr('id') == 'text-color') {
|
874 |
+
colormode = 'text';
|
875 |
+
o_fill.setColor(
|
876 |
+
animatedtext.find((x) => x.id == object.id).props.fill
|
877 |
+
);
|
878 |
+
} else {
|
879 |
+
colormode = 'shadow';
|
880 |
+
o_fill.setColor(object.shadow.color);
|
881 |
+
}
|
882 |
+
newcolorkeyframe = false;
|
883 |
+
o_fill.show();
|
884 |
+
} else {
|
885 |
+
o_fill.hide();
|
886 |
+
}
|
887 |
+
}
|
888 |
+
$(document).on('click', '#canvas-color', togglePicker);
|
889 |
+
$(document).on('click', '#object-color-fill', togglePicker);
|
890 |
+
$(document).on('click', '#object-color-stroke', togglePicker);
|
891 |
+
$(document).on('click', '#object-color-shadow', togglePicker);
|
892 |
+
$(document).on('click', '#chroma-color', togglePicker);
|
893 |
+
$(document).on('click', '#text-color', togglePicker);
|
894 |
+
|
895 |
+
window.onLoadImage = function (temp) {
|
896 |
+
$(temp).css('background-image', 'none');
|
897 |
+
};
|
898 |
+
|
899 |
+
// Populate shape grid on left panel
|
900 |
+
function populateGrid(type) {
|
901 |
+
if (type == 'shape-tool') {
|
902 |
+
$('#shapes-row').html('');
|
903 |
+
$('#emojis-row').html('');
|
904 |
+
shape_grid_items.forEach(function (item) {
|
905 |
+
$('#shapes-row').append(
|
906 |
+
"<div class='grid-item'><img onload='onLoadImage(this)' draggable=false src='" +
|
907 |
+
item +
|
908 |
+
"'></div>"
|
909 |
+
);
|
910 |
+
});
|
911 |
+
emoji_items.forEach(function (item) {
|
912 |
+
$('#emojis-row').append(
|
913 |
+
"<div class='grid-emoji-item'><img onload='onLoadImage(this)' draggable=false src='" +
|
914 |
+
item +
|
915 |
+
"'></div>"
|
916 |
+
);
|
917 |
+
});
|
918 |
+
} else if (type == 'image-tool') {
|
919 |
+
$('#images-grid').html('');
|
920 |
+
image_categories.forEach(function (category) {
|
921 |
+
$('#categories').append(
|
922 |
+
"<div class='category' data-name='" +
|
923 |
+
category.name +
|
924 |
+
"'><img onload='onLoadImage(this)' src='" +
|
925 |
+
category.image +
|
926 |
+
"'>" +
|
927 |
+
category.name +
|
928 |
+
'</div>'
|
929 |
+
);
|
930 |
+
});
|
931 |
+
} else if (type == 'video-tool') {
|
932 |
+
$('#images-grid').html('');
|
933 |
+
video_categories.forEach(function (category) {
|
934 |
+
$('#categories').append(
|
935 |
+
"<div class='category' data-name='" +
|
936 |
+
category.name +
|
937 |
+
"'><img onload='onLoadImage(this)' src='" +
|
938 |
+
category.image +
|
939 |
+
"'>" +
|
940 |
+
category.name +
|
941 |
+
'</div>'
|
942 |
+
);
|
943 |
+
});
|
944 |
+
} else if (type == 'images-tab') {
|
945 |
+
$('#images-grid').html('');
|
946 |
+
var flag = false;
|
947 |
+
uploaded_images
|
948 |
+
.slice()
|
949 |
+
.reverse()
|
950 |
+
.forEach(function (item) {
|
951 |
+
if (!item.hidden) {
|
952 |
+
flag = true;
|
953 |
+
$('#images-grid').append(
|
954 |
+
"<div class='image-grid-item' data-src='" +
|
955 |
+
item.src +
|
956 |
+
"' data-type='" +
|
957 |
+
item.type +
|
958 |
+
"' data-key='" +
|
959 |
+
item.key +
|
960 |
+
"'><img class='delete-media' draggable=false src='assets/more-options.svg'><img draggable=false onload='onLoadImage(this)' class='image-thing' src='" +
|
961 |
+
item.thumb +
|
962 |
+
"'</div>"
|
963 |
+
);
|
964 |
+
}
|
965 |
+
});
|
966 |
+
$('#landing').remove();
|
967 |
+
if (!flag) {
|
968 |
+
$('#upload-tabs').after(
|
969 |
+
'<div id="landing" class="upload-landing"><div id="landing-text">Your uploaded images will show up here for easy access.</div></div>'
|
970 |
+
);
|
971 |
+
}
|
972 |
+
} else if (type == 'videos-tab') {
|
973 |
+
$('#images-grid').html('');
|
974 |
+
var flag = false;
|
975 |
+
uploaded_videos
|
976 |
+
.slice()
|
977 |
+
.reverse()
|
978 |
+
.forEach(function (item) {
|
979 |
+
if (!item.hidden) {
|
980 |
+
flag = true;
|
981 |
+
$('#images-grid').append(
|
982 |
+
"<div class='video-grid-item' data-src='" +
|
983 |
+
item.src +
|
984 |
+
"' data-type='" +
|
985 |
+
item.type +
|
986 |
+
"' data-key='" +
|
987 |
+
item.key +
|
988 |
+
"'><img class='delete-media' draggable=false src='assets/more-options.svg'><img draggable=false onload='onLoadImage(this)' class='image-thing' src='" +
|
989 |
+
item.thumb +
|
990 |
+
"'></div>"
|
991 |
+
);
|
992 |
+
}
|
993 |
+
});
|
994 |
+
$('#landing').remove();
|
995 |
+
if (!flag) {
|
996 |
+
$('#upload-tabs').after(
|
997 |
+
'<div id="landing" class="upload-landing"><div id="landing-text">Your uploaded videos will show up here for easy access.</div></div>'
|
998 |
+
);
|
999 |
+
}
|
1000 |
+
} else if (type == 'audio-tool') {
|
1001 |
+
var flag = false;
|
1002 |
+
audio_items.forEach(function (item) {
|
1003 |
+
if (item.src == background_key) {
|
1004 |
+
flag = true;
|
1005 |
+
$('#audio-list').append(
|
1006 |
+
"<div class='audio-item audio-item-active' data-src='" +
|
1007 |
+
item.src +
|
1008 |
+
"'><div class='audio-preview'><img src='assets/play-button.svg'></div><img class='audio-thumb' src='" +
|
1009 |
+
item.thumb +
|
1010 |
+
"'><div class='audio-info'><div class='audio-info-title'>" +
|
1011 |
+
item.name +
|
1012 |
+
"</div><a href='" +
|
1013 |
+
item.link +
|
1014 |
+
"' target='_blank' class='audio-info-desc'>" +
|
1015 |
+
item.desc +
|
1016 |
+
"</a><div class='audio-info-duration'>" +
|
1017 |
+
item.duration +
|
1018 |
+
'</div></div></div></div>'
|
1019 |
+
);
|
1020 |
+
} else {
|
1021 |
+
$('#audio-list').append(
|
1022 |
+
"<div class='audio-item' data-src='" +
|
1023 |
+
item.src +
|
1024 |
+
"'><div class='audio-preview'><img src='assets/play-button.svg'></div><img class='audio-thumb' src='" +
|
1025 |
+
item.thumb +
|
1026 |
+
"'><div class='audio-info'><div class='audio-info-title'>" +
|
1027 |
+
item.name +
|
1028 |
+
"</div><a href='" +
|
1029 |
+
item.link +
|
1030 |
+
"' target='_blank' class='audio-info-desc'>" +
|
1031 |
+
item.desc +
|
1032 |
+
"</a><div class='audio-info-duration'>" +
|
1033 |
+
item.duration +
|
1034 |
+
'</div></div></div></div>'
|
1035 |
+
);
|
1036 |
+
}
|
1037 |
+
});
|
1038 |
+
} else if (type == 'text-tool') {
|
1039 |
+
$('#shapes-cont').append("<p class='row-title'>Animated</p>");
|
1040 |
+
$('#shapes-cont').append(
|
1041 |
+
"<div class='animated-text-grid'></div>"
|
1042 |
+
);
|
1043 |
+
text_animation_list.forEach(function (text) {
|
1044 |
+
$('.animated-text-grid').append(
|
1045 |
+
"<div class='animated-text-item noselect' data-id='" +
|
1046 |
+
text.name +
|
1047 |
+
"'><img draggable='false' class='noselect' src='" +
|
1048 |
+
text.src +
|
1049 |
+
"'></div>"
|
1050 |
+
);
|
1051 |
+
});
|
1052 |
+
$('#shapes-cont').append("<p class='row-title'>Sans Serif</p>");
|
1053 |
+
text_items.sansserif.forEach(function (text) {
|
1054 |
+
WebFont.load({
|
1055 |
+
google: {
|
1056 |
+
families: [text.fontname],
|
1057 |
+
},
|
1058 |
+
});
|
1059 |
+
$('#shapes-cont').append(
|
1060 |
+
"<div id='item-text' class='add-text noselect' data-font='" +
|
1061 |
+
text.fontname +
|
1062 |
+
"' style='font-family: " +
|
1063 |
+
text.fontname +
|
1064 |
+
", sans-serif'>" +
|
1065 |
+
text.name +
|
1066 |
+
'</div>'
|
1067 |
+
);
|
1068 |
+
});
|
1069 |
+
$('#shapes-cont').append("<p class='row-title'>Serif</p>");
|
1070 |
+
text_items.serif.forEach(function (text) {
|
1071 |
+
WebFont.load({
|
1072 |
+
google: {
|
1073 |
+
families: [text.fontname],
|
1074 |
+
},
|
1075 |
+
});
|
1076 |
+
$('#shapes-cont').append(
|
1077 |
+
"<div id='item-text' class='add-text noselect' data-font='" +
|
1078 |
+
text.fontname +
|
1079 |
+
"' style='font-family: " +
|
1080 |
+
text.fontname +
|
1081 |
+
"'>" +
|
1082 |
+
text.name +
|
1083 |
+
'</div>'
|
1084 |
+
);
|
1085 |
+
});
|
1086 |
+
$('#shapes-cont').append("<p class='row-title'>Monospace</p>");
|
1087 |
+
text_items.monospace.forEach(function (text) {
|
1088 |
+
WebFont.load({
|
1089 |
+
google: {
|
1090 |
+
families: [text.fontname],
|
1091 |
+
},
|
1092 |
+
});
|
1093 |
+
$('#shapes-cont').append(
|
1094 |
+
"<div id='item-text' class='add-text noselect' data-font='" +
|
1095 |
+
text.fontname +
|
1096 |
+
"' style='font-family: " +
|
1097 |
+
text.fontname +
|
1098 |
+
"'>" +
|
1099 |
+
text.name +
|
1100 |
+
'</div>'
|
1101 |
+
);
|
1102 |
+
});
|
1103 |
+
$('#shapes-cont').append("<p class='row-title'>Handwriting</p>");
|
1104 |
+
text_items.handwriting.forEach(function (text) {
|
1105 |
+
WebFont.load({
|
1106 |
+
google: {
|
1107 |
+
families: [text.fontname],
|
1108 |
+
},
|
1109 |
+
});
|
1110 |
+
$('#shapes-cont').append(
|
1111 |
+
"<div id='item-text' class='add-text noselect' data-font='" +
|
1112 |
+
text.fontname +
|
1113 |
+
"' style='font-family: " +
|
1114 |
+
text.fontname +
|
1115 |
+
"'>" +
|
1116 |
+
text.name +
|
1117 |
+
'</div>'
|
1118 |
+
);
|
1119 |
+
});
|
1120 |
+
$('#shapes-cont').append("<p class='row-title'>Display</p>");
|
1121 |
+
text_items.display.forEach(function (text) {
|
1122 |
+
WebFont.load({
|
1123 |
+
google: {
|
1124 |
+
families: [text.fontname],
|
1125 |
+
},
|
1126 |
+
});
|
1127 |
+
$('#shapes-cont').append(
|
1128 |
+
"<div id='item-text' class='add-text noselect' data-font='" +
|
1129 |
+
text.fontname +
|
1130 |
+
"' style='font-family: " +
|
1131 |
+
text.fontname +
|
1132 |
+
"'>" +
|
1133 |
+
text.name +
|
1134 |
+
'</div>'
|
1135 |
+
);
|
1136 |
+
});
|
1137 |
+
}
|
1138 |
+
}
|
1139 |
+
|
1140 |
+
function scrollBottom() {
|
1141 |
+
if (
|
1142 |
+
$(this).scrollTop() + $(this).innerHeight() >=
|
1143 |
+
$(this)[0].scrollHeight - 50
|
1144 |
+
) {
|
1145 |
+
loadMoreMedia();
|
1146 |
+
}
|
1147 |
+
if ($(this).scrollTop() > 0) {
|
1148 |
+
$('#search-fixed').addClass('search-scrolling');
|
1149 |
+
} else {
|
1150 |
+
$('.search-scrolling').removeClass('search-scrolling');
|
1151 |
+
}
|
1152 |
+
}
|
1153 |
+
|
1154 |
+
function addAnimatedText() {
|
1155 |
+
var newtext = new AnimatedText('Your text', {
|
1156 |
+
left: artboard.get('left') + artboard.get('width') / 2,
|
1157 |
+
top: artboard.get('top') + artboard.get('height') / 2,
|
1158 |
+
preset: $(this).attr('data-id'),
|
1159 |
+
typeAnim: 'letter',
|
1160 |
+
order: 'forward',
|
1161 |
+
fontFamily: 'Syne',
|
1162 |
+
duration: 1000,
|
1163 |
+
easing: 'easeInQuad',
|
1164 |
+
fill: '#FFFFFF',
|
1165 |
+
});
|
1166 |
+
animatedtext.push(newtext);
|
1167 |
+
newtext.render(canvas);
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
$(document).on('click', '.animated-text-item', addAnimatedText);
|
1171 |
+
|
1172 |
+
// Switch active panel in the library
|
1173 |
+
function updateBrowser(type) {
|
1174 |
+
$('#browser').scrollTop(0);
|
1175 |
+
if (type == 'image-tool') {
|
1176 |
+
$('#browser-container').html(image_browser);
|
1177 |
+
populateGrid(type);
|
1178 |
+
$('#browser').on('scroll', scrollBottom);
|
1179 |
+
} else if (type == 'shape-tool') {
|
1180 |
+
$('#browser-container').html(shape_browser);
|
1181 |
+
populateGrid(type);
|
1182 |
+
$('#browser').on('scroll', scrollBottom);
|
1183 |
+
} else if (type == 'video-tool') {
|
1184 |
+
$('#browser-container').html(video_browser);
|
1185 |
+
populateGrid(type);
|
1186 |
+
$('#browser').on('scroll', scrollBottom);
|
1187 |
+
} else if (type == 'text-tool') {
|
1188 |
+
$('#browser-container').html(text_browser);
|
1189 |
+
populateGrid(type);
|
1190 |
+
$('#browser').on('scroll', scrollBottom);
|
1191 |
+
} else if (type == 'upload-tool') {
|
1192 |
+
$('#browser-container').html(upload_browser);
|
1193 |
+
populateGrid('images-tab');
|
1194 |
+
$('#browser').on('scroll', scrollBottom);
|
1195 |
+
} else if (type == 'audio-tool') {
|
1196 |
+
$('#browser-container').html(audio_browser);
|
1197 |
+
populateGrid(type);
|
1198 |
+
$('#browser').on('scroll', scrollBottom);
|
1199 |
+
}
|
1200 |
+
}
|
1201 |
+
|
1202 |
+
// Switch tab in the uploads depending on item being uploaded
|
1203 |
+
function updateUploadType() {
|
1204 |
+
$('.upload-tab-active').removeClass('upload-tab-active');
|
1205 |
+
$(this).addClass('upload-tab-active');
|
1206 |
+
populateGrid($(this).attr('id'));
|
1207 |
+
}
|
1208 |
+
$(document).on(
|
1209 |
+
'click',
|
1210 |
+
'.upload-tab:not(.upload-tab-active)',
|
1211 |
+
updateUploadType
|
1212 |
+
);
|
1213 |
+
|
1214 |
+
// Switch tool
|
1215 |
+
function switchTool(e) {
|
1216 |
+
$('#browser').removeClass('collapsed');
|
1217 |
+
$('#canvas-area').removeClass('canvas-full');
|
1218 |
+
if ($(this).attr('id') == 'more-tool') {
|
1219 |
+
showMore();
|
1220 |
+
return false;
|
1221 |
+
}
|
1222 |
+
resizeCanvas();
|
1223 |
+
var act = $('.tool-active');
|
1224 |
+
if (act.attr('id') == 'image-tool') {
|
1225 |
+
act.find('img').attr('src', 'assets/image.svg');
|
1226 |
+
} else if (act.attr('id') == 'text-tool') {
|
1227 |
+
act.find('img').attr('src', 'assets/text.svg');
|
1228 |
+
} else if (act.attr('id') == 'mockup-tool') {
|
1229 |
+
act.find('img').attr('src', 'assets/mockup.svg');
|
1230 |
+
} else if (act.attr('id') == 'video-tool') {
|
1231 |
+
act.find('img').attr('src', 'assets/video.svg');
|
1232 |
+
} else if (act.attr('id') == 'shape-tool') {
|
1233 |
+
act.find('img').attr('src', 'assets/shape.svg');
|
1234 |
+
} else if (act.attr('id') == 'upload-tool') {
|
1235 |
+
act.find('img').attr('src', 'assets/uploads.svg');
|
1236 |
+
} else if (act.attr('id') == 'audio-tool') {
|
1237 |
+
act.find('img').attr('src', 'assets/audio.svg');
|
1238 |
+
}
|
1239 |
+
$('.tool-active').removeClass('tool-active');
|
1240 |
+
$(this).addClass('tool-active');
|
1241 |
+
if ($(this).attr('id') == 'image-tool') {
|
1242 |
+
$(this).find('img').attr('src', 'assets/image-active.svg');
|
1243 |
+
} else if ($(this).attr('id') == 'text-tool') {
|
1244 |
+
$(this).find('img').attr('src', 'assets/text-active.svg');
|
1245 |
+
} else if ($(this).attr('id') == 'mockup-tool') {
|
1246 |
+
$(this).find('img').attr('src', 'assets/mockup-active.svg');
|
1247 |
+
} else if ($(this).attr('id') == 'video-tool') {
|
1248 |
+
$(this).find('img').attr('src', 'assets/video-active.svg');
|
1249 |
+
} else if ($(this).attr('id') == 'shape-tool') {
|
1250 |
+
$(this).find('img').attr('src', 'assets/shape-active.svg');
|
1251 |
+
} else if ($(this).attr('id') == 'upload-tool') {
|
1252 |
+
$(this).find('img').attr('src', 'assets/uploads-active.svg');
|
1253 |
+
} else if ($(this).attr('id') == 'audio-tool') {
|
1254 |
+
$(this).find('img').attr('src', 'assets/audio-active.svg');
|
1255 |
+
}
|
1256 |
+
updateBrowser($(this).attr('id'));
|
1257 |
+
resetHeight();
|
1258 |
+
}
|
1259 |
+
$(document).on('click', '.tool:not(.tool-active)', switchTool);
|
1260 |
+
|
1261 |
+
// Replace image or video by dragging on top and holding a key
|
1262 |
+
function replaceObject(src, object) {
|
1263 |
+
var img = new Image();
|
1264 |
+
var width = object.width;
|
1265 |
+
var height = object.height;
|
1266 |
+
oldsrc = object._originalElement.currentSrc;
|
1267 |
+
oldobj = object;
|
1268 |
+
img.onload = function () {
|
1269 |
+
object.setElement(img);
|
1270 |
+
object.set('width', width);
|
1271 |
+
object.set('height', height);
|
1272 |
+
canvas.renderAll();
|
1273 |
+
};
|
1274 |
+
img.src = src;
|
1275 |
+
}
|
1276 |
+
|
1277 |
+
// Drag object from the panel
|
1278 |
+
function dragObject(e) {
|
1279 |
+
if (e.which == 3) {
|
1280 |
+
return false;
|
1281 |
+
}
|
1282 |
+
var drag = $(this).clone();
|
1283 |
+
drag.css({
|
1284 |
+
background: 'transparent',
|
1285 |
+
boxShadow: 'none',
|
1286 |
+
color: '#000',
|
1287 |
+
});
|
1288 |
+
drag.appendTo('body');
|
1289 |
+
drag.css({
|
1290 |
+
position: 'absolute',
|
1291 |
+
zIndex: 9999999,
|
1292 |
+
left: $(this).offset().left,
|
1293 |
+
top: $(this).offset().top,
|
1294 |
+
width: canvas.getZoom() * drag.width(),
|
1295 |
+
pointerEvents: 'none',
|
1296 |
+
opacity: 0,
|
1297 |
+
});
|
1298 |
+
var pageX = e.pageX;
|
1299 |
+
var pageY = e.pageY;
|
1300 |
+
var offset = drag.offset();
|
1301 |
+
var offsetx = drag.offset().left + drag.width() / 2 - e.pageX;
|
1302 |
+
var offsety = drag.offset().top + drag.height() / 2 - e.pageY;
|
1303 |
+
var replacing = false;
|
1304 |
+
draggingPanel = true;
|
1305 |
+
var move = false;
|
1306 |
+
canvas.discardActiveObject();
|
1307 |
+
canvas.renderAll();
|
1308 |
+
function dragging(e) {
|
1309 |
+
$('#bottom-area').addClass('noselect');
|
1310 |
+
$('#toolbar').addClass('noselect');
|
1311 |
+
$('#browser').addClass('noselect');
|
1312 |
+
$('#properties').addClass('noselect');
|
1313 |
+
$('#controls').addClass('noselect');
|
1314 |
+
move = true;
|
1315 |
+
var left = offset.left + (e.pageX - pageX);
|
1316 |
+
var top = offset.top + (e.pageY - pageY);
|
1317 |
+
drag.offset({ left: left, top: top });
|
1318 |
+
|
1319 |
+
if (
|
1320 |
+
overCanvas &&
|
1321 |
+
canvas.getActiveObject() &&
|
1322 |
+
!replacing &&
|
1323 |
+
canvas.getActiveObject().type == 'image' &&
|
1324 |
+
(drag.hasClass('image-grid-item') ||
|
1325 |
+
drag.hasClass('video-grid-item'))
|
1326 |
+
) {
|
1327 |
+
if (e.ctrlKey) {
|
1328 |
+
drag.css('visibility', 'hidden');
|
1329 |
+
replaceObject(
|
1330 |
+
drag.attr('data-src'),
|
1331 |
+
canvas.getActiveObject()
|
1332 |
+
);
|
1333 |
+
replacing = true;
|
1334 |
+
} else {
|
1335 |
+
$('#replace-image').addClass('replace-active');
|
1336 |
+
}
|
1337 |
+
} else if (
|
1338 |
+
(replacing && !canvas.getActiveObject()) ||
|
1339 |
+
(replacing && !e.ctrlKey)
|
1340 |
+
) {
|
1341 |
+
drag.css('visibility', 'visible');
|
1342 |
+
replaceObject(oldsrc, oldobj);
|
1343 |
+
replacing = false;
|
1344 |
+
canvas.discardActiveObject();
|
1345 |
+
$('#replace-image').removeClass('replace-active');
|
1346 |
+
} else {
|
1347 |
+
$('#replace-image').removeClass('replace-active');
|
1348 |
+
}
|
1349 |
+
|
1350 |
+
if (overCanvas) {
|
1351 |
+
drag.css({ opacity: 1 });
|
1352 |
+
} else {
|
1353 |
+
drag.css({ opacity: 0.5 });
|
1354 |
+
}
|
1355 |
+
}
|
1356 |
+
function released(e) {
|
1357 |
+
$('#replace-image').removeClass('replace-active');
|
1358 |
+
$('#bottom-area').removeClass('noselect');
|
1359 |
+
$('#toolbar').removeClass('noselect');
|
1360 |
+
$('#browser').removeClass('noselect');
|
1361 |
+
$('#properties').removeClass('noselect');
|
1362 |
+
$('#controls').removeClass('noselect');
|
1363 |
+
draggingPanel = false;
|
1364 |
+
$('body').off('mousemove', dragging).off('mouseup', released);
|
1365 |
+
canvasx = canvas.getPointer(e).x;
|
1366 |
+
canvasy = canvas.getPointer(e).y;
|
1367 |
+
var xpos = canvasx + offsetx - artboard.get('left');
|
1368 |
+
var ypos = canvasy + offsety - artboard.get('top');
|
1369 |
+
if (!overCanvas && move) {
|
1370 |
+
drag.remove();
|
1371 |
+
return false;
|
1372 |
+
}
|
1373 |
+
if (move && !replacing) {
|
1374 |
+
if (drag.hasClass('grid-item')) {
|
1375 |
+
newSVG(
|
1376 |
+
drag.find('img').attr('src'),
|
1377 |
+
xpos,
|
1378 |
+
ypos,
|
1379 |
+
drag.width(),
|
1380 |
+
false
|
1381 |
+
);
|
1382 |
+
} else if (drag.hasClass('image-external-grid-item')) {
|
1383 |
+
$('#load-image').addClass('loading-active');
|
1384 |
+
savePixabayImage(
|
1385 |
+
drag.attr('data-src'),
|
1386 |
+
xpos,
|
1387 |
+
ypos,
|
1388 |
+
drag.width()
|
1389 |
+
);
|
1390 |
+
} else if (drag.hasClass('video-external-grid-item')) {
|
1391 |
+
savePixabayVideo(
|
1392 |
+
drag.attr('data-src'),
|
1393 |
+
drag.find('img').attr('src'),
|
1394 |
+
xpos,
|
1395 |
+
ypos
|
1396 |
+
);
|
1397 |
+
} else if (drag.hasClass('image-grid-item')) {
|
1398 |
+
$('#load-image').addClass('loading-active');
|
1399 |
+
loadImage(
|
1400 |
+
drag.attr('data-src'),
|
1401 |
+
xpos,
|
1402 |
+
ypos,
|
1403 |
+
drag.width(),
|
1404 |
+
false
|
1405 |
+
);
|
1406 |
+
} else if (drag.hasClass('grid-emoji-item')) {
|
1407 |
+
$('#load-image').addClass('loading-active');
|
1408 |
+
loadImage(
|
1409 |
+
drag.find('img').attr('src'),
|
1410 |
+
xpos,
|
1411 |
+
ypos,
|
1412 |
+
drag.width(),
|
1413 |
+
false
|
1414 |
+
);
|
1415 |
+
} else if (drag.hasClass('add-text')) {
|
1416 |
+
if (drag.attr('id') == 'heading-text') {
|
1417 |
+
newTextbox(
|
1418 |
+
50,
|
1419 |
+
700,
|
1420 |
+
'Add a heading',
|
1421 |
+
canvasx - artboard.get('left'),
|
1422 |
+
canvasy - artboard.get('top'),
|
1423 |
+
drag.width(),
|
1424 |
+
false,
|
1425 |
+
drag.attr('data-font')
|
1426 |
+
);
|
1427 |
+
} else if (drag.attr('id') == 'subheading-text') {
|
1428 |
+
newTextbox(
|
1429 |
+
22,
|
1430 |
+
500,
|
1431 |
+
'Add a subheading',
|
1432 |
+
canvasx - artboard.get('left'),
|
1433 |
+
canvasy - artboard.get('top'),
|
1434 |
+
drag.width(),
|
1435 |
+
false,
|
1436 |
+
drag.attr('data-font')
|
1437 |
+
);
|
1438 |
+
} else if (drag.attr('id') == 'body-text') {
|
1439 |
+
newTextbox(
|
1440 |
+
18,
|
1441 |
+
400,
|
1442 |
+
'Add body text',
|
1443 |
+
canvasx - artboard.get('left'),
|
1444 |
+
canvasy - artboard.get('top'),
|
1445 |
+
drag.width(),
|
1446 |
+
false,
|
1447 |
+
drag.attr('data-font')
|
1448 |
+
);
|
1449 |
+
} else {
|
1450 |
+
newTextbox(
|
1451 |
+
18,
|
1452 |
+
400,
|
1453 |
+
'Your text',
|
1454 |
+
canvasx - artboard.get('left'),
|
1455 |
+
canvasy - artboard.get('top'),
|
1456 |
+
drag.width(),
|
1457 |
+
false,
|
1458 |
+
drag.attr('data-font')
|
1459 |
+
);
|
1460 |
+
}
|
1461 |
+
} else if (drag.hasClass('video-grid-item')) {
|
1462 |
+
$('#load-video').addClass('loading-active');
|
1463 |
+
loadVideo(drag.attr('data-src'), canvasx, canvasy);
|
1464 |
+
}
|
1465 |
+
} else if (!move && !replacing) {
|
1466 |
+
if (drag.hasClass('grid-item')) {
|
1467 |
+
newSVG(
|
1468 |
+
drag.find('img').attr('src'),
|
1469 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1470 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1471 |
+
100,
|
1472 |
+
true
|
1473 |
+
);
|
1474 |
+
} else if (drag.hasClass('image-external-grid-item')) {
|
1475 |
+
savePixabayImage(
|
1476 |
+
drag.attr('data-src'),
|
1477 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1478 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1479 |
+
150
|
1480 |
+
);
|
1481 |
+
} else if (drag.hasClass('video-external-grid-item')) {
|
1482 |
+
savePixabayVideo(
|
1483 |
+
drag.attr('data-src'),
|
1484 |
+
drag.find('img').attr('src'),
|
1485 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1486 |
+
artboard.get('top') + artboard.get('height') / 2
|
1487 |
+
);
|
1488 |
+
} else if (drag.hasClass('image-grid-item')) {
|
1489 |
+
$('#load-image').addClass('loading-active');
|
1490 |
+
loadImage(
|
1491 |
+
drag.attr('data-src'),
|
1492 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1493 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1494 |
+
150,
|
1495 |
+
true
|
1496 |
+
);
|
1497 |
+
} else if (drag.hasClass('grid-emoji-item')) {
|
1498 |
+
$('#load-image').addClass('loading-active');
|
1499 |
+
loadImage(
|
1500 |
+
drag.find('img').attr('src'),
|
1501 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1502 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1503 |
+
50,
|
1504 |
+
true
|
1505 |
+
);
|
1506 |
+
} else if (drag.hasClass('add-text')) {
|
1507 |
+
if (drag.attr('id') == 'heading-text') {
|
1508 |
+
newTextbox(
|
1509 |
+
50,
|
1510 |
+
700,
|
1511 |
+
'Add a heading',
|
1512 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1513 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1514 |
+
drag.width(),
|
1515 |
+
true,
|
1516 |
+
drag.attr('data-font')
|
1517 |
+
);
|
1518 |
+
} else if (drag.attr('id') == 'subheading-text') {
|
1519 |
+
newTextbox(
|
1520 |
+
22,
|
1521 |
+
500,
|
1522 |
+
'Add a subheading',
|
1523 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1524 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1525 |
+
drag.width(),
|
1526 |
+
true,
|
1527 |
+
drag.attr('data-font')
|
1528 |
+
);
|
1529 |
+
} else if (drag.attr('id') == 'body-text') {
|
1530 |
+
newTextbox(
|
1531 |
+
18,
|
1532 |
+
400,
|
1533 |
+
'Add body text',
|
1534 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1535 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1536 |
+
drag.width(),
|
1537 |
+
true,
|
1538 |
+
drag.attr('data-font')
|
1539 |
+
);
|
1540 |
+
} else {
|
1541 |
+
newTextbox(
|
1542 |
+
18,
|
1543 |
+
400,
|
1544 |
+
'Your text',
|
1545 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1546 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1547 |
+
drag.width(),
|
1548 |
+
true,
|
1549 |
+
drag.attr('data-font')
|
1550 |
+
);
|
1551 |
+
}
|
1552 |
+
} else if (drag.hasClass('video-grid-item')) {
|
1553 |
+
$('#load-video').addClass('loading-active');
|
1554 |
+
loadVideo(
|
1555 |
+
drag.attr('data-src'),
|
1556 |
+
artboard.get('left') + artboard.get('width') / 2,
|
1557 |
+
artboard.get('top') + artboard.get('height') / 2,
|
1558 |
+
true
|
1559 |
+
);
|
1560 |
+
}
|
1561 |
+
}
|
1562 |
+
drag.remove();
|
1563 |
+
}
|
1564 |
+
$('body').on('mouseup', released).on('mousemove', dragging);
|
1565 |
+
}
|
1566 |
+
$(document).on('mousedown', '.image-grid-item', dragObject);
|
1567 |
+
$(document).on('mousedown', '.video-grid-item', dragObject);
|
1568 |
+
$(document).on('mousedown', '.grid-item', dragObject);
|
1569 |
+
$(document).on('mousedown', '.grid-emoji-item', dragObject);
|
1570 |
+
$(document).on('mousedown', '.add-text', dragObject);
|
1571 |
+
$(document).on('mousedown click mouseup', '.credit', function (e) {
|
1572 |
+
e.stopPropagation();
|
1573 |
+
});
|
1574 |
+
|
1575 |
+
// Collapse library
|
1576 |
+
function collapsePanel() {
|
1577 |
+
$('#browser').addClass('collapsed');
|
1578 |
+
$('#behind-browser').addClass('collapsed');
|
1579 |
+
$('#canvas-area').addClass('canvas-full');
|
1580 |
+
var act = $('.tool-active');
|
1581 |
+
if (act.attr('id') == 'image-tool') {
|
1582 |
+
act.find('img').attr('src', 'assets/image.svg');
|
1583 |
+
} else if (act.attr('id') == 'text-tool') {
|
1584 |
+
act.find('img').attr('src', 'assets/text.svg');
|
1585 |
+
} else if (act.attr('id') == 'mockup-tool') {
|
1586 |
+
act.find('img').attr('src', 'assets/mockup.svg');
|
1587 |
+
} else if (act.attr('id') == 'video-tool') {
|
1588 |
+
act.find('img').attr('src', 'assets/video.svg');
|
1589 |
+
} else if (act.attr('id') == 'shape-tool') {
|
1590 |
+
act.find('img').attr('src', 'assets/shape.svg');
|
1591 |
+
} else if (act.attr('id') == 'upload-tool') {
|
1592 |
+
act.find('img').attr('src', 'assets/uploads.svg');
|
1593 |
+
}
|
1594 |
+
$('.tool-active').removeClass('tool-active');
|
1595 |
+
resizeCanvas();
|
1596 |
+
}
|
1597 |
+
$(document).on('click', '#collapse', collapsePanel);
|
1598 |
+
$(document).on('click', '.tool-active', collapsePanel);
|
1599 |
+
|
1600 |
+
// Change canvas dimensions to selected preset
|
1601 |
+
function setPreset() {
|
1602 |
+
if ($(this).val() != 'custom') {
|
1603 |
+
artboard.set({
|
1604 |
+
width: presets.find((x) => x.id == $(this).val()).width,
|
1605 |
+
height: presets.find((x) => x.id == $(this).val()).height,
|
1606 |
+
});
|
1607 |
+
canvas.renderAll();
|
1608 |
+
resizeCanvas();
|
1609 |
+
}
|
1610 |
+
activepreset = $(this).val();
|
1611 |
+
updatePanel();
|
1612 |
+
save();
|
1613 |
+
}
|
1614 |
+
$(document).on('change', '#preset', setPreset);
|
1615 |
+
|
1616 |
+
function setTextPreset() {
|
1617 |
+
var object = canvas.getActiveObject();
|
1618 |
+
animatedtext
|
1619 |
+
.find((x) => x.id == object.id)
|
1620 |
+
.setProp({ preset: $(this).val() }, canvas);
|
1621 |
+
save();
|
1622 |
+
}
|
1623 |
+
function setTextEasing() {
|
1624 |
+
var object = canvas.getActiveObject();
|
1625 |
+
animatedtext
|
1626 |
+
.find((x) => x.id == object.id)
|
1627 |
+
.setProp({ easing: $(this).val() }, canvas);
|
1628 |
+
save();
|
1629 |
+
}
|
1630 |
+
$(document).on('change', '#preset-picker', setTextPreset);
|
1631 |
+
$(document).on('change', '#easing-picker', setTextEasing);
|
1632 |
+
|
1633 |
+
// Delete media from the panel
|
1634 |
+
function deleteMedia(e) {
|
1635 |
+
e.preventDefault();
|
1636 |
+
e.stopPropagation();
|
1637 |
+
var key = $(this).parent().attr('data-key');
|
1638 |
+
if (
|
1639 |
+
window.confirm(
|
1640 |
+
'Are you sure you want to permanently delete this asset? It will also remove any instances of it in the canvas.'
|
1641 |
+
)
|
1642 |
+
) {
|
1643 |
+
deleteAsset(key);
|
1644 |
+
}
|
1645 |
+
}
|
1646 |
+
$(document).on('mousedown', '.delete-media', deleteMedia);
|
1647 |
+
|
1648 |
+
// Save layer name
|
1649 |
+
function saveLayerName() {
|
1650 |
+
$('.name-active').prop('readonly', true);
|
1651 |
+
if ($('.name-active').val() == '') {
|
1652 |
+
$('.name-active').val('Untitled layer');
|
1653 |
+
}
|
1654 |
+
objects.find(
|
1655 |
+
(x) =>
|
1656 |
+
x.id == $('.name-active').parent().parent().attr('data-object')
|
1657 |
+
).label = $('.name-active').val();
|
1658 |
+
save();
|
1659 |
+
$('.name-active').removeClass('name-active');
|
1660 |
+
if (window.getSelection) {
|
1661 |
+
if (window.getSelection().empty) {
|
1662 |
+
window.getSelection().empty();
|
1663 |
+
} else if (window.getSelection().removeAllRanges) {
|
1664 |
+
window.getSelection().removeAllRanges();
|
1665 |
+
}
|
1666 |
+
} else if (document.selection) {
|
1667 |
+
document.selection.empty();
|
1668 |
+
}
|
1669 |
+
editinglayer = false;
|
1670 |
+
}
|
1671 |
+
$(document).on('focusout', '.layer-custom-name', saveLayerName);
|
1672 |
+
|
1673 |
+
// Zoom to specific level
|
1674 |
+
function zoomTo() {
|
1675 |
+
var zoom;
|
1676 |
+
if ($(this).attr('data-zoom') == 'in') {
|
1677 |
+
zoom = canvas.getZoom() + 0.2;
|
1678 |
+
} else if ($(this).attr('data-zoom') == 'out') {
|
1679 |
+
zoom = canvas.getZoom() - 0.2;
|
1680 |
+
} else {
|
1681 |
+
zoom = parseInt($(this).attr('data-zoom')) / 100;
|
1682 |
+
}
|
1683 |
+
if (zoom > 20) zoom = 20;
|
1684 |
+
if (zoom < 0.01) zoom = 0.01;
|
1685 |
+
canvas.setZoom(1);
|
1686 |
+
canvas.renderAll();
|
1687 |
+
var vpw = canvas.width / zoom;
|
1688 |
+
var vph = canvas.height / zoom;
|
1689 |
+
var x = artboard.left + artboard.width / 2 - vpw / 2;
|
1690 |
+
var y = artboard.top + artboard.height / 2 - vph / 2;
|
1691 |
+
canvas.absolutePan({ x: x, y: y });
|
1692 |
+
canvas.setZoom(zoom);
|
1693 |
+
canvas.renderAll();
|
1694 |
+
$('#zoom-level span').html(
|
1695 |
+
(canvas.getZoom() * 100).toFixed(0) + '%'
|
1696 |
+
);
|
1697 |
+
}
|
1698 |
+
$(document).on('click', '.zoom-options-item', zoomTo);
|
1699 |
+
|
1700 |
+
// Add background audio (temporary)
|
1701 |
+
function addBackgroundAudio() {
|
1702 |
+
background_audio = new Audio('assets/audio.wav');
|
1703 |
+
}
|
1704 |
+
|
1705 |
+
// Hide all modals
|
1706 |
+
function hideModals() {
|
1707 |
+
$('.modal-open').removeClass('modal-open');
|
1708 |
+
}
|
1709 |
+
$('#background-overlay').on('click', hideModals);
|
1710 |
+
|
1711 |
+
// Open download modal
|
1712 |
+
function downloadModal() {
|
1713 |
+
if (!recording) {
|
1714 |
+
hideModals();
|
1715 |
+
$('#download-modal').addClass('modal-open');
|
1716 |
+
$('#background-overlay').addClass('modal-open');
|
1717 |
+
}
|
1718 |
+
}
|
1719 |
+
$('#download').on('click', downloadModal);
|
1720 |
+
|
1721 |
+
// Open import/export modal
|
1722 |
+
function importExportModal() {
|
1723 |
+
hideModals();
|
1724 |
+
$('#import-export-modal').toggleClass('modal-open');
|
1725 |
+
$('#background-overlay').toggleClass('modal-open');
|
1726 |
+
}
|
1727 |
+
$('#share').on('click', importExportModal);
|
1728 |
+
|
1729 |
+
function searchInput() {
|
1730 |
+
var value = $(this).val().toLowerCase();
|
1731 |
+
if (value == '') {
|
1732 |
+
$('#delete-search').removeClass('show-delete');
|
1733 |
+
} else {
|
1734 |
+
$('#delete-search').addClass('show-delete');
|
1735 |
+
}
|
1736 |
+
}
|
1737 |
+
|
1738 |
+
function fancyTimeFormat(duration) {
|
1739 |
+
var hrs = ~~(duration / 3600);
|
1740 |
+
var mins = ~~((duration % 3600) / 60);
|
1741 |
+
var secs = ~~duration % 60;
|
1742 |
+
var ret = '';
|
1743 |
+
if (hrs > 0) {
|
1744 |
+
ret += '' + hrs + ':' + (mins < 10 ? '0' : '');
|
1745 |
+
}
|
1746 |
+
ret += '' + mins + ':' + (secs < 10 ? '0' : '');
|
1747 |
+
ret += '' + secs;
|
1748 |
+
return ret;
|
1749 |
+
}
|
1750 |
+
|
1751 |
+
function loadMoreMedia() {
|
1752 |
+
var value = $('#browser-search input').val();
|
1753 |
+
if (value != '' && page != false) {
|
1754 |
+
page += 1;
|
1755 |
+
if ($('#image-tool').hasClass('tool-active')) {
|
1756 |
+
var URL =
|
1757 |
+
'https://pixabay.com/api/?key=' +
|
1758 |
+
API_KEY +
|
1759 |
+
'&q=' +
|
1760 |
+
encodeURIComponent(value) +
|
1761 |
+
'&page=' +
|
1762 |
+
page;
|
1763 |
+
$.getJSON(URL, function (data) {
|
1764 |
+
if (parseInt(data.totalHits) > 0) {
|
1765 |
+
$.each(data.hits, function (i, hit) {
|
1766 |
+
$('#images-grid').append(
|
1767 |
+
"<div class='image-grid-item image-external-grid-item' data-src='" +
|
1768 |
+
hit.webformatURL +
|
1769 |
+
"'><a class='credit' href='" +
|
1770 |
+
hit.pageURL +
|
1771 |
+
"' target='_blank'>" +
|
1772 |
+
hit.user +
|
1773 |
+
"</a><img draggable=false onload='onLoadImage(this)' src='" +
|
1774 |
+
hit.webformatURL +
|
1775 |
+
"'</div>"
|
1776 |
+
);
|
1777 |
+
});
|
1778 |
+
} else {
|
1779 |
+
page = false;
|
1780 |
+
}
|
1781 |
+
});
|
1782 |
+
} else if ($('#video-tool').hasClass('tool-active')) {
|
1783 |
+
var URL =
|
1784 |
+
'https://pixabay.com/api/videos/?key=' +
|
1785 |
+
API_KEY +
|
1786 |
+
'&q=' +
|
1787 |
+
encodeURIComponent(value) +
|
1788 |
+
'&page=' +
|
1789 |
+
page;
|
1790 |
+
$.getJSON(URL, function (data) {
|
1791 |
+
if (parseInt(data.totalHits) > 0) {
|
1792 |
+
$.each(data.hits, function (i, hit) {
|
1793 |
+
var video = hit.videos.medium.url;
|
1794 |
+
$('#images-grid').append(
|
1795 |
+
"<div class='image-grid-item video-external-grid-item' data-src='" +
|
1796 |
+
video +
|
1797 |
+
"'><a class='credit' href='" +
|
1798 |
+
hit.pageURL +
|
1799 |
+
"' target='_blank'>" +
|
1800 |
+
hit.user +
|
1801 |
+
"</a><div id='time-video'>" +
|
1802 |
+
fancyTimeFormat(hit.duration) +
|
1803 |
+
"</div><img draggable=false onload='onLoadImage(this)' src='assets/transparent.png'</div>"
|
1804 |
+
);
|
1805 |
+
createVideoThumbnail(video, 250, 0, true).then(function (
|
1806 |
+
data
|
1807 |
+
) {
|
1808 |
+
$(".image-grid-item[data-src='" + video + "']")
|
1809 |
+
.find('img')
|
1810 |
+
.attr('src', data);
|
1811 |
+
});
|
1812 |
+
});
|
1813 |
+
} else {
|
1814 |
+
page = false;
|
1815 |
+
}
|
1816 |
+
});
|
1817 |
+
}
|
1818 |
+
}
|
1819 |
+
}
|
1820 |
+
|
1821 |
+
function search() {
|
1822 |
+
page = 1;
|
1823 |
+
var value = $('#browser-search input').val();
|
1824 |
+
if ($('#image-tool').hasClass('tool-active')) {
|
1825 |
+
var URL =
|
1826 |
+
'https://pixabay.com/api/?key=' +
|
1827 |
+
API_KEY +
|
1828 |
+
'&q=' +
|
1829 |
+
encodeURIComponent(value) +
|
1830 |
+
'&page=' +
|
1831 |
+
page;
|
1832 |
+
$('#images-grid').html('');
|
1833 |
+
if (value != '') {
|
1834 |
+
$('#pixabay').addClass('hide-pixabay');
|
1835 |
+
$('#landing').addClass('hide-landing');
|
1836 |
+
$.getJSON(URL, function (data) {
|
1837 |
+
if (parseInt(data.totalHits) > 0) {
|
1838 |
+
$.each(data.hits, function (i, hit) {
|
1839 |
+
$('#images-grid').append(
|
1840 |
+
"<div class='image-grid-item image-external-grid-item' data-src='" +
|
1841 |
+
hit.webformatURL +
|
1842 |
+
"'><a class='credit' href='" +
|
1843 |
+
hit.pageURL +
|
1844 |
+
"' target='_blank'>" +
|
1845 |
+
hit.user +
|
1846 |
+
"</a><img draggable=false onload='onLoadImage(this)' src='" +
|
1847 |
+
hit.webformatURL +
|
1848 |
+
"'</div>"
|
1849 |
+
);
|
1850 |
+
});
|
1851 |
+
} else {
|
1852 |
+
$('#shapes-cont').html(
|
1853 |
+
"<div id='no-results'>Sorry, we couldn't find any results for "" +
|
1854 |
+
encodeURIComponent(value) +
|
1855 |
+
'". Please try a different query.</div>'
|
1856 |
+
);
|
1857 |
+
}
|
1858 |
+
});
|
1859 |
+
} else {
|
1860 |
+
$('#pixabay').removeClass('hide-pixabay');
|
1861 |
+
$('#landing').removeClass('hide-landing');
|
1862 |
+
}
|
1863 |
+
} else if ($('#video-tool').hasClass('tool-active')) {
|
1864 |
+
var URL =
|
1865 |
+
'https://pixabay.com/api/videos/?key=' +
|
1866 |
+
API_KEY +
|
1867 |
+
'&q=' +
|
1868 |
+
encodeURIComponent(value);
|
1869 |
+
$('#images-grid').html('');
|
1870 |
+
if (value != '') {
|
1871 |
+
$('#landing').addClass('hide-landing');
|
1872 |
+
$('#pixabay').addClass('hide-pixabay');
|
1873 |
+
$.getJSON(URL, function (data) {
|
1874 |
+
if (parseInt(data.totalHits) > 0) {
|
1875 |
+
$.each(data.hits, function (i, hit) {
|
1876 |
+
var video = hit.videos.medium.url;
|
1877 |
+
$('#images-grid').append(
|
1878 |
+
"<div class='image-grid-item video-external-grid-item' data-src='" +
|
1879 |
+
video +
|
1880 |
+
"'><a class='credit' href='" +
|
1881 |
+
hit.pageURL +
|
1882 |
+
"' target='_blank'>" +
|
1883 |
+
hit.user +
|
1884 |
+
"</a><div id='time-video'>" +
|
1885 |
+
fancyTimeFormat(hit.duration) +
|
1886 |
+
"</div><img draggable=false onload='onLoadImage(this)' src='assets/transparent.png'</div>"
|
1887 |
+
);
|
1888 |
+
//createVideoThumbnail(video, 250, 0, true).then(function(data){
|
1889 |
+
$(".image-grid-item[data-src='" + video + "']")
|
1890 |
+
.find('img')
|
1891 |
+
.attr(
|
1892 |
+
'src',
|
1893 |
+
'https://i.vimeocdn.com/video/' +
|
1894 |
+
hit.picture_id +
|
1895 |
+
'_640x360.jpg'
|
1896 |
+
);
|
1897 |
+
//});
|
1898 |
+
});
|
1899 |
+
} else {
|
1900 |
+
$('#shapes-cont').html(
|
1901 |
+
"<div id='no-results'>Sorry, we couldn't find any results for "" +
|
1902 |
+
encodeURIComponent(value) +
|
1903 |
+
'". Please try a different query.</div>'
|
1904 |
+
);
|
1905 |
+
}
|
1906 |
+
});
|
1907 |
+
} else {
|
1908 |
+
$('#pixabay').removeClass('hide-pixabay');
|
1909 |
+
$('#landing').removeClass('hide-landing');
|
1910 |
+
}
|
1911 |
+
} else if ($('#shape-tool').hasClass('tool-active')) {
|
1912 |
+
if (value == '') {
|
1913 |
+
$('#shapes-cont').html(
|
1914 |
+
'<p class="row-title">Shapes</p><div class="gallery-row" id="shapes-row"></div><p class="row-title">Emojis</p><div class="gallery-row" id="emojis-row"></div>'
|
1915 |
+
);
|
1916 |
+
populateGrid('shape-tool');
|
1917 |
+
} else {
|
1918 |
+
$('.row-title').remove();
|
1919 |
+
$('.gallery-row').remove();
|
1920 |
+
$('#shapes-cont').html("<div class='gallery-row'></div>");
|
1921 |
+
var combined = shape_grid_items.concat(emoji_items);
|
1922 |
+
var flag = false;
|
1923 |
+
combined.forEach(function (item) {
|
1924 |
+
if (item.indexOf(value) > -1) {
|
1925 |
+
flag = true;
|
1926 |
+
if (item.indexOf('emoji') > -1) {
|
1927 |
+
$('.gallery-row').append(
|
1928 |
+
"<div class='grid-emoji-item'><img draggable=false src='" +
|
1929 |
+
item +
|
1930 |
+
"'></div>"
|
1931 |
+
);
|
1932 |
+
} else {
|
1933 |
+
$('.gallery-row').append(
|
1934 |
+
"<div class='grid-item'><img draggable=false src='" +
|
1935 |
+
item +
|
1936 |
+
"'></div>"
|
1937 |
+
);
|
1938 |
+
}
|
1939 |
+
}
|
1940 |
+
});
|
1941 |
+
if (!flag) {
|
1942 |
+
$('#shapes-cont').html(
|
1943 |
+
"<div id='no-results'>Sorry, we couldn't find any results for "" +
|
1944 |
+
encodeURIComponent(value) +
|
1945 |
+
'". Please try a different query.</div>'
|
1946 |
+
);
|
1947 |
+
}
|
1948 |
+
}
|
1949 |
+
} else if ($('#text-tool').hasClass('tool-active')) {
|
1950 |
+
if (value == '') {
|
1951 |
+
$('#browser-container').html(text_browser);
|
1952 |
+
populateGrid('text-tool');
|
1953 |
+
} else {
|
1954 |
+
$('#shapes-cont').html('');
|
1955 |
+
$('.row-title').remove();
|
1956 |
+
var flag = false;
|
1957 |
+
fonts.forEach(function (font) {
|
1958 |
+
if (font.toLowerCase().indexOf(value) > -1) {
|
1959 |
+
flag = true;
|
1960 |
+
WebFont.load({
|
1961 |
+
google: {
|
1962 |
+
families: [font],
|
1963 |
+
},
|
1964 |
+
});
|
1965 |
+
$('#shapes-cont').append(
|
1966 |
+
"<div id='item-text' class='add-text noselect' data-font='" +
|
1967 |
+
font +
|
1968 |
+
"' style='font-family: " +
|
1969 |
+
font +
|
1970 |
+
"'>" +
|
1971 |
+
font +
|
1972 |
+
'</div>'
|
1973 |
+
);
|
1974 |
+
}
|
1975 |
+
});
|
1976 |
+
if (!flag) {
|
1977 |
+
$('#shapes-cont').html(
|
1978 |
+
"<div id='no-results'>Sorry, we couldn't find any results for "" +
|
1979 |
+
encodeURIComponent(value) +
|
1980 |
+
'". Please try a different query.</div>'
|
1981 |
+
);
|
1982 |
+
}
|
1983 |
+
}
|
1984 |
+
}
|
1985 |
+
}
|
1986 |
+
|
1987 |
+
function searchCategory() {
|
1988 |
+
$('#browser-search input').val($(this).attr('data-name'));
|
1989 |
+
$('#delete-search').addClass('show-delete');
|
1990 |
+
search();
|
1991 |
+
$('#pixabay').addClass('hide-pixabay');
|
1992 |
+
}
|
1993 |
+
|
1994 |
+
function deleteSearch() {
|
1995 |
+
$('#browser-search input').val('');
|
1996 |
+
$('#delete-search').removeClass('show-delete');
|
1997 |
+
if ($('#shape-tool').hasClass('tool-active')) {
|
1998 |
+
$('#shapes-cont').html(
|
1999 |
+
'<p class="row-title">Shapes</p><div class="gallery-row" id="shapes-row"></div><p class="row-title">Emojis</p><div class="gallery-row" id="emojis-row"></div>'
|
2000 |
+
);
|
2001 |
+
populateGrid('shape-tool');
|
2002 |
+
} else if ($('#image-tool').hasClass('tool-active')) {
|
2003 |
+
$('#images-grid').html('');
|
2004 |
+
$('#landing').removeClass('hide-landing');
|
2005 |
+
$('#pixabay').removeClass('hide-pixabay');
|
2006 |
+
} else if ($('#video-tool').hasClass('tool-active')) {
|
2007 |
+
$('#images-grid').html('');
|
2008 |
+
$('#landing').removeClass('hide-landing');
|
2009 |
+
$('#pixabay').removeClass('hide-pixabay');
|
2010 |
+
} else if ($('#text-tool').hasClass('tool-active')) {
|
2011 |
+
$('#browser-container').html(text_browser);
|
2012 |
+
populateGrid('text-tool');
|
2013 |
+
}
|
2014 |
+
}
|
2015 |
+
$(document).on('click', '#delete-search', deleteSearch);
|
2016 |
+
$(document).on('input', '#browser-search input', searchInput);
|
2017 |
+
$(document).on('click', '#search-button', search);
|
2018 |
+
$(document).on('click', '.category', searchCategory);
|
2019 |
+
|
2020 |
+
function replaceAudioBackground() {
|
2021 |
+
var src = $(this).attr('data-src');
|
2022 |
+
newAudioLayer(src);
|
2023 |
+
/*
|
2024 |
+
if ($(this).hasClass("audio-item-active")) {
|
2025 |
+
background_audio = false;
|
2026 |
+
background_key = false;
|
2027 |
+
$(this).removeClass("audio-item-active");
|
2028 |
+
save();
|
2029 |
+
} else {
|
2030 |
+
var src = $(this).attr("data-src");
|
2031 |
+
if (background_audio != false) {
|
2032 |
+
$("#audio-upload-button").removeClass("remove-audio");
|
2033 |
+
$("#audio-upload-button").html('<img src="assets/upload.svg"> Upload audio');
|
2034 |
+
}
|
2035 |
+
db.collection("projects").doc({id: 1}).update({
|
2036 |
+
audiosrc: src,
|
2037 |
+
});
|
2038 |
+
background_audio = new Audio(src);
|
2039 |
+
background_audio.crossOrigin = "anonymous";
|
2040 |
+
background_key = src;
|
2041 |
+
save();
|
2042 |
+
$(this).addClass("audio-item-active");
|
2043 |
+
}
|
2044 |
+
*/
|
2045 |
+
}
|
2046 |
+
$(document).on('click', '.audio-item', replaceAudioBackground);
|
2047 |
+
|
2048 |
+
function previewAudioBackground(e) {
|
2049 |
+
e.preventDefault();
|
2050 |
+
e.stopPropagation();
|
2051 |
+
var src = $(this).parent().attr('data-src');
|
2052 |
+
if ($(this).find('img').attr('src') == 'assets/play-button.svg') {
|
2053 |
+
temp_audio = new Audio(src);
|
2054 |
+
temp_audio.crossOrigin = 'anonymous';
|
2055 |
+
temp_audio.currentTime = 0;
|
2056 |
+
temp_audio.play();
|
2057 |
+
$(this).find('img').attr('src', 'assets/pause-button.svg');
|
2058 |
+
} else {
|
2059 |
+
if (temp_audio != false) {
|
2060 |
+
temp_audio.pause();
|
2061 |
+
}
|
2062 |
+
$(this).find('img').attr('src', 'assets/play-button.svg');
|
2063 |
+
}
|
2064 |
+
}
|
2065 |
+
$(document).on('click', '.audio-preview', previewAudioBackground);
|
2066 |
+
|
2067 |
+
/* Filters options */
|
2068 |
+
function checkFilter() {
|
2069 |
+
resetFilters();
|
2070 |
+
if (canvas.getActiveObject()) {
|
2071 |
+
var obj = canvas.getActiveObject();
|
2072 |
+
if (
|
2073 |
+
canvas.getActiveObjects().length == 1 &&
|
2074 |
+
(obj.type == 'image' || obj.type == 'video')
|
2075 |
+
) {
|
2076 |
+
var value = 'none';
|
2077 |
+
if (obj.filters.length > 0) {
|
2078 |
+
obj.filters.forEach(function (filter) {
|
2079 |
+
if (
|
2080 |
+
filter.type == 'BlackWhite' ||
|
2081 |
+
filter.type == 'Invert' ||
|
2082 |
+
filter.type == 'Sepia' ||
|
2083 |
+
filter.type == 'Kodachrome' ||
|
2084 |
+
filter.type == 'Polaroid' ||
|
2085 |
+
filter.type == 'Technicolor' ||
|
2086 |
+
filter.type == 'Brownie' ||
|
2087 |
+
filter.type == 'Vintage'
|
2088 |
+
) {
|
2089 |
+
value = filter.type;
|
2090 |
+
} else if (filter.type == 'Brightness') {
|
2091 |
+
sliders
|
2092 |
+
.find((x) => x.name == 'filter-brightness')
|
2093 |
+
.slider.setValue(filter.brightness * 100);
|
2094 |
+
} else if (filter.type == 'Contrast') {
|
2095 |
+
sliders
|
2096 |
+
.find((x) => x.name == 'filter-contrast')
|
2097 |
+
.slider.setValue(filter.contrast * 100);
|
2098 |
+
} else if (filter.type == 'Vibrance') {
|
2099 |
+
sliders
|
2100 |
+
.find((x) => x.name == 'filter-vibrance')
|
2101 |
+
.slider.setValue(filter.vibrance * 100);
|
2102 |
+
} else if (filter.type == 'Saturation') {
|
2103 |
+
sliders
|
2104 |
+
.find((x) => x.name == 'filter-saturation')
|
2105 |
+
.slider.setValue(filter.saturation * 100);
|
2106 |
+
} else if (filter.type == 'HueRotation') {
|
2107 |
+
sliders
|
2108 |
+
.find((x) => x.name == 'filter-hue')
|
2109 |
+
.slider.setValue(filter.rotation * 100);
|
2110 |
+
} else if (filter.type == 'Blur') {
|
2111 |
+
blurslider.setValue(filter.blur * 100);
|
2112 |
+
} else if (filter.type == 'Noise') {
|
2113 |
+
noiseslider.setValue(filter.noise);
|
2114 |
+
}
|
2115 |
+
$('#filters-list').val(value);
|
2116 |
+
$('#filters-list').niceSelect('update');
|
2117 |
+
});
|
2118 |
+
} else {
|
2119 |
+
$('#filters-list').val(value);
|
2120 |
+
$('#filters-list').niceSelect('update');
|
2121 |
+
}
|
2122 |
+
}
|
2123 |
+
}
|
2124 |
+
}
|
2125 |
+
function clearFilters() {
|
2126 |
+
if (canvas.getActiveObject()) {
|
2127 |
+
var obj = canvas.getActiveObject();
|
2128 |
+
obj.filters = $.grep(obj.filters, function (i) {
|
2129 |
+
return (
|
2130 |
+
i.type != 'BlackWhite' &&
|
2131 |
+
i.type != 'Invert' &&
|
2132 |
+
i.type != 'Sepia' &&
|
2133 |
+
i.type != 'Kodachrome' &&
|
2134 |
+
i.type != 'Polaroid' &&
|
2135 |
+
i.type != 'Technicolor' &&
|
2136 |
+
i.type != 'Brownie' &&
|
2137 |
+
i.type != 'Vintage'
|
2138 |
+
);
|
2139 |
+
});
|
2140 |
+
canvas.renderAll();
|
2141 |
+
}
|
2142 |
+
}
|
2143 |
+
function applyFilter(name) {
|
2144 |
+
if (canvas.getActiveObject()) {
|
2145 |
+
var obj = canvas.getActiveObject();
|
2146 |
+
if (name == 'Sepia') {
|
2147 |
+
obj.filters.push(new f.Sepia());
|
2148 |
+
} else if (name == 'Invert') {
|
2149 |
+
obj.filters.push(new f.Invert());
|
2150 |
+
} else if (name == 'BlackWhite') {
|
2151 |
+
obj.filters.push(new f.BlackWhite());
|
2152 |
+
} else if (name == 'Kodachrome') {
|
2153 |
+
obj.filters.push(new f.Kodachrome());
|
2154 |
+
} else if (name == 'Polaroid') {
|
2155 |
+
obj.filters.push(new f.Polaroid());
|
2156 |
+
} else if (name == 'Technicolor') {
|
2157 |
+
obj.filters.push(new f.Technicolor());
|
2158 |
+
} else if (name == 'Vintage') {
|
2159 |
+
obj.filters.push(new f.Vintage());
|
2160 |
+
} else if (name == 'Brownie') {
|
2161 |
+
obj.filters.push(new f.Brownie());
|
2162 |
+
}
|
2163 |
+
obj.applyFilters();
|
2164 |
+
canvas.renderAll();
|
2165 |
+
save();
|
2166 |
+
}
|
2167 |
+
}
|
2168 |
+
function updateMediaFilters() {
|
2169 |
+
var value = $(this).val();
|
2170 |
+
if (canvas.getActiveObject()) {
|
2171 |
+
clearFilters();
|
2172 |
+
applyFilter(value);
|
2173 |
+
}
|
2174 |
+
}
|
2175 |
+
$(document).on('change', '#filters select', updateMediaFilters);
|
2176 |
+
|
2177 |
+
function resetFilters() {
|
2178 |
+
if (canvas.getActiveObject()) {
|
2179 |
+
var object = canvas.getActiveObject();
|
2180 |
+
if (object.filters) {
|
2181 |
+
if (!object.filters.find((x) => x.type == 'Blur')) {
|
2182 |
+
blurslider.setValue(0);
|
2183 |
+
}
|
2184 |
+
if (!object.filters.find((x) => x.type == 'Noise')) {
|
2185 |
+
noiseslider.setValue(0);
|
2186 |
+
}
|
2187 |
+
if (object.filters.length > 0) {
|
2188 |
+
sliders.forEach(function (slider) {
|
2189 |
+
var name = '';
|
2190 |
+
if (slider.name == 'filter-hue') {
|
2191 |
+
name = 'HueRotation';
|
2192 |
+
} else if (slider.name == 'filter-brightness') {
|
2193 |
+
name = 'Brightness';
|
2194 |
+
} else if (slider.name == 'filter-vibrance') {
|
2195 |
+
name = 'Vibrance';
|
2196 |
+
} else if (slider.name == 'filter-contrast') {
|
2197 |
+
name = 'Contrast';
|
2198 |
+
} else if (slider.name == 'filter-saturation') {
|
2199 |
+
name = 'Saturation';
|
2200 |
+
}
|
2201 |
+
if (!object.filters.find((x) => x.type == name)) {
|
2202 |
+
slider.slider.setValue(0);
|
2203 |
+
}
|
2204 |
+
});
|
2205 |
+
} else {
|
2206 |
+
sliders.forEach(function (slider) {
|
2207 |
+
slider.slider.setValue(0);
|
2208 |
+
});
|
2209 |
+
}
|
2210 |
+
} else {
|
2211 |
+
sliders.forEach(function (slider) {
|
2212 |
+
slider.slider.setValue(0);
|
2213 |
+
});
|
2214 |
+
}
|
2215 |
+
}
|
2216 |
+
}
|
2217 |
+
function removeFilters() {
|
2218 |
+
sliders.forEach(function (slider) {
|
2219 |
+
slider.slider.setValue(0);
|
2220 |
+
});
|
2221 |
+
}
|
2222 |
+
$(document).on('click', '#reset-filters', removeFilters);
|
2223 |
+
|
2224 |
+
function updateChromaValues() {
|
2225 |
+
if (canvas.getActiveObject()) {
|
2226 |
+
var obj = canvas.getActiveObject();
|
2227 |
+
if ($('.status-active').attr('id') == 'status-on') {
|
2228 |
+
if (obj.filters.find((x) => x.type == 'RemoveColor')) {
|
2229 |
+
obj.filters.find((x) => x.type == 'RemoveColor').distance =
|
2230 |
+
chromaslider.getValue() / 100;
|
2231 |
+
obj.filters.find((x) => x.type == 'RemoveColor').color = $(
|
2232 |
+
'#chroma-color input'
|
2233 |
+
).val();
|
2234 |
+
} else {
|
2235 |
+
obj.filters.push(
|
2236 |
+
new f.RemoveColor({
|
2237 |
+
distance: chromaslider.getValue() / 100,
|
2238 |
+
color: $('#chroma-color input').val(),
|
2239 |
+
})
|
2240 |
+
);
|
2241 |
+
}
|
2242 |
+
obj.applyFilters();
|
2243 |
+
canvas.renderAll();
|
2244 |
+
save();
|
2245 |
+
} else {
|
2246 |
+
if (obj.filters.find((x) => x.type == 'RemoveColor')) {
|
2247 |
+
obj.filters = $.grep(obj.filters, function (i) {
|
2248 |
+
return i.type != 'RemoveColor';
|
2249 |
+
});
|
2250 |
+
obj.applyFilters();
|
2251 |
+
canvas.renderAll();
|
2252 |
+
save();
|
2253 |
+
}
|
2254 |
+
}
|
2255 |
+
}
|
2256 |
+
}
|
2257 |
+
|
2258 |
+
function updateChromaUI() {
|
2259 |
+
if (canvas.getActiveObject()) {
|
2260 |
+
var obj = canvas.getActiveObject();
|
2261 |
+
if (obj.filters) {
|
2262 |
+
if (obj.filters.length > 0) {
|
2263 |
+
if (obj.filters.find((x) => x.type == 'RemoveColor')) {
|
2264 |
+
$('.status-active').removeClass('status-active');
|
2265 |
+
$('#status-on').addClass('status-active');
|
2266 |
+
chromaslider.setValue(
|
2267 |
+
obj.filters.find((x) => x.type == 'RemoveColor').distance
|
2268 |
+
);
|
2269 |
+
$('#chroma-color input').val(
|
2270 |
+
obj.filters.find((x) => x.type == 'RemoveColor').color
|
2271 |
+
);
|
2272 |
+
$('#color-chroma-side').css(
|
2273 |
+
'background-color',
|
2274 |
+
obj.filters.find((x) => x.type == 'RemoveColor').color
|
2275 |
+
);
|
2276 |
+
} else {
|
2277 |
+
$('.status-active').removeClass('status-active');
|
2278 |
+
$('#status-off').addClass('status-active');
|
2279 |
+
chromaslider.setValue(1);
|
2280 |
+
$('#chroma-color input').val('#FFFFFF');
|
2281 |
+
$('#color-chroma-side').css('background-color', '#FFFFF');
|
2282 |
+
}
|
2283 |
+
}
|
2284 |
+
}
|
2285 |
+
}
|
2286 |
+
}
|
2287 |
+
|
2288 |
+
function toggleChroma() {
|
2289 |
+
if (canvas.getActiveObject()) {
|
2290 |
+
$('.status-active').removeClass('status-active');
|
2291 |
+
$(this).addClass('status-active');
|
2292 |
+
updateChromaValues();
|
2293 |
+
}
|
2294 |
+
}
|
2295 |
+
|
2296 |
+
$(document).on(
|
2297 |
+
'click',
|
2298 |
+
'.status-trigger:not(.status-active)',
|
2299 |
+
toggleChroma
|
2300 |
+
);
|
2301 |
+
|
2302 |
+
async function getColor() {
|
2303 |
+
try {
|
2304 |
+
const selectedColor = await eyeDropper.open();
|
2305 |
+
colormode = 'chroma';
|
2306 |
+
o_fill.setColor(selectedColor.sRGBHex);
|
2307 |
+
} catch (err) {}
|
2308 |
+
}
|
2309 |
+
$(document).on('click', '.pcr-current-color', getColor);
|
2310 |
+
|
2311 |
+
function closeFilters() {
|
2312 |
+
$('.show-filters').removeClass('show-filters');
|
2313 |
+
}
|
2314 |
+
|
2315 |
+
function openFilters() {
|
2316 |
+
$('#filters-parent').addClass('show-filters');
|
2317 |
+
}
|
2318 |
+
|
2319 |
+
$(document).on('click', '#filters-button', openFilters);
|
2320 |
+
$(document).on('click', '#filters-close', closeFilters);
|
2321 |
+
|
2322 |
+
function toggleSpeed(e) {
|
2323 |
+
e.stopPropagation();
|
2324 |
+
e.preventDefault();
|
2325 |
+
$('#speed-settings').toggleClass('show-speed');
|
2326 |
+
$('#speed-arrow').toggleClass('arrow-on');
|
2327 |
+
}
|
2328 |
+
function setSpeed(e) {
|
2329 |
+
e.stopPropagation();
|
2330 |
+
e.preventDefault();
|
2331 |
+
speed = parseFloat($(this).attr('data-speed'));
|
2332 |
+
$('#speed span').html($(this).html());
|
2333 |
+
toggleSpeed(e);
|
2334 |
+
save();
|
2335 |
+
}
|
2336 |
+
|
2337 |
+
$(document).on('click', '.speed', setSpeed);
|
2338 |
+
$(document).on('click', '#speed', toggleSpeed);
|
2339 |
+
|
2340 |
+
function showMore() {
|
2341 |
+
$('#more-over').css(
|
2342 |
+
'top',
|
2343 |
+
$('#more-tool').offset().top + 5 - $('#more-over').height() / 4
|
2344 |
+
);
|
2345 |
+
$('#more-over').addClass('more-show');
|
2346 |
+
}
|
2347 |
+
function hideMore() {
|
2348 |
+
$('#more-over').removeClass('more-show');
|
2349 |
+
}
|
2350 |
+
|
2351 |
+
function handleLottieUpload() {
|
2352 |
+
var filething = $('#filepick3').get(0).files;
|
2353 |
+
var reader = new FileReader();
|
2354 |
+
reader.onload = function (event) {
|
2355 |
+
newLottieAnimation(
|
2356 |
+
artboard.get('left') + artboard.get('width') / 2,
|
2357 |
+
artboard.get('top') + artboard.get('height') / 2,
|
2358 |
+
event.target.result
|
2359 |
+
);
|
2360 |
+
};
|
2361 |
+
reader.readAsDataURL(filething.item(0));
|
2362 |
+
}
|
2363 |
+
|
2364 |
+
$(document).on('change', '#filepick3', handleLottieUpload);
|
2365 |
+
|
2366 |
+
function uploadLottie() {
|
2367 |
+
$('#filepick3').click();
|
2368 |
+
}
|
2369 |
+
$(document).on('click', '#upload-lottie', uploadLottie);
|
js/webm-writer2.js
ADDED
@@ -0,0 +1,1165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* A tool for presenting an ArrayBuffer as a stream for writing some simple data
|
3 |
+
* types.
|
4 |
+
*
|
5 |
+
* By Nicholas Sherlock, with updates from jimbankoski
|
6 |
+
*
|
7 |
+
* - make it work off frames with timestamps from webcodecs
|
8 |
+
* - make it write via Native File IO apis instead of FileWriter
|
9 |
+
* - remove alpha and transparency
|
10 |
+
* -
|
11 |
+
*
|
12 |
+
* Released under the WTFPLv2 https://en.wikipedia.org/wiki/WTFPL
|
13 |
+
*/
|
14 |
+
|
15 |
+
'use strict';
|
16 |
+
|
17 |
+
(function() {
|
18 |
+
/*
|
19 |
+
* Create an ArrayBuffer of the given length and present it as a writable stream
|
20 |
+
* with methods for writing data in different formats.
|
21 |
+
*/
|
22 |
+
let ArrayBufferDataStream = function(length) {
|
23 |
+
this.data = new Uint8Array(length);
|
24 |
+
this.pos = 0;
|
25 |
+
};
|
26 |
+
|
27 |
+
ArrayBufferDataStream.prototype.seek = function(toOffset) {
|
28 |
+
this.pos = toOffset;
|
29 |
+
};
|
30 |
+
|
31 |
+
ArrayBufferDataStream.prototype.writeBytes = function(arr) {
|
32 |
+
for (let i = 0; i < arr.length; i++) {
|
33 |
+
this.data[this.pos++] = arr[i];
|
34 |
+
}
|
35 |
+
};
|
36 |
+
|
37 |
+
ArrayBufferDataStream.prototype.writeByte = function(b) {
|
38 |
+
this.data[this.pos++] = b;
|
39 |
+
};
|
40 |
+
|
41 |
+
// Synonym:
|
42 |
+
ArrayBufferDataStream.prototype.writeU8 =
|
43 |
+
ArrayBufferDataStream.prototype.writeByte;
|
44 |
+
|
45 |
+
ArrayBufferDataStream.prototype.writeU16BE = function(u) {
|
46 |
+
this.data[this.pos++] = u >> 8;
|
47 |
+
this.data[this.pos++] = u;
|
48 |
+
};
|
49 |
+
|
50 |
+
ArrayBufferDataStream.prototype.writeDoubleBE = function(d) {
|
51 |
+
let bytes = new Uint8Array(new Float64Array([d]).buffer);
|
52 |
+
|
53 |
+
for (let i = bytes.length - 1; i >= 0; i--) {
|
54 |
+
this.writeByte(bytes[i]);
|
55 |
+
}
|
56 |
+
};
|
57 |
+
|
58 |
+
ArrayBufferDataStream.prototype.writeFloatBE = function(d) {
|
59 |
+
let bytes = new Uint8Array(new Float32Array([d]).buffer);
|
60 |
+
|
61 |
+
for (let i = bytes.length - 1; i >= 0; i--) {
|
62 |
+
this.writeByte(bytes[i]);
|
63 |
+
}
|
64 |
+
};
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Write an ASCII string to the stream
|
68 |
+
*/
|
69 |
+
ArrayBufferDataStream.prototype.writeString = function(s) {
|
70 |
+
for (let i = 0; i < s.length; i++) {
|
71 |
+
this.data[this.pos++] = s.charCodeAt(i);
|
72 |
+
}
|
73 |
+
};
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Write the given 32-bit integer to the stream as an EBML variable-length
|
77 |
+
* integer using the given byte width (use measureEBMLVarInt).
|
78 |
+
*
|
79 |
+
* No error checking is performed to ensure that the supplied width is correct
|
80 |
+
* for the integer.
|
81 |
+
*
|
82 |
+
* @param i Integer to be written
|
83 |
+
* @param width Number of bytes to write to the stream
|
84 |
+
*/
|
85 |
+
ArrayBufferDataStream.prototype.writeEBMLVarIntWidth = function(i, width) {
|
86 |
+
switch (width) {
|
87 |
+
case 1:
|
88 |
+
this.writeU8((1 << 7) | i);
|
89 |
+
break;
|
90 |
+
case 2:
|
91 |
+
this.writeU8((1 << 6) | (i >> 8));
|
92 |
+
this.writeU8(i);
|
93 |
+
break;
|
94 |
+
case 3:
|
95 |
+
this.writeU8((1 << 5) | (i >> 16));
|
96 |
+
this.writeU8(i >> 8);
|
97 |
+
this.writeU8(i);
|
98 |
+
break;
|
99 |
+
case 4:
|
100 |
+
this.writeU8((1 << 4) | (i >> 24));
|
101 |
+
this.writeU8(i >> 16);
|
102 |
+
this.writeU8(i >> 8);
|
103 |
+
this.writeU8(i);
|
104 |
+
break;
|
105 |
+
case 5:
|
106 |
+
/*
|
107 |
+
* JavaScript converts its doubles to 32-bit integers for bitwise
|
108 |
+
* operations, so we need to do a division by 2^32 instead of a
|
109 |
+
* right-shift of 32 to retain those top 3 bits
|
110 |
+
*/
|
111 |
+
this.writeU8((1 << 3) | ((i / 4294967296) & 0x7));
|
112 |
+
this.writeU8(i >> 24);
|
113 |
+
this.writeU8(i >> 16);
|
114 |
+
this.writeU8(i >> 8);
|
115 |
+
this.writeU8(i);
|
116 |
+
break;
|
117 |
+
default:
|
118 |
+
throw new Error('Bad EBML VINT size ' + width);
|
119 |
+
}
|
120 |
+
};
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Return the number of bytes needed to encode the given integer as an EBML
|
124 |
+
* VINT.
|
125 |
+
*/
|
126 |
+
ArrayBufferDataStream.prototype.measureEBMLVarInt = function(val) {
|
127 |
+
if (val < (1 << 7) - 1) {
|
128 |
+
/* Top bit is set, leaving 7 bits to hold the integer, but we can't store
|
129 |
+
* 127 because "all bits set to one" is a reserved value. Same thing for the
|
130 |
+
* other cases below:
|
131 |
+
*/
|
132 |
+
return 1;
|
133 |
+
} else if (val < (1 << 14) - 1) {
|
134 |
+
return 2;
|
135 |
+
} else if (val < (1 << 21) - 1) {
|
136 |
+
return 3;
|
137 |
+
} else if (val < (1 << 28) - 1) {
|
138 |
+
return 4;
|
139 |
+
} else if (val < 34359738367) { // 2 ^ 35 - 1 (can address 32GB)
|
140 |
+
return 5;
|
141 |
+
} else {
|
142 |
+
throw new Error('EBML VINT size not supported ' + val);
|
143 |
+
}
|
144 |
+
};
|
145 |
+
|
146 |
+
ArrayBufferDataStream.prototype.writeEBMLVarInt = function(i) {
|
147 |
+
this.writeEBMLVarIntWidth(i, this.measureEBMLVarInt(i));
|
148 |
+
};
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Write the given unsigned 32-bit integer to the stream in big-endian order
|
152 |
+
* using the given byte width. No error checking is performed to ensure that the
|
153 |
+
* supplied width is correct for the integer.
|
154 |
+
*
|
155 |
+
* Omit the width parameter to have it determined automatically for you.
|
156 |
+
*
|
157 |
+
* @param u Unsigned integer to be written
|
158 |
+
* @param width Number of bytes to write to the stream
|
159 |
+
*/
|
160 |
+
ArrayBufferDataStream.prototype.writeUnsignedIntBE = function(u, width) {
|
161 |
+
if (width === undefined) {
|
162 |
+
width = this.measureUnsignedInt(u);
|
163 |
+
}
|
164 |
+
|
165 |
+
// Each case falls through:
|
166 |
+
switch (width) {
|
167 |
+
case 5:
|
168 |
+
this.writeU8(
|
169 |
+
Math.floor(u / 4294967296)); // Need to use division to access >32
|
170 |
+
// bits of floating point var
|
171 |
+
case 4:
|
172 |
+
this.writeU8(u >> 24);
|
173 |
+
case 3:
|
174 |
+
this.writeU8(u >> 16);
|
175 |
+
case 2:
|
176 |
+
this.writeU8(u >> 8);
|
177 |
+
case 1:
|
178 |
+
this.writeU8(u);
|
179 |
+
break;
|
180 |
+
default:
|
181 |
+
throw new Error('Bad UINT size ' + width);
|
182 |
+
}
|
183 |
+
};
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Return the number of bytes needed to hold the non-zero bits of the given
|
187 |
+
* unsigned integer.
|
188 |
+
*/
|
189 |
+
ArrayBufferDataStream.prototype.measureUnsignedInt = function(val) {
|
190 |
+
// Force to 32-bit unsigned integer
|
191 |
+
if (val < (1 << 8)) {
|
192 |
+
return 1;
|
193 |
+
} else if (val < (1 << 16)) {
|
194 |
+
return 2;
|
195 |
+
} else if (val < (1 << 24)) {
|
196 |
+
return 3;
|
197 |
+
} else if (val < 4294967296) {
|
198 |
+
return 4;
|
199 |
+
} else {
|
200 |
+
return 5;
|
201 |
+
}
|
202 |
+
};
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Return a view on the portion of the buffer from the beginning to the current
|
206 |
+
* seek position as a Uint8Array.
|
207 |
+
*/
|
208 |
+
ArrayBufferDataStream.prototype.getAsDataArray = function() {
|
209 |
+
if (this.pos < this.data.byteLength) {
|
210 |
+
return this.data.subarray(0, this.pos);
|
211 |
+
} else if (this.pos == this.data.byteLength) {
|
212 |
+
return this.data;
|
213 |
+
} else {
|
214 |
+
throw new Error('ArrayBufferDataStream\'s pos lies beyond end of buffer');
|
215 |
+
}
|
216 |
+
};
|
217 |
+
|
218 |
+
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
219 |
+
module.exports = ArrayBufferDataStream;
|
220 |
+
} else {
|
221 |
+
self.ArrayBufferDataStream = ArrayBufferDataStream;
|
222 |
+
}
|
223 |
+
}());
|
224 |
+
'use strict';
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Allows a series of Blob-convertible objects (ArrayBuffer, Blob, String, etc)
|
228 |
+
* to be added to a buffer. Seeking and overwriting of blobs is allowed.
|
229 |
+
*
|
230 |
+
* You can supply a FileWriter, in which case the BlobBuffer is just used as
|
231 |
+
* temporary storage before it writes it through to the disk.
|
232 |
+
*
|
233 |
+
* By Nicholas Sherlock
|
234 |
+
*
|
235 |
+
* Released under the WTFPLv2 https://en.wikipedia.org/wiki/WTFPL
|
236 |
+
*/
|
237 |
+
(function() {
|
238 |
+
let BlobBuffer = function(fs) {
|
239 |
+
return function(destination) {
|
240 |
+
let buffer = [], writePromise = Promise.resolve(), fileWriter = null,
|
241 |
+
fd = null;
|
242 |
+
|
243 |
+
if (destination &&
|
244 |
+
destination.constructor.name === 'FileSystemWritableFileStream') {
|
245 |
+
fileWriter = destination;
|
246 |
+
} else if (fs && destination) {
|
247 |
+
fd = destination;
|
248 |
+
}
|
249 |
+
|
250 |
+
// Current seek offset
|
251 |
+
this.pos = 0;
|
252 |
+
|
253 |
+
// One more than the index of the highest byte ever written
|
254 |
+
this.length = 0;
|
255 |
+
|
256 |
+
// Returns a promise that converts the blob to an ArrayBuffer
|
257 |
+
function readBlobAsBuffer(blob) {
|
258 |
+
return new Promise(function(resolve, reject) {
|
259 |
+
let reader = new FileReader();
|
260 |
+
|
261 |
+
reader.addEventListener('loadend', function() {
|
262 |
+
resolve(reader.result);
|
263 |
+
});
|
264 |
+
|
265 |
+
reader.readAsArrayBuffer(blob);
|
266 |
+
});
|
267 |
+
}
|
268 |
+
|
269 |
+
function convertToUint8Array(thing) {
|
270 |
+
return new Promise(function(resolve, reject) {
|
271 |
+
if (thing instanceof Uint8Array) {
|
272 |
+
resolve(thing);
|
273 |
+
} else if (thing instanceof ArrayBuffer || ArrayBuffer.isView(thing)) {
|
274 |
+
resolve(new Uint8Array(thing));
|
275 |
+
} else if (thing instanceof Blob) {
|
276 |
+
resolve(readBlobAsBuffer(thing).then(function(buffer) {
|
277 |
+
return new Uint8Array(buffer);
|
278 |
+
}));
|
279 |
+
} else {
|
280 |
+
// Assume that Blob will know how to read this thing
|
281 |
+
resolve(readBlobAsBuffer(new Blob([thing])).then(function(buffer) {
|
282 |
+
return new Uint8Array(buffer);
|
283 |
+
}));
|
284 |
+
}
|
285 |
+
});
|
286 |
+
}
|
287 |
+
|
288 |
+
function measureData(data) {
|
289 |
+
let result = data.byteLength || data.length || data.size;
|
290 |
+
|
291 |
+
if (!Number.isInteger(result)) {
|
292 |
+
throw new Error('Failed to determine size of element');
|
293 |
+
}
|
294 |
+
|
295 |
+
return result;
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Seek to the given absolute offset.
|
300 |
+
*
|
301 |
+
* You may not seek beyond the end of the file (this would create a hole
|
302 |
+
* and/or allow blocks to be written in non- sequential order, which isn't
|
303 |
+
* currently supported by the memory buffer backend).
|
304 |
+
*/
|
305 |
+
this.seek = function(offset) {
|
306 |
+
if (offset < 0) {
|
307 |
+
throw new Error('Offset may not be negative');
|
308 |
+
}
|
309 |
+
|
310 |
+
if (isNaN(offset)) {
|
311 |
+
throw new Error('Offset may not be NaN');
|
312 |
+
}
|
313 |
+
|
314 |
+
if (offset > this.length) {
|
315 |
+
throw new Error('Seeking beyond the end of file is not allowed');
|
316 |
+
}
|
317 |
+
|
318 |
+
this.pos = offset;
|
319 |
+
};
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Write the Blob-convertible data to the buffer at the current seek
|
323 |
+
* position.
|
324 |
+
*
|
325 |
+
* Note: If overwriting existing data, the write must not cross preexisting
|
326 |
+
* block boundaries (written data must be fully contained by the extent of a
|
327 |
+
* previous write).
|
328 |
+
*/
|
329 |
+
this.write = function(data) {
|
330 |
+
let newEntry = {offset: this.pos, data: data, length: measureData(data)},
|
331 |
+
isAppend = newEntry.offset >= this.length;
|
332 |
+
|
333 |
+
this.pos += newEntry.length;
|
334 |
+
this.length = Math.max(this.length, this.pos);
|
335 |
+
|
336 |
+
// After previous writes complete, perform our write
|
337 |
+
writePromise = writePromise.then(async function() {
|
338 |
+
if (fd) {
|
339 |
+
return new Promise(function(resolve, reject) {
|
340 |
+
convertToUint8Array(newEntry.data).then(function(dataArray) {
|
341 |
+
let totalWritten = 0, buffer = Buffer.from(dataArray.buffer),
|
342 |
+
|
343 |
+
handleWriteComplete = function(err, written, buffer) {
|
344 |
+
totalWritten += written;
|
345 |
+
|
346 |
+
if (totalWritten >= buffer.length) {
|
347 |
+
resolve();
|
348 |
+
} else {
|
349 |
+
// We still have more to write...
|
350 |
+
fs.write(
|
351 |
+
fd, buffer, totalWritten,
|
352 |
+
buffer.length - totalWritten,
|
353 |
+
newEntry.offset + totalWritten, handleWriteComplete);
|
354 |
+
}
|
355 |
+
};
|
356 |
+
|
357 |
+
fs.write(
|
358 |
+
fd, buffer, 0, buffer.length, newEntry.offset,
|
359 |
+
handleWriteComplete);
|
360 |
+
});
|
361 |
+
});
|
362 |
+
} else if (fileWriter) {
|
363 |
+
return new Promise(function(resolve, reject) {
|
364 |
+
fileWriter.seek(newEntry.offset)
|
365 |
+
.then(() => {fileWriter.write(new Blob([newEntry.data]))})
|
366 |
+
.then(() => {resolve();
|
367 |
+
})
|
368 |
+
});
|
369 |
+
} else if (!isAppend) {
|
370 |
+
// We might be modifying a write that was already buffered in memory.
|
371 |
+
|
372 |
+
// Slow linear search to find a block we might be overwriting
|
373 |
+
for (let i = 0; i < buffer.length; i++) {
|
374 |
+
let entry = buffer[i];
|
375 |
+
|
376 |
+
// If our new entry overlaps the old one in any way...
|
377 |
+
if (!(newEntry.offset + newEntry.length <= entry.offset ||
|
378 |
+
newEntry.offset >= entry.offset + entry.length)) {
|
379 |
+
if (newEntry.offset < entry.offset ||
|
380 |
+
newEntry.offset + newEntry.length >
|
381 |
+
entry.offset + entry.length) {
|
382 |
+
throw new Error('Overwrite crosses blob boundaries');
|
383 |
+
}
|
384 |
+
|
385 |
+
if (newEntry.offset == entry.offset &&
|
386 |
+
newEntry.length == entry.length) {
|
387 |
+
// We overwrote the entire block
|
388 |
+
entry.data = newEntry.data;
|
389 |
+
|
390 |
+
// We're done
|
391 |
+
return;
|
392 |
+
} else {
|
393 |
+
return convertToUint8Array(entry.data)
|
394 |
+
.then(function(entryArray) {
|
395 |
+
entry.data = entryArray;
|
396 |
+
|
397 |
+
return convertToUint8Array(newEntry.data);
|
398 |
+
})
|
399 |
+
.then(function(newEntryArray) {
|
400 |
+
newEntry.data = newEntryArray;
|
401 |
+
|
402 |
+
entry.data.set(
|
403 |
+
newEntry.data, newEntry.offset - entry.offset);
|
404 |
+
});
|
405 |
+
}
|
406 |
+
}
|
407 |
+
}
|
408 |
+
// Else fall through to do a simple append, as we didn't overwrite any
|
409 |
+
// pre-existing blocks
|
410 |
+
}
|
411 |
+
|
412 |
+
buffer.push(newEntry);
|
413 |
+
});
|
414 |
+
};
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Finish all writes to the buffer, returning a promise that signals when
|
418 |
+
* that is complete.
|
419 |
+
*
|
420 |
+
* If a FileWriter was not provided, the promise is resolved with a Blob
|
421 |
+
* that represents the completed BlobBuffer contents. You can optionally
|
422 |
+
* pass in a mimeType to be used for this blob.
|
423 |
+
*
|
424 |
+
* If a FileWriter was provided, the promise is resolved with null as the
|
425 |
+
* first argument.
|
426 |
+
*/
|
427 |
+
this.complete = function(mimeType) {
|
428 |
+
if (fd || fileWriter) {
|
429 |
+
writePromise = writePromise.then(function() {
|
430 |
+
return null;
|
431 |
+
});
|
432 |
+
} else {
|
433 |
+
// After writes complete we need to merge the buffer to give to the
|
434 |
+
// caller
|
435 |
+
writePromise = writePromise.then(function() {
|
436 |
+
let result = [];
|
437 |
+
|
438 |
+
for (let i = 0; i < buffer.length; i++) {
|
439 |
+
result.push(buffer[i].data);
|
440 |
+
}
|
441 |
+
|
442 |
+
return new Blob(result, {type: mimeType});
|
443 |
+
});
|
444 |
+
}
|
445 |
+
|
446 |
+
return writePromise;
|
447 |
+
};
|
448 |
+
};
|
449 |
+
};
|
450 |
+
|
451 |
+
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
452 |
+
module.exports = BlobBuffer(require('fs'));
|
453 |
+
} else {
|
454 |
+
self.BlobBuffer = BlobBuffer(null);
|
455 |
+
}
|
456 |
+
})();
|
457 |
+
/**
|
458 |
+
* WebM video encoder for Google Chrome. This implementation is suitable for
|
459 |
+
* creating very large video files, because it can stream Blobs directly to a
|
460 |
+
* FileWriter without buffering the entire video in memory.
|
461 |
+
*
|
462 |
+
* When FileWriter is not available or not desired, it can buffer the video in
|
463 |
+
* memory as a series of Blobs which are eventually returned as one composite
|
464 |
+
* Blob.
|
465 |
+
*
|
466 |
+
* By Nicholas Sherlock.
|
467 |
+
*
|
468 |
+
* Based on the ideas from Whammy: https://github.com/antimatter15/whammy
|
469 |
+
*
|
470 |
+
* Released under the WTFPLv2 https://en.wikipedia.org/wiki/WTFPL
|
471 |
+
*/
|
472 |
+
|
473 |
+
'use strict';
|
474 |
+
|
475 |
+
(function() {
|
476 |
+
function extend(base, top) {
|
477 |
+
let target = {};
|
478 |
+
|
479 |
+
[base, top].forEach(function(obj) {
|
480 |
+
for (let prop in obj) {
|
481 |
+
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
482 |
+
target[prop] = obj[prop];
|
483 |
+
}
|
484 |
+
}
|
485 |
+
});
|
486 |
+
|
487 |
+
return target;
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* @param {String} string
|
492 |
+
* @returns {number}
|
493 |
+
*/
|
494 |
+
function byteStringToUint32LE(string) {
|
495 |
+
let a = string.charCodeAt(0), b = string.charCodeAt(1),
|
496 |
+
c = string.charCodeAt(2), d = string.charCodeAt(3);
|
497 |
+
|
498 |
+
return (a | (b << 8) | (c << 16) | (d << 24)) >>> 0;
|
499 |
+
}
|
500 |
+
|
501 |
+
|
502 |
+
// Just a little utility so we can tag values as floats for the EBML encoder's
|
503 |
+
// benefit
|
504 |
+
function EBMLFloat32(value) {
|
505 |
+
this.value = value;
|
506 |
+
}
|
507 |
+
|
508 |
+
function EBMLFloat64(value) {
|
509 |
+
this.value = value;
|
510 |
+
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
* Write the given EBML object to the provided ArrayBufferStream.
|
514 |
+
*
|
515 |
+
* @param buffer
|
516 |
+
* @param {Number} bufferFileOffset - The buffer's first byte is at this
|
517 |
+
* position inside the video file.
|
518 |
+
* This is used to complete offset and
|
519 |
+
* dataOffset fields in each EBML structure, indicating the file offset of the
|
520 |
+
* first byte of the EBML element and its data payload.
|
521 |
+
* @param {*} ebml
|
522 |
+
*/
|
523 |
+
function writeEBML(buffer, bufferFileOffset, ebml) {
|
524 |
+
// Is the ebml an array of sibling elements?
|
525 |
+
if (Array.isArray(ebml)) {
|
526 |
+
for (let i = 0; i < ebml.length; i++) {
|
527 |
+
writeEBML(buffer, bufferFileOffset, ebml[i]);
|
528 |
+
}
|
529 |
+
// Is this some sort of raw data that we want to write directly?
|
530 |
+
} else if (typeof ebml === 'string') {
|
531 |
+
buffer.writeString(ebml);
|
532 |
+
} else if (ebml instanceof Uint8Array) {
|
533 |
+
buffer.writeBytes(ebml);
|
534 |
+
} else if (ebml.id) {
|
535 |
+
// We're writing an EBML element
|
536 |
+
ebml.offset = buffer.pos + bufferFileOffset;
|
537 |
+
|
538 |
+
buffer.writeUnsignedIntBE(ebml.id); // ID field
|
539 |
+
|
540 |
+
// Now we need to write the size field, so we must know the payload size:
|
541 |
+
|
542 |
+
if (Array.isArray(ebml.data)) {
|
543 |
+
// Writing an array of child elements. We won't try to measure the size of
|
544 |
+
// the children up-front
|
545 |
+
|
546 |
+
let sizePos, dataBegin, dataEnd;
|
547 |
+
|
548 |
+
if (ebml.size === -1) {
|
549 |
+
// Write the reserved all-one-bits marker to note that the size of this
|
550 |
+
// element is unknown/unbounded
|
551 |
+
buffer.writeByte(0xFF);
|
552 |
+
} else {
|
553 |
+
sizePos = buffer.pos;
|
554 |
+
|
555 |
+
/* Write a dummy size field to overwrite later. 4 bytes allows an
|
556 |
+
* element maximum size of 256MB, which should be plenty (we don't want
|
557 |
+
* to have to buffer that much data in memory at one time anyway!)
|
558 |
+
*/
|
559 |
+
buffer.writeBytes([0, 0, 0, 0]);
|
560 |
+
}
|
561 |
+
|
562 |
+
dataBegin = buffer.pos;
|
563 |
+
|
564 |
+
ebml.dataOffset = dataBegin + bufferFileOffset;
|
565 |
+
writeEBML(buffer, bufferFileOffset, ebml.data);
|
566 |
+
|
567 |
+
if (ebml.size !== -1) {
|
568 |
+
dataEnd = buffer.pos;
|
569 |
+
|
570 |
+
ebml.size = dataEnd - dataBegin;
|
571 |
+
|
572 |
+
buffer.seek(sizePos);
|
573 |
+
buffer.writeEBMLVarIntWidth(ebml.size, 4); // Size field
|
574 |
+
|
575 |
+
buffer.seek(dataEnd);
|
576 |
+
}
|
577 |
+
} else if (typeof ebml.data === 'string') {
|
578 |
+
buffer.writeEBMLVarInt(ebml.data.length); // Size field
|
579 |
+
ebml.dataOffset = buffer.pos + bufferFileOffset;
|
580 |
+
buffer.writeString(ebml.data);
|
581 |
+
} else if (typeof ebml.data === 'number') {
|
582 |
+
// Allow the caller to explicitly choose the size if they wish by
|
583 |
+
// supplying a size field
|
584 |
+
if (!ebml.size) {
|
585 |
+
ebml.size = buffer.measureUnsignedInt(ebml.data);
|
586 |
+
}
|
587 |
+
|
588 |
+
buffer.writeEBMLVarInt(ebml.size); // Size field
|
589 |
+
ebml.dataOffset = buffer.pos + bufferFileOffset;
|
590 |
+
buffer.writeUnsignedIntBE(ebml.data, ebml.size);
|
591 |
+
} else if (ebml.data instanceof EBMLFloat64) {
|
592 |
+
buffer.writeEBMLVarInt(8); // Size field
|
593 |
+
ebml.dataOffset = buffer.pos + bufferFileOffset;
|
594 |
+
buffer.writeDoubleBE(ebml.data.value);
|
595 |
+
} else if (ebml.data instanceof EBMLFloat32) {
|
596 |
+
buffer.writeEBMLVarInt(4); // Size field
|
597 |
+
ebml.dataOffset = buffer.pos + bufferFileOffset;
|
598 |
+
buffer.writeFloatBE(ebml.data.value);
|
599 |
+
} else if (ebml.data instanceof Uint8Array) {
|
600 |
+
buffer.writeEBMLVarInt(ebml.data.byteLength); // Size field
|
601 |
+
ebml.dataOffset = buffer.pos + bufferFileOffset;
|
602 |
+
buffer.writeBytes(ebml.data);
|
603 |
+
} else {
|
604 |
+
throw new Error('Bad EBML datatype ' + typeof ebml.data);
|
605 |
+
}
|
606 |
+
} else {
|
607 |
+
throw new Error('Bad EBML datatype ' + typeof ebml.data);
|
608 |
+
}
|
609 |
+
}
|
610 |
+
|
611 |
+
/**
|
612 |
+
* @typedef {Object} Frame
|
613 |
+
* @property {string} frame - Raw VP8 frame data
|
614 |
+
* @property {Number} trackNumber - From 1 to 126 (inclusive)
|
615 |
+
* @property {Number} timecode
|
616 |
+
*/
|
617 |
+
|
618 |
+
/**
|
619 |
+
* @typedef {Object} Cluster
|
620 |
+
* @property {Number} timecode - Start time for the cluster
|
621 |
+
*/
|
622 |
+
|
623 |
+
/**
|
624 |
+
* @param ArrayBufferDataStream - Imported library
|
625 |
+
* @param BlobBuffer - Imported library
|
626 |
+
*
|
627 |
+
* @returns WebMWriter
|
628 |
+
*
|
629 |
+
* @constructor
|
630 |
+
*/
|
631 |
+
let WebMWriter = function(ArrayBufferDataStream, BlobBuffer) {
|
632 |
+
return function(options) {
|
633 |
+
let MAX_CLUSTER_DURATION_MSEC = 5000000, DEFAULT_TRACK_NUMBER = 1,
|
634 |
+
writtenHeader = false, videoWidth = 0, videoHeight = 0,
|
635 |
+
firstTimestampEver = true, earliestTimestamp = 0,
|
636 |
+
|
637 |
+
|
638 |
+
/**
|
639 |
+
*
|
640 |
+
* @type {Frame[]}
|
641 |
+
*/
|
642 |
+
clusterFrameBuffer = [], clusterStartTime = 0, clusterDuration = 0,
|
643 |
+
lastTimeCode = 0,
|
644 |
+
|
645 |
+
optionDefaults = {
|
646 |
+
fileWriter: null, // Chrome FileWriter in order to stream to a file
|
647 |
+
// instead of buffering to memory (optional)
|
648 |
+
fd: null, // Node.JS file descriptor to write to instead of buffering
|
649 |
+
// (optional)
|
650 |
+
codec: 'VP8', // Codec to write to webm file
|
651 |
+
|
652 |
+
},
|
653 |
+
|
654 |
+
seekPoints = {
|
655 |
+
Cues: {id: new Uint8Array([0x1C, 0x53, 0xBB, 0x6B]), positionEBML: null},
|
656 |
+
SegmentInfo:
|
657 |
+
{id: new Uint8Array([0x15, 0x49, 0xA9, 0x66]), positionEBML: null},
|
658 |
+
Tracks:
|
659 |
+
{id: new Uint8Array([0x16, 0x54, 0xAE, 0x6B]), positionEBML: null},
|
660 |
+
},
|
661 |
+
|
662 |
+
ebmlSegment, // Root element of the EBML document
|
663 |
+
|
664 |
+
segmentDuration = {
|
665 |
+
'id': 0x4489, // Duration
|
666 |
+
'data': new EBMLFloat64(0)
|
667 |
+
},
|
668 |
+
|
669 |
+
seekHead,
|
670 |
+
|
671 |
+
cues = [],
|
672 |
+
|
673 |
+
blobBuffer = new BlobBuffer(options.fileWriter || options.fd);
|
674 |
+
|
675 |
+
function fileOffsetToSegmentRelative(fileOffset) {
|
676 |
+
return fileOffset - ebmlSegment.dataOffset;
|
677 |
+
}
|
678 |
+
|
679 |
+
|
680 |
+
/**
|
681 |
+
* Create a SeekHead element with descriptors for the points in the global
|
682 |
+
* seekPoints array.
|
683 |
+
*
|
684 |
+
* 5 bytes of position values are reserved for each node, which lie at the
|
685 |
+
* offset point.positionEBML.dataOffset, to be overwritten later.
|
686 |
+
*/
|
687 |
+
function createSeekHead() {
|
688 |
+
let seekPositionEBMLTemplate = {
|
689 |
+
'id': 0x53AC, // SeekPosition
|
690 |
+
'size': 5, // Allows for 32GB video files
|
691 |
+
'data': 0 // We'll overwrite this when the file is complete
|
692 |
+
},
|
693 |
+
|
694 |
+
result = {
|
695 |
+
'id': 0x114D9B74, // SeekHead
|
696 |
+
'data': []
|
697 |
+
};
|
698 |
+
|
699 |
+
for (let name in seekPoints) {
|
700 |
+
let seekPoint = seekPoints[name];
|
701 |
+
|
702 |
+
seekPoint.positionEBML = Object.create(seekPositionEBMLTemplate);
|
703 |
+
|
704 |
+
result.data.push({
|
705 |
+
'id': 0x4DBB, // Seek
|
706 |
+
'data': [
|
707 |
+
{
|
708 |
+
'id': 0x53AB, // SeekID
|
709 |
+
'data': seekPoint.id
|
710 |
+
},
|
711 |
+
seekPoint.positionEBML
|
712 |
+
]
|
713 |
+
});
|
714 |
+
}
|
715 |
+
|
716 |
+
return result;
|
717 |
+
}
|
718 |
+
|
719 |
+
/**
|
720 |
+
* Write the WebM file header to the stream.
|
721 |
+
*/
|
722 |
+
function writeHeader() {
|
723 |
+
seekHead = createSeekHead();
|
724 |
+
|
725 |
+
let ebmlHeader = {
|
726 |
+
'id': 0x1a45dfa3, // EBML
|
727 |
+
'data': [
|
728 |
+
{
|
729 |
+
'id': 0x4286, // EBMLVersion
|
730 |
+
'data': 1
|
731 |
+
},
|
732 |
+
{
|
733 |
+
'id': 0x42f7, // EBMLReadVersion
|
734 |
+
'data': 1
|
735 |
+
},
|
736 |
+
{
|
737 |
+
'id': 0x42f2, // EBMLMaxIDLength
|
738 |
+
'data': 4
|
739 |
+
},
|
740 |
+
{
|
741 |
+
'id': 0x42f3, // EBMLMaxSizeLength
|
742 |
+
'data': 8
|
743 |
+
},
|
744 |
+
{
|
745 |
+
'id': 0x4282, // DocType
|
746 |
+
'data': 'webm'
|
747 |
+
},
|
748 |
+
{
|
749 |
+
'id': 0x4287, // DocTypeVersion
|
750 |
+
'data': 2
|
751 |
+
},
|
752 |
+
{
|
753 |
+
'id': 0x4285, // DocTypeReadVersion
|
754 |
+
'data': 2
|
755 |
+
}
|
756 |
+
]
|
757 |
+
},
|
758 |
+
|
759 |
+
segmentInfo = {
|
760 |
+
'id': 0x1549a966, // Info
|
761 |
+
'data': [
|
762 |
+
{
|
763 |
+
'id': 0x2ad7b1, // TimecodeScale
|
764 |
+
'data': 1e6 // Times will be in microseconds (1e6 nanoseconds
|
765 |
+
// per step = 1ms)
|
766 |
+
},
|
767 |
+
{
|
768 |
+
'id': 0x4d80, // MuxingApp
|
769 |
+
'data': 'webm-writer-js',
|
770 |
+
},
|
771 |
+
{
|
772 |
+
'id': 0x5741, // WritingApp
|
773 |
+
'data': 'webm-writer-js'
|
774 |
+
},
|
775 |
+
segmentDuration // To be filled in later
|
776 |
+
]
|
777 |
+
},
|
778 |
+
|
779 |
+
videoProperties = [
|
780 |
+
{
|
781 |
+
'id': 0xb0, // PixelWidth
|
782 |
+
'data': videoWidth
|
783 |
+
},
|
784 |
+
{
|
785 |
+
'id': 0xba, // PixelHeight
|
786 |
+
'data': videoHeight
|
787 |
+
}
|
788 |
+
];
|
789 |
+
|
790 |
+
let tracks = {
|
791 |
+
'id': 0x1654ae6b, // Tracks
|
792 |
+
'data': [{
|
793 |
+
'id': 0xae, // TrackEntry
|
794 |
+
'data': [
|
795 |
+
{
|
796 |
+
'id': 0xd7, // TrackNumber
|
797 |
+
'data': DEFAULT_TRACK_NUMBER
|
798 |
+
},
|
799 |
+
{
|
800 |
+
'id': 0x73c5, // TrackUID
|
801 |
+
'data': DEFAULT_TRACK_NUMBER
|
802 |
+
},
|
803 |
+
{
|
804 |
+
'id': 0x83, // TrackType
|
805 |
+
'data': 1
|
806 |
+
},
|
807 |
+
{
|
808 |
+
'id': 0xe0, // Video
|
809 |
+
'data': videoProperties
|
810 |
+
},
|
811 |
+
{
|
812 |
+
'id': 0x9c, // FlagLacing
|
813 |
+
'data': 0
|
814 |
+
},
|
815 |
+
{
|
816 |
+
'id': 0x22b59c, // Language
|
817 |
+
'data': 'und'
|
818 |
+
},
|
819 |
+
{
|
820 |
+
'id': 0xb9, // FlagEnabled
|
821 |
+
'data': 1
|
822 |
+
},
|
823 |
+
{
|
824 |
+
'id': 0x88, // FlagDefault
|
825 |
+
'data': 1
|
826 |
+
},
|
827 |
+
{
|
828 |
+
'id': 0x55aa, // FlagForced
|
829 |
+
'data': 0
|
830 |
+
},
|
831 |
+
|
832 |
+
{
|
833 |
+
'id': 0x86, // CodecID
|
834 |
+
'data': 'V_' + options.codec
|
835 |
+
}, /*
|
836 |
+
(options.codec == 'VP8' ?
|
837 |
+
{
|
838 |
+
'id': 0x63A2, // Codec private data
|
839 |
+
'data': []
|
840 |
+
} :
|
841 |
+
{
|
842 |
+
'id': 0x63A2, // Codec private data for vp9
|
843 |
+
'data': [
|
844 |
+
{
|
845 |
+
'id': 1, // vp9 Profile
|
846 |
+
'size': 1,
|
847 |
+
'data': 0
|
848 |
+
},
|
849 |
+
{
|
850 |
+
'id': 2, // Feature level
|
851 |
+
'size': 1,
|
852 |
+
'data': 10
|
853 |
+
},
|
854 |
+
{
|
855 |
+
'id': 3, // bitdepth level
|
856 |
+
'size': 1,
|
857 |
+
'data': 8
|
858 |
+
},
|
859 |
+
{
|
860 |
+
'id': 4, // color sampling
|
861 |
+
'size': 1,
|
862 |
+
'data': 0
|
863 |
+
}
|
864 |
+
]
|
865 |
+
}),
|
866 |
+
{
|
867 |
+
'id': 0x258688, // CodecName
|
868 |
+
'data': options.codec
|
869 |
+
},*/
|
870 |
+
]
|
871 |
+
}]
|
872 |
+
};
|
873 |
+
|
874 |
+
ebmlSegment = {
|
875 |
+
'id': 0x18538067, // Segment
|
876 |
+
'size': -1, // Unbounded size
|
877 |
+
'data': [
|
878 |
+
seekHead,
|
879 |
+
segmentInfo,
|
880 |
+
tracks,
|
881 |
+
]
|
882 |
+
};
|
883 |
+
|
884 |
+
let bufferStream = new ArrayBufferDataStream(256);
|
885 |
+
|
886 |
+
writeEBML(bufferStream, blobBuffer.pos, [ebmlHeader, ebmlSegment]);
|
887 |
+
blobBuffer.write(bufferStream.getAsDataArray());
|
888 |
+
|
889 |
+
// Now we know where these top-level elements lie in the file:
|
890 |
+
seekPoints.SegmentInfo.positionEBML.data =
|
891 |
+
fileOffsetToSegmentRelative(segmentInfo.offset);
|
892 |
+
seekPoints.Tracks.positionEBML.data =
|
893 |
+
fileOffsetToSegmentRelative(tracks.offset);
|
894 |
+
|
895 |
+
writtenHeader = true;
|
896 |
+
}
|
897 |
+
|
898 |
+
/**
|
899 |
+
* Create a SimpleBlock element to hold the given frame.
|
900 |
+
*
|
901 |
+
* @param {Frame} frame
|
902 |
+
*
|
903 |
+
* @return A SimpleBlock EBML element.
|
904 |
+
*/
|
905 |
+
function createSimpleBlockForframe(frame) {
|
906 |
+
let bufferStream = new ArrayBufferDataStream(1 + 2 + 1);
|
907 |
+
|
908 |
+
if (!(frame.trackNumber > 0 && frame.trackNumber < 127)) {
|
909 |
+
throw new Error('TrackNumber must be > 0 and < 127');
|
910 |
+
}
|
911 |
+
|
912 |
+
bufferStream.writeEBMLVarInt(
|
913 |
+
frame.trackNumber); // Always 1 byte since we limit the range of
|
914 |
+
// trackNumber
|
915 |
+
bufferStream.writeU16BE(frame.timecode);
|
916 |
+
|
917 |
+
// Flags byte
|
918 |
+
bufferStream.writeByte(
|
919 |
+
(frame.type == "key" ? 1 : 0) << 7 // frame
|
920 |
+
);
|
921 |
+
|
922 |
+
return {
|
923 |
+
'id': 0xA3, // SimpleBlock
|
924 |
+
'data': [bufferStream.getAsDataArray(), frame.frame]
|
925 |
+
};
|
926 |
+
}
|
927 |
+
|
928 |
+
/**
|
929 |
+
* Create a Cluster EBML node.
|
930 |
+
*
|
931 |
+
* @param {Cluster} cluster
|
932 |
+
*
|
933 |
+
* Returns an EBML element.
|
934 |
+
*/
|
935 |
+
function createCluster(cluster) {
|
936 |
+
return {
|
937 |
+
'id': 0x1f43b675,
|
938 |
+
'data': [{
|
939 |
+
'id': 0xe7, // Timecode
|
940 |
+
'data': Math.round(cluster.timecode)
|
941 |
+
}]
|
942 |
+
};
|
943 |
+
}
|
944 |
+
|
945 |
+
function addCuePoint(trackIndex, clusterTime, clusterFileOffset) {
|
946 |
+
cues.push({
|
947 |
+
'id': 0xBB, // Cue
|
948 |
+
'data': [
|
949 |
+
{
|
950 |
+
'id': 0xB3, // CueTime
|
951 |
+
'data': clusterTime
|
952 |
+
},
|
953 |
+
{
|
954 |
+
'id': 0xB7, // CueTrackPositions
|
955 |
+
'data': [
|
956 |
+
{
|
957 |
+
'id': 0xF7, // CueTrack
|
958 |
+
'data': trackIndex
|
959 |
+
},
|
960 |
+
{
|
961 |
+
'id': 0xF1, // CueClusterPosition
|
962 |
+
'data': fileOffsetToSegmentRelative(clusterFileOffset)
|
963 |
+
}
|
964 |
+
]
|
965 |
+
}
|
966 |
+
]
|
967 |
+
});
|
968 |
+
}
|
969 |
+
|
970 |
+
/**
|
971 |
+
* Write a Cues element to the blobStream using the global `cues` array of
|
972 |
+
* CuePoints (use addCuePoint()). The seek entry for the Cues in the
|
973 |
+
* SeekHead is updated.
|
974 |
+
*/
|
975 |
+
function writeCues() {
|
976 |
+
let ebml = {'id': 0x1C53BB6B, 'data': cues},
|
977 |
+
|
978 |
+
cuesBuffer = new ArrayBufferDataStream(
|
979 |
+
16 +
|
980 |
+
cues.length *
|
981 |
+
32); // Pretty crude estimate of the buffer size we'll need
|
982 |
+
|
983 |
+
writeEBML(cuesBuffer, blobBuffer.pos, ebml);
|
984 |
+
blobBuffer.write(cuesBuffer.getAsDataArray());
|
985 |
+
|
986 |
+
// Now we know where the Cues element has ended up, we can update the
|
987 |
+
// SeekHead
|
988 |
+
seekPoints.Cues.positionEBML.data =
|
989 |
+
fileOffsetToSegmentRelative(ebml.offset);
|
990 |
+
}
|
991 |
+
|
992 |
+
/**
|
993 |
+
* Flush the frames in the current clusterFrameBuffer out to the stream as a
|
994 |
+
* Cluster.
|
995 |
+
*/
|
996 |
+
function flushClusterFrameBuffer() {
|
997 |
+
if (clusterFrameBuffer.length === 0) {
|
998 |
+
return;
|
999 |
+
}
|
1000 |
+
|
1001 |
+
// First work out how large of a buffer we need to hold the cluster data
|
1002 |
+
let rawImageSize = 0;
|
1003 |
+
|
1004 |
+
for (let i = 0; i < clusterFrameBuffer.length; i++) {
|
1005 |
+
rawImageSize += clusterFrameBuffer[i].frame.byteLength;
|
1006 |
+
}
|
1007 |
+
|
1008 |
+
let buffer = new ArrayBufferDataStream(
|
1009 |
+
rawImageSize +
|
1010 |
+
clusterFrameBuffer.length *
|
1011 |
+
64), // Estimate 64 bytes per block header
|
1012 |
+
|
1013 |
+
cluster = createCluster({
|
1014 |
+
timecode: Math.round(clusterStartTime),
|
1015 |
+
});
|
1016 |
+
|
1017 |
+
for (let i = 0; i < clusterFrameBuffer.length; i++) {
|
1018 |
+
cluster.data.push(createSimpleBlockForframe(clusterFrameBuffer[i]));
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
writeEBML(buffer, blobBuffer.pos, cluster);
|
1022 |
+
blobBuffer.write(buffer.getAsDataArray());
|
1023 |
+
|
1024 |
+
addCuePoint(
|
1025 |
+
DEFAULT_TRACK_NUMBER, Math.round(clusterStartTime), cluster.offset);
|
1026 |
+
|
1027 |
+
clusterFrameBuffer = [];
|
1028 |
+
clusterDuration = 0;
|
1029 |
+
}
|
1030 |
+
|
1031 |
+
function validateOptions() {
|
1032 |
+
}
|
1033 |
+
|
1034 |
+
/**
|
1035 |
+
*
|
1036 |
+
* @param {Frame} frame
|
1037 |
+
*/
|
1038 |
+
function addFrameToCluster(frame) {
|
1039 |
+
frame.trackNumber = DEFAULT_TRACK_NUMBER;
|
1040 |
+
var time = frame.intime / 1000;
|
1041 |
+
if (firstTimestampEver) {
|
1042 |
+
earliestTimestamp = time;
|
1043 |
+
time = 0;
|
1044 |
+
firstTimestampEver = false;
|
1045 |
+
} else {
|
1046 |
+
time = time - earliestTimestamp;
|
1047 |
+
}
|
1048 |
+
lastTimeCode = time;
|
1049 |
+
if (clusterDuration == 0) clusterStartTime = time;
|
1050 |
+
|
1051 |
+
// Frame timecodes are relative to the start of their cluster:
|
1052 |
+
// frame.timecode = Math.round(clusterDuration);
|
1053 |
+
frame.timecode = Math.round(time - clusterStartTime);
|
1054 |
+
|
1055 |
+
clusterFrameBuffer.push(frame);
|
1056 |
+
clusterDuration = frame.timecode + 1;
|
1057 |
+
|
1058 |
+
if (clusterDuration >= MAX_CLUSTER_DURATION_MSEC) {
|
1059 |
+
flushClusterFrameBuffer();
|
1060 |
+
}
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
/**
|
1064 |
+
* Rewrites the SeekHead element that was initially written to the stream
|
1065 |
+
* with the offsets of top level elements.
|
1066 |
+
*
|
1067 |
+
* Call once writing is complete (so the offset of all top level elements
|
1068 |
+
* is known).
|
1069 |
+
*/
|
1070 |
+
function rewriteSeekHead() {
|
1071 |
+
let seekHeadBuffer = new ArrayBufferDataStream(seekHead.size),
|
1072 |
+
oldPos = blobBuffer.pos;
|
1073 |
+
|
1074 |
+
// Write the rewritten SeekHead element's data payload to the stream
|
1075 |
+
// (don't need to update the id or size)
|
1076 |
+
writeEBML(seekHeadBuffer, seekHead.dataOffset, seekHead.data);
|
1077 |
+
|
1078 |
+
// And write that through to the file
|
1079 |
+
blobBuffer.seek(seekHead.dataOffset);
|
1080 |
+
blobBuffer.write(seekHeadBuffer.getAsDataArray());
|
1081 |
+
blobBuffer.seek(oldPos);
|
1082 |
+
}
|
1083 |
+
|
1084 |
+
/**
|
1085 |
+
* Rewrite the Duration field of the Segment with the newly-discovered
|
1086 |
+
* video duration.
|
1087 |
+
*/
|
1088 |
+
function rewriteDuration() {
|
1089 |
+
let buffer = new ArrayBufferDataStream(8), oldPos = blobBuffer.pos;
|
1090 |
+
|
1091 |
+
// Rewrite the data payload (don't need to update the id or size)
|
1092 |
+
buffer.writeDoubleBE(lastTimeCode);
|
1093 |
+
|
1094 |
+
// And write that through to the file
|
1095 |
+
blobBuffer.seek(segmentDuration.dataOffset);
|
1096 |
+
blobBuffer.write(buffer.getAsDataArray());
|
1097 |
+
|
1098 |
+
blobBuffer.seek(oldPos);
|
1099 |
+
}
|
1100 |
+
|
1101 |
+
/**
|
1102 |
+
* Add a frame to the video.
|
1103 |
+
*
|
1104 |
+
* @param {HTMLCanvasElement|String} frame - A Canvas element that
|
1105 |
+
* contains the frame, or a WebP string you obtained by calling
|
1106 |
+
* toDataUrl() on an image yourself.
|
1107 |
+
*
|
1108 |
+
*/
|
1109 |
+
this.addFrame = function(frame) {
|
1110 |
+
if (!writtenHeader) {
|
1111 |
+
videoWidth = options.width;
|
1112 |
+
videoHeight = options.height;
|
1113 |
+
writeHeader();
|
1114 |
+
}
|
1115 |
+
if (frame.constructor.name == 'EncodedVideoChunk') {
|
1116 |
+
let frameData = new Uint8Array(frame.byteLength);
|
1117 |
+
frame.copyTo(frameData);
|
1118 |
+
addFrameToCluster({
|
1119 |
+
frame: frameData,
|
1120 |
+
intime: frame.timestamp,
|
1121 |
+
type: frame.type,
|
1122 |
+
});
|
1123 |
+
return;
|
1124 |
+
}
|
1125 |
+
};
|
1126 |
+
|
1127 |
+
/**
|
1128 |
+
* Finish writing the video and return a Promise to signal completion.
|
1129 |
+
*
|
1130 |
+
* If the destination device was memory (i.e. options.fileWriter was not
|
1131 |
+
* supplied), the Promise is resolved with a Blob with the contents of the
|
1132 |
+
* entire video.
|
1133 |
+
*/
|
1134 |
+
this.complete = function() {
|
1135 |
+
if (!writtenHeader) {
|
1136 |
+
writeHeader();
|
1137 |
+
}
|
1138 |
+
firstTimestampEver = true;
|
1139 |
+
|
1140 |
+
flushClusterFrameBuffer();
|
1141 |
+
|
1142 |
+
writeCues();
|
1143 |
+
rewriteSeekHead();
|
1144 |
+
rewriteDuration();
|
1145 |
+
|
1146 |
+
return blobBuffer.complete('video/webm');
|
1147 |
+
};
|
1148 |
+
|
1149 |
+
this.getWrittenSize = function() {
|
1150 |
+
return blobBuffer.length;
|
1151 |
+
};
|
1152 |
+
|
1153 |
+
options = extend(optionDefaults, options || {});
|
1154 |
+
validateOptions();
|
1155 |
+
};
|
1156 |
+
};
|
1157 |
+
|
1158 |
+
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
1159 |
+
module.exports =
|
1160 |
+
WebMWriter(require('./ArrayBufferDataStream'), require('./BlobBuffer'));
|
1161 |
+
} else {
|
1162 |
+
self.WebMWriter =
|
1163 |
+
WebMWriter(self.ArrayBufferDataStream, self.BlobBuffer);
|
1164 |
+
}
|
1165 |
+
})();
|