2023-11-04 13:06:49 -06:00

64 lines
1.6 KiB
TypeScript

import { Vector } from "../geometry/vector.ts";
import { Frame, handleGIF } from "../processing/gif.ts";
type frame = { canvas: HTMLCanvasElement } & Frame;
export class GIFAnimation {
frames: frame[] = [];
canvas: HTMLCanvasElement;
ctx!: CanvasRenderingContext2D;
ready = false;
constructor(
url: string,
private origin: Vector,
private scale = 1,
) {
this.canvas = document.createElement("canvas");
this.init(url);
}
async init(url: string) {
const res = await fetch(url);
const buf = new Uint8Array(await res.arrayBuffer());
const gif = handleGIF(buf);
this.frames = gif.frames;
this.frameTimes = this.frames.map((f) => f.delay);
this.totalAnimationTime = this.frameTimes.reduce(
(a, b) => a + b,
0,
);
this.canvas.width = gif.w;
this.canvas.height = gif.h;
this.ctx = this.canvas.getContext("2d")!;
this.ready = true;
}
frameTimes!: number[];
totalAnimationTime = 0;
_frameCounter = 0;
currentFrameIndex = 0;
draw(timeSinceLastFrame: number) {
if (!this.ready) return;
this._frameCounter += timeSinceLastFrame;
const currentFrameDelay = this.frames[this.currentFrameIndex].delay * 10;
while (this._frameCounter >= currentFrameDelay) {
this._frameCounter -= currentFrameDelay;
this.currentFrameIndex = (this.currentFrameIndex + 1) %
this.frames.length;
}
const currentFrame = this.frames[this.currentFrameIndex];
doodler.drawImage(
currentFrame.canvas,
this.origin,
this.canvas.width * this.scale,
this.canvas.height * this.scale,
);
}
}