Skip to content

Commit e35e13f

Browse files
committed
read a gif and add some options
1 parent 3caaeb4 commit e35e13f

File tree

1 file changed

+65
-34
lines changed
  • packages/2d/src/Components

1 file changed

+65
-34
lines changed

packages/2d/src/Components/GIF.ts

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,93 @@
11
import { AnimationAPI, AnimationFrame } from './Animation';
22
import { useType } from '@hex-engine/core';
3-
import gifken from 'gifken';
3+
import gifken, { Gif } from 'gifken';
44

5-
interface GIFInterface extends AnimationAPI<{}> {
5+
interface GIFInterface extends AnimationAPI<HTMLImageElement> {
6+
getGif(): Gif,
67
drawCurrentFrame(context: CanvasRenderingContext2D): void;
78
}
89

9-
export default function GIF(options: { url: string }): GIFInterface {
10+
export default function GIF(options: { url: string, width: number, height: number, fps?: number, compressed?: boolean, loop?: boolean }): GIFInterface {
1011
useType(GIF);
11-
let frames: any[] = [];
12+
let gif: Gif = new Gif();
13+
let frames: AnimationFrame<HTMLImageElement>[] = [];
14+
let play: boolean = false;
1215
let i = 0;
1316

14-
var xhr = new XMLHttpRequest();
15-
xhr.open("GET", options.url, true);
16-
xhr.responseType = "arraybuffer";
17-
xhr.onload = (e: any) => {
18-
var arrayBuffer = e.target["response"];
19-
var gif = gifken.Gif.parse(arrayBuffer);
20-
21-
frames = gif.split(false).map(frame => {
22-
const url = URL.createObjectURL(new Blob(frame.writeToArrayBuffer())).toString();
23-
const img = document.createElement('img');
24-
img.src = url;
25-
return img
17+
load(options.url).then(arrayBuffer => {
18+
gif = gifken.Gif.parse(arrayBuffer);
19+
frames = getFrames({
20+
gif,
21+
width: options.width,
22+
height: options.height,
23+
compressed: options.compressed
2624
})
27-
};
28-
xhr.send();
2925

26+
setInterval(() => {
27+
if (frames.length - 1 > i && play) {
28+
i++;
29+
}
30+
31+
if(frames.length - 1 <= i && options.loop && play) {
32+
i = 0;
33+
}
34+
}, 30)
35+
})
36+
37+
3038
return {
39+
getGif() {
40+
return gif;
41+
},
3142
drawCurrentFrame(context: CanvasRenderingContext2D) {
32-
if(frames.length !== 0) {
33-
context.drawImage(frames[i], 0, 0);
34-
if(frames.length - 1 > i) {
35-
i++;
36-
}
43+
if(frames.length !== 0 && play) {
44+
context.drawImage(frames[i].data, 0, 0);
3745
}
3846
},
39-
frames: [],
40-
loop: false,
41-
currentFrameIndex: 0,
42-
currentFrame: new AnimationFrame({}, {
43-
duration: 0,
44-
}),
47+
frames: frames,
48+
loop: options.loop || false,
49+
currentFrameIndex: i,
50+
currentFrame: frames[i],
4551
currentFrameCompletion: 0,
4652
pause() {
47-
return void 0;
53+
play = false;
4854
},
4955
resume() {
50-
return void 0;
56+
play = true;
5157
},
5258
play() {
53-
return void 0;
59+
play = true;
5460
},
5561
restart() {
56-
return void 0;
62+
i = 0;
63+
play = true;
5764
},
5865
goToFrame(frameNumber: number) {
59-
return frameNumber;
66+
i = frameNumber;
6067
},
6168
}
69+
}
70+
71+
async function load(url: string) {
72+
return await fetch(url)
73+
.then((res) => res.arrayBuffer());
74+
}
75+
76+
function getFrames({ gif, width, height, compressed = false }: {
77+
gif: Gif,
78+
width: number,
79+
height: number,
80+
compressed?: boolean,
81+
}){
82+
return gif.split(compressed).map(frame => {
83+
const blob = gifken.GifPresenter.writeToBlob(frame.writeToArrayBuffer())
84+
const url = URL.createObjectURL(blob).toString();
85+
const img = document.createElement('img');
86+
img.width = width;
87+
img.height = height;
88+
img.src = url;
89+
return new AnimationFrame<HTMLImageElement>(img, {
90+
duration: 0,
91+
});
92+
});
6293
}

0 commit comments

Comments
 (0)