@leafer-in/film 0.0.0-stage → 2.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1 -3
- package/dist/film.cjs +962 -0
- package/dist/film.esm.js +956 -0
- package/dist/film.esm.min.js +2 -0
- package/dist/film.esm.min.js.map +1 -0
- package/dist/film.js +933 -0
- package/dist/film.min.cjs +2 -0
- package/dist/film.min.cjs.map +1 -0
- package/dist/film.min.js +2 -0
- package/dist/film.min.js.map +1 -0
- package/package.json +38 -3
- package/src/Film.ts +27 -0
- package/src/FilmDecoder.ts +201 -0
- package/src/OmgFilmDecoder.ts +143 -0
- package/src/PaintFilm.ts +56 -0
- package/src/data/FilmData.ts +9 -0
- package/src/helper/ext.ts +23 -0
- package/src/index.ts +75 -0
- package/types/index.d.ts +69 -0
package/dist/film.cjs
ADDED
|
@@ -0,0 +1,962 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var draw = require("@leafer-ui/draw");
|
|
4
|
+
|
|
5
|
+
function __decorate(decorators, target, key, desc) {
|
|
6
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
7
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
8
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) {
|
|
13
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
14
|
+
resolve(value);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
18
|
+
function fulfilled(value) {
|
|
19
|
+
try {
|
|
20
|
+
step(generator.next(value));
|
|
21
|
+
} catch (e) {
|
|
22
|
+
reject(e);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function rejected(value) {
|
|
26
|
+
try {
|
|
27
|
+
step(generator["throw"](value));
|
|
28
|
+
} catch (e) {
|
|
29
|
+
reject(e);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function step(result) {
|
|
33
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
34
|
+
}
|
|
35
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
|
|
40
|
+
var e = new Error(message);
|
|
41
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
class FilmDecoder {
|
|
45
|
+
constructor() {
|
|
46
|
+
this.frames = [];
|
|
47
|
+
this.decodedIndex = -1;
|
|
48
|
+
}
|
|
49
|
+
static register(type, Decoder, force) {
|
|
50
|
+
FilmDecoder.decoderMap[type] = {
|
|
51
|
+
Decoder: Decoder,
|
|
52
|
+
force: force
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
static canUse(mimeType) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function*() {
|
|
57
|
+
const {supportMap: supportMap} = this;
|
|
58
|
+
let canUse = supportMap[mimeType];
|
|
59
|
+
if (!draw.isUndefined(canUse)) return canUse;
|
|
60
|
+
if (typeof ImageDecoder === "undefined") return false;
|
|
61
|
+
canUse = yield ImageDecoder.isTypeSupported(mimeType);
|
|
62
|
+
return supportMap[mimeType] = canUse;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
createAtlas() {
|
|
66
|
+
const {width: width, height: height, total: total} = this;
|
|
67
|
+
if (width * height * total <= FilmDecoder.maxAtlasSize) {
|
|
68
|
+
const columns = Math.ceil(Math.sqrt(total * height / width));
|
|
69
|
+
const rows = Math.ceil(total / columns);
|
|
70
|
+
this.atlasGrid = {
|
|
71
|
+
x: columns,
|
|
72
|
+
y: rows
|
|
73
|
+
};
|
|
74
|
+
this.atlas = draw.Platform.origin.createCanvas(width * columns, height * rows);
|
|
75
|
+
this.atlasContext = this.atlas.getContext("2d");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
decodeHeader(data, type) {
|
|
79
|
+
return __awaiter(this, void 0, void 0, function*() {
|
|
80
|
+
this.decoder = new ImageDecoder({
|
|
81
|
+
data: data,
|
|
82
|
+
type: type
|
|
83
|
+
});
|
|
84
|
+
yield this.decoder.tracks.ready;
|
|
85
|
+
const first = yield this.decodeFrame(0);
|
|
86
|
+
const {displayWidth: displayWidth, displayHeight: displayHeight} = first.image, {selectedTrack: selectedTrack} = this.decoder.tracks;
|
|
87
|
+
this.width = displayWidth;
|
|
88
|
+
this.height = displayHeight;
|
|
89
|
+
this.total = selectedTrack.frameCount;
|
|
90
|
+
this.loop = selectedTrack.repetitionCount;
|
|
91
|
+
this.createAtlas();
|
|
92
|
+
if (this.atlas) this.mergeFrame(0);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
decodeFrame(frameIndex) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function*() {
|
|
97
|
+
const {frames: frames} = this, frame = frames[frameIndex];
|
|
98
|
+
if (frame && !frame.decoding) return frame;
|
|
99
|
+
for (let i = this.decodedIndex + 1; i <= frameIndex; i++) {
|
|
100
|
+
yield this.decodeOneFrame(i);
|
|
101
|
+
this.decodedIndex = i;
|
|
102
|
+
}
|
|
103
|
+
return frames[frameIndex];
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
decodeOneFrame(frameIndex) {
|
|
107
|
+
return __awaiter(this, void 0, void 0, function*() {
|
|
108
|
+
return new Promise(resolve => {
|
|
109
|
+
this.decoder.decode({
|
|
110
|
+
frameIndex: frameIndex
|
|
111
|
+
}).then(result => {
|
|
112
|
+
const {image: image} = result;
|
|
113
|
+
const frame = {
|
|
114
|
+
image: image,
|
|
115
|
+
duration: image.duration / 1e3 / 1e3
|
|
116
|
+
};
|
|
117
|
+
this.frames[frameIndex] = frame;
|
|
118
|
+
if (this.atlas) this.mergeFrame(frameIndex);
|
|
119
|
+
resolve(frame);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
mergeFrame(frameIndex, destoryFrameImage = true) {
|
|
125
|
+
const frame = this.frames[frameIndex], {atlasGrid: atlasGrid, width: width, height: height} = this;
|
|
126
|
+
frame.x = frameIndex % atlasGrid.x * width;
|
|
127
|
+
frame.y = Math.floor(frameIndex / atlasGrid.x) * height;
|
|
128
|
+
this.atlasContext.drawImage(frame.image, frame.x, frame.y);
|
|
129
|
+
if (destoryFrameImage) this.destoryFrameImage(frame); else delete frame.image;
|
|
130
|
+
}
|
|
131
|
+
render(canvas, x, y, width, height, leaf, playOptions, _imageScaleX, _imageScaleY) {
|
|
132
|
+
let {nowIndex: nowIndex, paused: paused, speed: speed, pauseIndex: pauseIndex, loop: loop, frameTimer: frameTimer} = playOptions;
|
|
133
|
+
if (draw.isUndefined(nowIndex)) nowIndex = 0;
|
|
134
|
+
const {frames: frames} = this, frame = frames[nowIndex];
|
|
135
|
+
if (this.renderFrame(frame, canvas, x, y, width, height)) {
|
|
136
|
+
if (frameTimer) return;
|
|
137
|
+
if (!draw.isUndefined(pauseIndex) && nowIndex === pauseIndex) {
|
|
138
|
+
playOptions.paused = true;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
let nextIndex = nowIndex + 1;
|
|
142
|
+
if (nextIndex >= this.total) {
|
|
143
|
+
if (this.loop && isFinite(this.loop)) {
|
|
144
|
+
loop = (loop || 0) + 1;
|
|
145
|
+
if (loop > this.loop) return;
|
|
146
|
+
playOptions.loop = loop;
|
|
147
|
+
}
|
|
148
|
+
nextIndex = 0;
|
|
149
|
+
}
|
|
150
|
+
if (nextIndex < this.total && !frames[nextIndex]) {
|
|
151
|
+
frames[nextIndex] = {
|
|
152
|
+
duration: 0,
|
|
153
|
+
decoding: true
|
|
154
|
+
};
|
|
155
|
+
this.decodeFrame(nextIndex).finally(() => {
|
|
156
|
+
if (this.decodedIndex === this.total - 1) this.destroyDecoder();
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (paused) return;
|
|
160
|
+
playOptions.frameTimer = setTimeout(() => {
|
|
161
|
+
playOptions.nowIndex = nextIndex;
|
|
162
|
+
delete playOptions.frameTimer;
|
|
163
|
+
leaf.forceRender();
|
|
164
|
+
}, frame.duration * (speed || 1) * 1e3);
|
|
165
|
+
} else {
|
|
166
|
+
this.renderFrame(frames[nowIndex - 1], canvas, x, y, width, height);
|
|
167
|
+
leaf.forceRender();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
renderFrame(frame, canvas, x, y, width, height) {
|
|
171
|
+
const canRender = frame && !frame.decoding, {atlas: atlas} = this;
|
|
172
|
+
if (canRender) {
|
|
173
|
+
if (atlas) canvas.drawImage(atlas, frame.x, frame.y, this.width, this.height, x, y, width, height); else canvas.drawImage(frame.image, x, y, width, height);
|
|
174
|
+
}
|
|
175
|
+
return canRender;
|
|
176
|
+
}
|
|
177
|
+
destoryFrame(frameIndex, deleteIndex = true) {
|
|
178
|
+
const {frames: frames} = this, frame = frames[frameIndex];
|
|
179
|
+
if (frame) {
|
|
180
|
+
this.destoryFrameImage(frame);
|
|
181
|
+
if (deleteIndex) delete frames[frameIndex];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
destoryFrameImage(frame) {
|
|
185
|
+
const {image: image} = frame;
|
|
186
|
+
if (image && image.close) image.close();
|
|
187
|
+
delete frame.image;
|
|
188
|
+
}
|
|
189
|
+
destroyDecoder() {
|
|
190
|
+
if (this.decoder) {
|
|
191
|
+
this.decoder.close();
|
|
192
|
+
this.decoder = null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
close() {
|
|
196
|
+
if (this.atlas) this.atlas = this.atlasContext = null;
|
|
197
|
+
this.frames.forEach((_item, index) => this.destoryFrame(index, false));
|
|
198
|
+
this.frames.length = 0;
|
|
199
|
+
this.destroyDecoder();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
FilmDecoder.decoderMap = {};
|
|
204
|
+
|
|
205
|
+
FilmDecoder.supportMap = {};
|
|
206
|
+
|
|
207
|
+
FilmDecoder.maxAtlasSize = draw.Platform.image.maxPatternSize;
|
|
208
|
+
|
|
209
|
+
var omggif = {};
|
|
210
|
+
|
|
211
|
+
var GifReader_1;
|
|
212
|
+
|
|
213
|
+
var GifWriter_1;
|
|
214
|
+
|
|
215
|
+
function GifWriter(buf, width, height, gopts) {
|
|
216
|
+
var p = 0;
|
|
217
|
+
var gopts = gopts === undefined ? {} : gopts;
|
|
218
|
+
var loop_count = gopts.loop === undefined ? null : gopts.loop;
|
|
219
|
+
var global_palette = gopts.palette === undefined ? null : gopts.palette;
|
|
220
|
+
if (width <= 0 || height <= 0 || width > 65535 || height > 65535) throw new Error("Width/Height invalid.");
|
|
221
|
+
function check_palette_and_num_colors(palette) {
|
|
222
|
+
var num_colors = palette.length;
|
|
223
|
+
if (num_colors < 2 || num_colors > 256 || num_colors & num_colors - 1) {
|
|
224
|
+
throw new Error("Invalid code/color length, must be power of 2 and 2 .. 256.");
|
|
225
|
+
}
|
|
226
|
+
return num_colors;
|
|
227
|
+
}
|
|
228
|
+
buf[p++] = 71;
|
|
229
|
+
buf[p++] = 73;
|
|
230
|
+
buf[p++] = 70;
|
|
231
|
+
buf[p++] = 56;
|
|
232
|
+
buf[p++] = 57;
|
|
233
|
+
buf[p++] = 97;
|
|
234
|
+
var gp_num_colors_pow2 = 0;
|
|
235
|
+
var background = 0;
|
|
236
|
+
if (global_palette !== null) {
|
|
237
|
+
var gp_num_colors = check_palette_and_num_colors(global_palette);
|
|
238
|
+
while (gp_num_colors >>= 1) ++gp_num_colors_pow2;
|
|
239
|
+
gp_num_colors = 1 << gp_num_colors_pow2;
|
|
240
|
+
--gp_num_colors_pow2;
|
|
241
|
+
if (gopts.background !== undefined) {
|
|
242
|
+
background = gopts.background;
|
|
243
|
+
if (background >= gp_num_colors) throw new Error("Background index out of range.");
|
|
244
|
+
if (background === 0) throw new Error("Background index explicitly passed as 0.");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
buf[p++] = width & 255;
|
|
248
|
+
buf[p++] = width >> 8 & 255;
|
|
249
|
+
buf[p++] = height & 255;
|
|
250
|
+
buf[p++] = height >> 8 & 255;
|
|
251
|
+
buf[p++] = (global_palette !== null ? 128 : 0) | gp_num_colors_pow2;
|
|
252
|
+
buf[p++] = background;
|
|
253
|
+
buf[p++] = 0;
|
|
254
|
+
if (global_palette !== null) {
|
|
255
|
+
for (var i = 0, il = global_palette.length; i < il; ++i) {
|
|
256
|
+
var rgb = global_palette[i];
|
|
257
|
+
buf[p++] = rgb >> 16 & 255;
|
|
258
|
+
buf[p++] = rgb >> 8 & 255;
|
|
259
|
+
buf[p++] = rgb & 255;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (loop_count !== null) {
|
|
263
|
+
if (loop_count < 0 || loop_count > 65535) throw new Error("Loop count invalid.");
|
|
264
|
+
buf[p++] = 33;
|
|
265
|
+
buf[p++] = 255;
|
|
266
|
+
buf[p++] = 11;
|
|
267
|
+
buf[p++] = 78;
|
|
268
|
+
buf[p++] = 69;
|
|
269
|
+
buf[p++] = 84;
|
|
270
|
+
buf[p++] = 83;
|
|
271
|
+
buf[p++] = 67;
|
|
272
|
+
buf[p++] = 65;
|
|
273
|
+
buf[p++] = 80;
|
|
274
|
+
buf[p++] = 69;
|
|
275
|
+
buf[p++] = 50;
|
|
276
|
+
buf[p++] = 46;
|
|
277
|
+
buf[p++] = 48;
|
|
278
|
+
buf[p++] = 3;
|
|
279
|
+
buf[p++] = 1;
|
|
280
|
+
buf[p++] = loop_count & 255;
|
|
281
|
+
buf[p++] = loop_count >> 8 & 255;
|
|
282
|
+
buf[p++] = 0;
|
|
283
|
+
}
|
|
284
|
+
var ended = false;
|
|
285
|
+
this.addFrame = function(x, y, w, h, indexed_pixels, opts) {
|
|
286
|
+
if (ended === true) {
|
|
287
|
+
--p;
|
|
288
|
+
ended = false;
|
|
289
|
+
}
|
|
290
|
+
opts = opts === undefined ? {} : opts;
|
|
291
|
+
if (x < 0 || y < 0 || x > 65535 || y > 65535) throw new Error("x/y invalid.");
|
|
292
|
+
if (w <= 0 || h <= 0 || w > 65535 || h > 65535) throw new Error("Width/Height invalid.");
|
|
293
|
+
if (indexed_pixels.length < w * h) throw new Error("Not enough pixels for the frame size.");
|
|
294
|
+
var using_local_palette = true;
|
|
295
|
+
var palette = opts.palette;
|
|
296
|
+
if (palette === undefined || palette === null) {
|
|
297
|
+
using_local_palette = false;
|
|
298
|
+
palette = global_palette;
|
|
299
|
+
}
|
|
300
|
+
if (palette === undefined || palette === null) throw new Error("Must supply either a local or global palette.");
|
|
301
|
+
var num_colors = check_palette_and_num_colors(palette);
|
|
302
|
+
var min_code_size = 0;
|
|
303
|
+
while (num_colors >>= 1) ++min_code_size;
|
|
304
|
+
num_colors = 1 << min_code_size;
|
|
305
|
+
var delay = opts.delay === undefined ? 0 : opts.delay;
|
|
306
|
+
var disposal = opts.disposal === undefined ? 0 : opts.disposal;
|
|
307
|
+
if (disposal < 0 || disposal > 3) throw new Error("Disposal out of range.");
|
|
308
|
+
var use_transparency = false;
|
|
309
|
+
var transparent_index = 0;
|
|
310
|
+
if (opts.transparent !== undefined && opts.transparent !== null) {
|
|
311
|
+
use_transparency = true;
|
|
312
|
+
transparent_index = opts.transparent;
|
|
313
|
+
if (transparent_index < 0 || transparent_index >= num_colors) throw new Error("Transparent color index.");
|
|
314
|
+
}
|
|
315
|
+
if (disposal !== 0 || use_transparency || delay !== 0) {
|
|
316
|
+
buf[p++] = 33;
|
|
317
|
+
buf[p++] = 249;
|
|
318
|
+
buf[p++] = 4;
|
|
319
|
+
buf[p++] = disposal << 2 | (use_transparency === true ? 1 : 0);
|
|
320
|
+
buf[p++] = delay & 255;
|
|
321
|
+
buf[p++] = delay >> 8 & 255;
|
|
322
|
+
buf[p++] = transparent_index;
|
|
323
|
+
buf[p++] = 0;
|
|
324
|
+
}
|
|
325
|
+
buf[p++] = 44;
|
|
326
|
+
buf[p++] = x & 255;
|
|
327
|
+
buf[p++] = x >> 8 & 255;
|
|
328
|
+
buf[p++] = y & 255;
|
|
329
|
+
buf[p++] = y >> 8 & 255;
|
|
330
|
+
buf[p++] = w & 255;
|
|
331
|
+
buf[p++] = w >> 8 & 255;
|
|
332
|
+
buf[p++] = h & 255;
|
|
333
|
+
buf[p++] = h >> 8 & 255;
|
|
334
|
+
buf[p++] = using_local_palette === true ? 128 | min_code_size - 1 : 0;
|
|
335
|
+
if (using_local_palette === true) {
|
|
336
|
+
for (var i = 0, il = palette.length; i < il; ++i) {
|
|
337
|
+
var rgb = palette[i];
|
|
338
|
+
buf[p++] = rgb >> 16 & 255;
|
|
339
|
+
buf[p++] = rgb >> 8 & 255;
|
|
340
|
+
buf[p++] = rgb & 255;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
p = GifWriterOutputLZWCodeStream(buf, p, min_code_size < 2 ? 2 : min_code_size, indexed_pixels);
|
|
344
|
+
return p;
|
|
345
|
+
};
|
|
346
|
+
this.end = function() {
|
|
347
|
+
if (ended === false) {
|
|
348
|
+
buf[p++] = 59;
|
|
349
|
+
ended = true;
|
|
350
|
+
}
|
|
351
|
+
return p;
|
|
352
|
+
};
|
|
353
|
+
this.getOutputBuffer = function() {
|
|
354
|
+
return buf;
|
|
355
|
+
};
|
|
356
|
+
this.setOutputBuffer = function(v) {
|
|
357
|
+
buf = v;
|
|
358
|
+
};
|
|
359
|
+
this.getOutputBufferPosition = function() {
|
|
360
|
+
return p;
|
|
361
|
+
};
|
|
362
|
+
this.setOutputBufferPosition = function(v) {
|
|
363
|
+
p = v;
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) {
|
|
368
|
+
buf[p++] = min_code_size;
|
|
369
|
+
var cur_subblock = p++;
|
|
370
|
+
var clear_code = 1 << min_code_size;
|
|
371
|
+
var code_mask = clear_code - 1;
|
|
372
|
+
var eoi_code = clear_code + 1;
|
|
373
|
+
var next_code = eoi_code + 1;
|
|
374
|
+
var cur_code_size = min_code_size + 1;
|
|
375
|
+
var cur_shift = 0;
|
|
376
|
+
var cur = 0;
|
|
377
|
+
function emit_bytes_to_buffer(bit_block_size) {
|
|
378
|
+
while (cur_shift >= bit_block_size) {
|
|
379
|
+
buf[p++] = cur & 255;
|
|
380
|
+
cur >>= 8;
|
|
381
|
+
cur_shift -= 8;
|
|
382
|
+
if (p === cur_subblock + 256) {
|
|
383
|
+
buf[cur_subblock] = 255;
|
|
384
|
+
cur_subblock = p++;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function emit_code(c) {
|
|
389
|
+
cur |= c << cur_shift;
|
|
390
|
+
cur_shift += cur_code_size;
|
|
391
|
+
emit_bytes_to_buffer(8);
|
|
392
|
+
}
|
|
393
|
+
var ib_code = index_stream[0] & code_mask;
|
|
394
|
+
var code_table = {};
|
|
395
|
+
emit_code(clear_code);
|
|
396
|
+
for (var i = 1, il = index_stream.length; i < il; ++i) {
|
|
397
|
+
var k = index_stream[i] & code_mask;
|
|
398
|
+
var cur_key = ib_code << 8 | k;
|
|
399
|
+
var cur_code = code_table[cur_key];
|
|
400
|
+
if (cur_code === undefined) {
|
|
401
|
+
cur |= ib_code << cur_shift;
|
|
402
|
+
cur_shift += cur_code_size;
|
|
403
|
+
while (cur_shift >= 8) {
|
|
404
|
+
buf[p++] = cur & 255;
|
|
405
|
+
cur >>= 8;
|
|
406
|
+
cur_shift -= 8;
|
|
407
|
+
if (p === cur_subblock + 256) {
|
|
408
|
+
buf[cur_subblock] = 255;
|
|
409
|
+
cur_subblock = p++;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (next_code === 4096) {
|
|
413
|
+
emit_code(clear_code);
|
|
414
|
+
next_code = eoi_code + 1;
|
|
415
|
+
cur_code_size = min_code_size + 1;
|
|
416
|
+
code_table = {};
|
|
417
|
+
} else {
|
|
418
|
+
if (next_code >= 1 << cur_code_size) ++cur_code_size;
|
|
419
|
+
code_table[cur_key] = next_code++;
|
|
420
|
+
}
|
|
421
|
+
ib_code = k;
|
|
422
|
+
} else {
|
|
423
|
+
ib_code = cur_code;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
emit_code(ib_code);
|
|
427
|
+
emit_code(eoi_code);
|
|
428
|
+
emit_bytes_to_buffer(1);
|
|
429
|
+
if (cur_subblock + 1 === p) {
|
|
430
|
+
buf[cur_subblock] = 0;
|
|
431
|
+
} else {
|
|
432
|
+
buf[cur_subblock] = p - cur_subblock - 1;
|
|
433
|
+
buf[p++] = 0;
|
|
434
|
+
}
|
|
435
|
+
return p;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
function GifReader(buf) {
|
|
439
|
+
var p = 0;
|
|
440
|
+
if (buf[p++] !== 71 || buf[p++] !== 73 || buf[p++] !== 70 || buf[p++] !== 56 || (buf[p++] + 1 & 253) !== 56 || buf[p++] !== 97) {
|
|
441
|
+
throw new Error("Invalid GIF 87a/89a header.");
|
|
442
|
+
}
|
|
443
|
+
var width = buf[p++] | buf[p++] << 8;
|
|
444
|
+
var height = buf[p++] | buf[p++] << 8;
|
|
445
|
+
var pf0 = buf[p++];
|
|
446
|
+
var global_palette_flag = pf0 >> 7;
|
|
447
|
+
var num_global_colors_pow2 = pf0 & 7;
|
|
448
|
+
var num_global_colors = 1 << num_global_colors_pow2 + 1;
|
|
449
|
+
buf[p++];
|
|
450
|
+
buf[p++];
|
|
451
|
+
var global_palette_offset = null;
|
|
452
|
+
var global_palette_size = null;
|
|
453
|
+
if (global_palette_flag) {
|
|
454
|
+
global_palette_offset = p;
|
|
455
|
+
global_palette_size = num_global_colors;
|
|
456
|
+
p += num_global_colors * 3;
|
|
457
|
+
}
|
|
458
|
+
var no_eof = true;
|
|
459
|
+
var frames = [];
|
|
460
|
+
var delay = 0;
|
|
461
|
+
var transparent_index = null;
|
|
462
|
+
var disposal = 0;
|
|
463
|
+
var loop_count = null;
|
|
464
|
+
this.width = width;
|
|
465
|
+
this.height = height;
|
|
466
|
+
while (no_eof && p < buf.length) {
|
|
467
|
+
switch (buf[p++]) {
|
|
468
|
+
case 33:
|
|
469
|
+
switch (buf[p++]) {
|
|
470
|
+
case 255:
|
|
471
|
+
if (buf[p] !== 11 || buf[p + 1] == 78 && buf[p + 2] == 69 && buf[p + 3] == 84 && buf[p + 4] == 83 && buf[p + 5] == 67 && buf[p + 6] == 65 && buf[p + 7] == 80 && buf[p + 8] == 69 && buf[p + 9] == 50 && buf[p + 10] == 46 && buf[p + 11] == 48 && buf[p + 12] == 3 && buf[p + 13] == 1 && buf[p + 16] == 0) {
|
|
472
|
+
p += 14;
|
|
473
|
+
loop_count = buf[p++] | buf[p++] << 8;
|
|
474
|
+
p++;
|
|
475
|
+
} else {
|
|
476
|
+
p += 12;
|
|
477
|
+
while (true) {
|
|
478
|
+
var block_size = buf[p++];
|
|
479
|
+
if (!(block_size >= 0)) throw Error("Invalid block size");
|
|
480
|
+
if (block_size === 0) break;
|
|
481
|
+
p += block_size;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
break;
|
|
485
|
+
|
|
486
|
+
case 249:
|
|
487
|
+
if (buf[p++] !== 4 || buf[p + 4] !== 0) throw new Error("Invalid graphics extension block.");
|
|
488
|
+
var pf1 = buf[p++];
|
|
489
|
+
delay = buf[p++] | buf[p++] << 8;
|
|
490
|
+
transparent_index = buf[p++];
|
|
491
|
+
if ((pf1 & 1) === 0) transparent_index = null;
|
|
492
|
+
disposal = pf1 >> 2 & 7;
|
|
493
|
+
p++;
|
|
494
|
+
break;
|
|
495
|
+
|
|
496
|
+
case 254:
|
|
497
|
+
while (true) {
|
|
498
|
+
var block_size = buf[p++];
|
|
499
|
+
if (!(block_size >= 0)) throw Error("Invalid block size");
|
|
500
|
+
if (block_size === 0) break;
|
|
501
|
+
p += block_size;
|
|
502
|
+
}
|
|
503
|
+
break;
|
|
504
|
+
|
|
505
|
+
default:
|
|
506
|
+
throw new Error("Unknown graphic control label: 0x" + buf[p - 1].toString(16));
|
|
507
|
+
}
|
|
508
|
+
break;
|
|
509
|
+
|
|
510
|
+
case 44:
|
|
511
|
+
var x = buf[p++] | buf[p++] << 8;
|
|
512
|
+
var y = buf[p++] | buf[p++] << 8;
|
|
513
|
+
var w = buf[p++] | buf[p++] << 8;
|
|
514
|
+
var h = buf[p++] | buf[p++] << 8;
|
|
515
|
+
var pf2 = buf[p++];
|
|
516
|
+
var local_palette_flag = pf2 >> 7;
|
|
517
|
+
var interlace_flag = pf2 >> 6 & 1;
|
|
518
|
+
var num_local_colors_pow2 = pf2 & 7;
|
|
519
|
+
var num_local_colors = 1 << num_local_colors_pow2 + 1;
|
|
520
|
+
var palette_offset = global_palette_offset;
|
|
521
|
+
var palette_size = global_palette_size;
|
|
522
|
+
var has_local_palette = false;
|
|
523
|
+
if (local_palette_flag) {
|
|
524
|
+
var has_local_palette = true;
|
|
525
|
+
palette_offset = p;
|
|
526
|
+
palette_size = num_local_colors;
|
|
527
|
+
p += num_local_colors * 3;
|
|
528
|
+
}
|
|
529
|
+
var data_offset = p;
|
|
530
|
+
p++;
|
|
531
|
+
while (true) {
|
|
532
|
+
var block_size = buf[p++];
|
|
533
|
+
if (!(block_size >= 0)) throw Error("Invalid block size");
|
|
534
|
+
if (block_size === 0) break;
|
|
535
|
+
p += block_size;
|
|
536
|
+
}
|
|
537
|
+
frames.push({
|
|
538
|
+
x: x,
|
|
539
|
+
y: y,
|
|
540
|
+
width: w,
|
|
541
|
+
height: h,
|
|
542
|
+
has_local_palette: has_local_palette,
|
|
543
|
+
palette_offset: palette_offset,
|
|
544
|
+
palette_size: palette_size,
|
|
545
|
+
data_offset: data_offset,
|
|
546
|
+
data_length: p - data_offset,
|
|
547
|
+
transparent_index: transparent_index,
|
|
548
|
+
interlaced: !!interlace_flag,
|
|
549
|
+
delay: delay,
|
|
550
|
+
disposal: disposal
|
|
551
|
+
});
|
|
552
|
+
break;
|
|
553
|
+
|
|
554
|
+
case 59:
|
|
555
|
+
no_eof = false;
|
|
556
|
+
break;
|
|
557
|
+
|
|
558
|
+
default:
|
|
559
|
+
throw new Error("Unknown gif block: 0x" + buf[p - 1].toString(16));
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
this.numFrames = function() {
|
|
563
|
+
return frames.length;
|
|
564
|
+
};
|
|
565
|
+
this.loopCount = function() {
|
|
566
|
+
return loop_count;
|
|
567
|
+
};
|
|
568
|
+
this.frameInfo = function(frame_num) {
|
|
569
|
+
if (frame_num < 0 || frame_num >= frames.length) throw new Error("Frame index out of range.");
|
|
570
|
+
return frames[frame_num];
|
|
571
|
+
};
|
|
572
|
+
this.decodeAndBlitFrameBGRA = function(frame_num, pixels) {
|
|
573
|
+
var frame = this.frameInfo(frame_num);
|
|
574
|
+
var num_pixels = frame.width * frame.height;
|
|
575
|
+
var index_stream = new Uint8Array(num_pixels);
|
|
576
|
+
GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels);
|
|
577
|
+
var palette_offset = frame.palette_offset;
|
|
578
|
+
var trans = frame.transparent_index;
|
|
579
|
+
if (trans === null) trans = 256;
|
|
580
|
+
var framewidth = frame.width;
|
|
581
|
+
var framestride = width - framewidth;
|
|
582
|
+
var xleft = framewidth;
|
|
583
|
+
var opbeg = (frame.y * width + frame.x) * 4;
|
|
584
|
+
var opend = ((frame.y + frame.height) * width + frame.x) * 4;
|
|
585
|
+
var op = opbeg;
|
|
586
|
+
var scanstride = framestride * 4;
|
|
587
|
+
if (frame.interlaced === true) {
|
|
588
|
+
scanstride += width * 4 * 7;
|
|
589
|
+
}
|
|
590
|
+
var interlaceskip = 8;
|
|
591
|
+
for (var i = 0, il = index_stream.length; i < il; ++i) {
|
|
592
|
+
var index = index_stream[i];
|
|
593
|
+
if (xleft === 0) {
|
|
594
|
+
op += scanstride;
|
|
595
|
+
xleft = framewidth;
|
|
596
|
+
if (op >= opend) {
|
|
597
|
+
scanstride = framestride * 4 + width * 4 * (interlaceskip - 1);
|
|
598
|
+
op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
|
|
599
|
+
interlaceskip >>= 1;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (index === trans) {
|
|
603
|
+
op += 4;
|
|
604
|
+
} else {
|
|
605
|
+
var r = buf[palette_offset + index * 3];
|
|
606
|
+
var g = buf[palette_offset + index * 3 + 1];
|
|
607
|
+
var b = buf[palette_offset + index * 3 + 2];
|
|
608
|
+
pixels[op++] = b;
|
|
609
|
+
pixels[op++] = g;
|
|
610
|
+
pixels[op++] = r;
|
|
611
|
+
pixels[op++] = 255;
|
|
612
|
+
}
|
|
613
|
+
--xleft;
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
this.decodeAndBlitFrameRGBA = function(frame_num, pixels) {
|
|
617
|
+
var frame = this.frameInfo(frame_num);
|
|
618
|
+
var num_pixels = frame.width * frame.height;
|
|
619
|
+
var index_stream = new Uint8Array(num_pixels);
|
|
620
|
+
GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels);
|
|
621
|
+
var palette_offset = frame.palette_offset;
|
|
622
|
+
var trans = frame.transparent_index;
|
|
623
|
+
if (trans === null) trans = 256;
|
|
624
|
+
var framewidth = frame.width;
|
|
625
|
+
var framestride = width - framewidth;
|
|
626
|
+
var xleft = framewidth;
|
|
627
|
+
var opbeg = (frame.y * width + frame.x) * 4;
|
|
628
|
+
var opend = ((frame.y + frame.height) * width + frame.x) * 4;
|
|
629
|
+
var op = opbeg;
|
|
630
|
+
var scanstride = framestride * 4;
|
|
631
|
+
if (frame.interlaced === true) {
|
|
632
|
+
scanstride += width * 4 * 7;
|
|
633
|
+
}
|
|
634
|
+
var interlaceskip = 8;
|
|
635
|
+
for (var i = 0, il = index_stream.length; i < il; ++i) {
|
|
636
|
+
var index = index_stream[i];
|
|
637
|
+
if (xleft === 0) {
|
|
638
|
+
op += scanstride;
|
|
639
|
+
xleft = framewidth;
|
|
640
|
+
if (op >= opend) {
|
|
641
|
+
scanstride = framestride * 4 + width * 4 * (interlaceskip - 1);
|
|
642
|
+
op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
|
|
643
|
+
interlaceskip >>= 1;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (index === trans) {
|
|
647
|
+
op += 4;
|
|
648
|
+
} else {
|
|
649
|
+
var r = buf[palette_offset + index * 3];
|
|
650
|
+
var g = buf[palette_offset + index * 3 + 1];
|
|
651
|
+
var b = buf[palette_offset + index * 3 + 2];
|
|
652
|
+
pixels[op++] = r;
|
|
653
|
+
pixels[op++] = g;
|
|
654
|
+
pixels[op++] = b;
|
|
655
|
+
pixels[op++] = 255;
|
|
656
|
+
}
|
|
657
|
+
--xleft;
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) {
|
|
663
|
+
var min_code_size = code_stream[p++];
|
|
664
|
+
var clear_code = 1 << min_code_size;
|
|
665
|
+
var eoi_code = clear_code + 1;
|
|
666
|
+
var next_code = eoi_code + 1;
|
|
667
|
+
var cur_code_size = min_code_size + 1;
|
|
668
|
+
var code_mask = (1 << cur_code_size) - 1;
|
|
669
|
+
var cur_shift = 0;
|
|
670
|
+
var cur = 0;
|
|
671
|
+
var op = 0;
|
|
672
|
+
var subblock_size = code_stream[p++];
|
|
673
|
+
var code_table = new Int32Array(4096);
|
|
674
|
+
var prev_code = null;
|
|
675
|
+
while (true) {
|
|
676
|
+
while (cur_shift < 16) {
|
|
677
|
+
if (subblock_size === 0) break;
|
|
678
|
+
cur |= code_stream[p++] << cur_shift;
|
|
679
|
+
cur_shift += 8;
|
|
680
|
+
if (subblock_size === 1) {
|
|
681
|
+
subblock_size = code_stream[p++];
|
|
682
|
+
} else {
|
|
683
|
+
--subblock_size;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (cur_shift < cur_code_size) break;
|
|
687
|
+
var code = cur & code_mask;
|
|
688
|
+
cur >>= cur_code_size;
|
|
689
|
+
cur_shift -= cur_code_size;
|
|
690
|
+
if (code === clear_code) {
|
|
691
|
+
next_code = eoi_code + 1;
|
|
692
|
+
cur_code_size = min_code_size + 1;
|
|
693
|
+
code_mask = (1 << cur_code_size) - 1;
|
|
694
|
+
prev_code = null;
|
|
695
|
+
continue;
|
|
696
|
+
} else if (code === eoi_code) {
|
|
697
|
+
break;
|
|
698
|
+
}
|
|
699
|
+
var chase_code = code < next_code ? code : prev_code;
|
|
700
|
+
var chase_length = 0;
|
|
701
|
+
var chase = chase_code;
|
|
702
|
+
while (chase > clear_code) {
|
|
703
|
+
chase = code_table[chase] >> 8;
|
|
704
|
+
++chase_length;
|
|
705
|
+
}
|
|
706
|
+
var k = chase;
|
|
707
|
+
var op_end = op + chase_length + (chase_code !== code ? 1 : 0);
|
|
708
|
+
if (op_end > output_length) {
|
|
709
|
+
console.log("Warning, gif stream longer than expected.");
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
output[op++] = k;
|
|
713
|
+
op += chase_length;
|
|
714
|
+
var b = op;
|
|
715
|
+
if (chase_code !== code) output[op++] = k;
|
|
716
|
+
chase = chase_code;
|
|
717
|
+
while (chase_length--) {
|
|
718
|
+
chase = code_table[chase];
|
|
719
|
+
output[--b] = chase & 255;
|
|
720
|
+
chase >>= 8;
|
|
721
|
+
}
|
|
722
|
+
if (prev_code !== null && next_code < 4096) {
|
|
723
|
+
code_table[next_code++] = prev_code << 8 | k;
|
|
724
|
+
if (next_code >= code_mask + 1 && cur_code_size < 12) {
|
|
725
|
+
++cur_code_size;
|
|
726
|
+
code_mask = code_mask << 1 | 1;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
prev_code = code;
|
|
730
|
+
}
|
|
731
|
+
if (op !== output_length) {
|
|
732
|
+
console.log("Warning, gif stream shorter than expected.");
|
|
733
|
+
}
|
|
734
|
+
return output;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
try {
|
|
738
|
+
GifWriter_1 = omggif.GifWriter = GifWriter;
|
|
739
|
+
GifReader_1 = omggif.GifReader = GifReader;
|
|
740
|
+
} catch (e) {}
|
|
741
|
+
|
|
742
|
+
class OmgFilmDecoder extends FilmDecoder {
|
|
743
|
+
constructor() {
|
|
744
|
+
super(...arguments);
|
|
745
|
+
this.restoreImageData = null;
|
|
746
|
+
}
|
|
747
|
+
decodeHeader(data) {
|
|
748
|
+
return __awaiter(this, void 0, void 0, function*() {
|
|
749
|
+
const decoder = this.decoder = new GifReader_1(new Uint8Array(data));
|
|
750
|
+
const {width: width, height: height} = decoder;
|
|
751
|
+
this.width = width;
|
|
752
|
+
this.height = height;
|
|
753
|
+
this.total = decoder.numFrames();
|
|
754
|
+
this.loop = decoder.loopCount() || 0;
|
|
755
|
+
this.bufferCanvas = draw.Platform.origin.createCanvas(width, height);
|
|
756
|
+
this.bufferContext = this.bufferCanvas.getContext("2d");
|
|
757
|
+
this.decodeBuffer = new Uint8ClampedArray(width * height * 4);
|
|
758
|
+
this.sharedImageData = this.bufferContext.createImageData(width, height);
|
|
759
|
+
this.createAtlas();
|
|
760
|
+
yield this.decodeFrame(0);
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
decodeOneFrame(frameIndex) {
|
|
764
|
+
return __awaiter(this, void 0, void 0, function*() {
|
|
765
|
+
const {decoder: decoder, decodeBuffer: decodeBuffer, bufferCanvas: bufferCanvas, bufferContext: bufferContext, sharedImageData: sharedImageData} = this;
|
|
766
|
+
const info = decoder.frameInfo(frameIndex);
|
|
767
|
+
if (info.disposal === 3) this.restoreImageData = bufferContext.getImageData(0, 0, this.width, this.height);
|
|
768
|
+
decoder.decodeAndBlitFrameRGBA(frameIndex, decodeBuffer);
|
|
769
|
+
sharedImageData.data.set(decodeBuffer);
|
|
770
|
+
bufferContext.putImageData(sharedImageData, 0, 0);
|
|
771
|
+
let image;
|
|
772
|
+
if (this.atlas) {
|
|
773
|
+
image = bufferCanvas;
|
|
774
|
+
} else {
|
|
775
|
+
image = draw.Platform.origin.createCanvas(this.width, this.height);
|
|
776
|
+
const frameCtx = image.getContext("2d");
|
|
777
|
+
frameCtx.drawImage(bufferCanvas, 0, 0);
|
|
778
|
+
}
|
|
779
|
+
const frame = {
|
|
780
|
+
image: image,
|
|
781
|
+
duration: (info.delay || 10) / 100
|
|
782
|
+
};
|
|
783
|
+
this.frames[frameIndex] = frame;
|
|
784
|
+
if (this.atlas) this.mergeFrame(frameIndex, false);
|
|
785
|
+
this.applyDisposal(info);
|
|
786
|
+
return frame;
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
applyDisposal(info) {
|
|
790
|
+
const {bufferContext: bufferContext, restoreImageData: restoreImageData} = this;
|
|
791
|
+
const disposal = info.disposal;
|
|
792
|
+
if (disposal === 2) {
|
|
793
|
+
bufferContext.clearRect(info.x, info.y, info.width, info.height);
|
|
794
|
+
} else if (disposal === 3) {
|
|
795
|
+
if (restoreImageData) {
|
|
796
|
+
bufferContext.putImageData(restoreImageData, 0, 0);
|
|
797
|
+
this.restoreImageData = null;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
destoryFrameImage(frame) {
|
|
802
|
+
if (!frame.image) return;
|
|
803
|
+
const canvas = frame.image;
|
|
804
|
+
canvas.width = 0;
|
|
805
|
+
canvas.height = 0;
|
|
806
|
+
delete frame.image;
|
|
807
|
+
}
|
|
808
|
+
destroyDecoder() {
|
|
809
|
+
if (this.bufferCanvas) {
|
|
810
|
+
this.bufferCanvas.width = 0;
|
|
811
|
+
this.bufferCanvas.height = 0;
|
|
812
|
+
this.decoder = null;
|
|
813
|
+
this.bufferCanvas = null;
|
|
814
|
+
this.bufferContext = null;
|
|
815
|
+
this.decodeBuffer = null;
|
|
816
|
+
this.sharedImageData = null;
|
|
817
|
+
this.restoreImageData = null;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
function getFileExt(url) {
|
|
823
|
+
if (!url) return "";
|
|
824
|
+
if (url.startsWith("data:")) {
|
|
825
|
+
const head = url.slice(5, url.indexOf(","));
|
|
826
|
+
const slash = head.indexOf("/");
|
|
827
|
+
const semi = head.indexOf(";");
|
|
828
|
+
return slash > -1 ? head.slice(slash + 1, semi > -1 ? semi : undefined).toLowerCase() : "";
|
|
829
|
+
}
|
|
830
|
+
let end = url.length;
|
|
831
|
+
const q = url.indexOf("?");
|
|
832
|
+
const h = url.indexOf("#");
|
|
833
|
+
if (q > -1 && q < end) end = q;
|
|
834
|
+
if (h > -1 && h < end) end = h;
|
|
835
|
+
const dot = url.lastIndexOf(".", end);
|
|
836
|
+
const slash = url.lastIndexOf("/", end);
|
|
837
|
+
return dot > slash ? url.slice(dot + 1, end).toLowerCase() : "";
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
class FilmData extends draw.ImageData {
|
|
841
|
+
get __urlType() {
|
|
842
|
+
return "film";
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
class PaintFilm {
|
|
847
|
+
get playerOptions() {
|
|
848
|
+
const {fill: fill} = (this.element || this).__;
|
|
849
|
+
return draw.isArray(fill) && fill.find(item => item.type === "film");
|
|
850
|
+
}
|
|
851
|
+
get decoder() {
|
|
852
|
+
const {playerOptions: playerOptions} = this;
|
|
853
|
+
return playerOptions && playerOptions.image && playerOptions.image.view;
|
|
854
|
+
}
|
|
855
|
+
constructor(element) {
|
|
856
|
+
this.element = element;
|
|
857
|
+
}
|
|
858
|
+
togglePlay() {
|
|
859
|
+
const {playerOptions: playerOptions} = this;
|
|
860
|
+
if (playerOptions) {
|
|
861
|
+
if (playerOptions.paused) this.play(); else this.pause();
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
play() {
|
|
865
|
+
const {playerOptions: playerOptions} = this;
|
|
866
|
+
if (playerOptions && playerOptions.paused) {
|
|
867
|
+
delete playerOptions.paused;
|
|
868
|
+
(this.element || this).forceRender();
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
pause() {
|
|
872
|
+
const {playerOptions: playerOptions} = this;
|
|
873
|
+
if (playerOptions) playerOptions.paused = true;
|
|
874
|
+
}
|
|
875
|
+
stop() {
|
|
876
|
+
const {playerOptions: playerOptions} = this;
|
|
877
|
+
if (playerOptions) {
|
|
878
|
+
delete playerOptions.frameTime;
|
|
879
|
+
playerOptions.nowIndex = 0;
|
|
880
|
+
this.pause();
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
seekFrame(frameIndex) {
|
|
884
|
+
const {playerOptions: playerOptions} = this;
|
|
885
|
+
if (playerOptions) {
|
|
886
|
+
playerOptions.nowIndex = frameIndex;
|
|
887
|
+
(this.element || this).forceRender();
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
exports.Film = class Film extends draw.Image {
|
|
893
|
+
get __tag() {
|
|
894
|
+
return "Film";
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
__decorate([ draw.dataProcessor(FilmData) ], exports.Film.prototype, "__", void 0);
|
|
899
|
+
|
|
900
|
+
exports.Film = __decorate([ draw.useModule(PaintFilm), draw.registerUI() ], exports.Film);
|
|
901
|
+
|
|
902
|
+
draw.Plugin.add("flim");
|
|
903
|
+
|
|
904
|
+
draw.PaintImage.film = function(paint, oldPaint) {
|
|
905
|
+
paint.film = true;
|
|
906
|
+
paint.nowIndex = 0;
|
|
907
|
+
if (draw.isObject(oldPaint)) {
|
|
908
|
+
paint.nowIndex = oldPaint.nowIndex;
|
|
909
|
+
paint.pauseIndex = oldPaint.pauseIndex;
|
|
910
|
+
paint.speed = oldPaint.speed;
|
|
911
|
+
paint.paused = oldPaint.paused;
|
|
912
|
+
paint.loop = oldPaint.loop;
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
draw.Creator.film = function(options) {
|
|
917
|
+
return new draw.LeaferFilm(options);
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
draw.Resource.loadFilm = function(key, format) {
|
|
921
|
+
return new Promise((resolve, reject) => {
|
|
922
|
+
const config = {
|
|
923
|
+
url: key
|
|
924
|
+
};
|
|
925
|
+
if (format) config.format = format;
|
|
926
|
+
const film = draw.Creator.film(config);
|
|
927
|
+
draw.Resource.set(key, film);
|
|
928
|
+
film.load(() => resolve(film), e => reject(e));
|
|
929
|
+
});
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
draw.LeaferFilm.prototype.render = function(canvas, x, y, width, height, leaf, paint, imageScaleX, imageScaleY) {
|
|
933
|
+
this.view.render(canvas, x, y, width, height, leaf, paint, imageScaleX, imageScaleY);
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
FilmDecoder.register("gif", OmgFilmDecoder);
|
|
937
|
+
|
|
938
|
+
draw.Platform.origin.loadFilm = function(url, _crossOrigin, leaferFilm) {
|
|
939
|
+
return __awaiter(this, void 0, void 0, function*() {
|
|
940
|
+
const buffer = yield draw.Platform.origin.loadContent(url, "arrayBuffer");
|
|
941
|
+
let ext = getFileExt(url);
|
|
942
|
+
if (!ext) {
|
|
943
|
+
if (leaferFilm) ext = leaferFilm.config.format;
|
|
944
|
+
if (!ext) ext = "gif";
|
|
945
|
+
}
|
|
946
|
+
const mimeType = draw.FileHelper.mimeType(ext);
|
|
947
|
+
const canUseFilmDecoder = yield FilmDecoder.canUse(mimeType);
|
|
948
|
+
let Decoder;
|
|
949
|
+
const tool = FilmDecoder.decoderMap[ext];
|
|
950
|
+
if (!tool || canUseFilmDecoder && !tool.force) Decoder = FilmDecoder; else Decoder = tool.Decoder;
|
|
951
|
+
if (!Decoder) throw new Error("no decoder: " + mimeType);
|
|
952
|
+
const decoder = new Decoder;
|
|
953
|
+
yield decoder.decodeHeader(buffer, mimeType);
|
|
954
|
+
return decoder;
|
|
955
|
+
});
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
exports.FilmData = FilmData;
|
|
959
|
+
|
|
960
|
+
exports.FilmDecoder = FilmDecoder;
|
|
961
|
+
|
|
962
|
+
exports.PaintFilm = PaintFilm;
|