UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1 lines 11.4 kB
{"version":3,"file":"GifSource.mjs","sources":["../../src/gif/GifSource.ts"],"sourcesContent":["import { decompressFrames, type ParsedFrame, parseGIF } from 'gifuct-js';\nimport { DOMAdapter } from '../environment/adapter';\nimport { CanvasSource, type CanvasSourceOptions } from '../rendering/renderers/shared/texture/sources/CanvasSource';\nimport { Texture } from '../rendering/renderers/shared/texture/Texture';\n\n/**\n * Represents a single frame of a GIF. Includes image and timing data.\n * @category gif\n * @advanced\n */\ninterface GifFrame\n{\n /** Image data for the current frame */\n texture: Texture<CanvasSource>;\n /** The start of the current frame, in milliseconds */\n start: number;\n /** The end of the current frame, in milliseconds */\n end: number;\n}\n\n/**\n * Options when constructing from buffer\n * @category gif\n * @advanced\n */\ninterface GifBufferOptions extends Omit<CanvasSourceOptions, 'resource'>\n{\n /** FPS to use when the GIF animation doesn't define any delay between frames */\n fps?: number;\n}\n\n/**\n * Resource provided to GifSprite instances. This is very similar to using a shared\n * Texture between Sprites. This source contains all the frames and animation needed\n * to support playback.\n * @category gif\n * @advanced\n */\nclass GifSource\n{\n /** Width of the animation */\n public readonly width: number;\n\n /** Height of the animation */\n public readonly height: number;\n\n /** The total time to play the animation in milliseconds */\n public readonly duration: number;\n\n /** Animation frames */\n public readonly frames: GifFrame[];\n\n /** Textures */\n public readonly textures: Texture<CanvasSource>[];\n\n /** Total number of frames in the animation */\n public readonly totalFrames: number;\n\n /**\n * @param frames - Array of GifFrame instances.\n */\n constructor(frames: GifFrame[])\n {\n // #if _DEBUG\n if (!frames || !frames.length) throw new Error('Invalid frames');\n // #endif\n\n // All frames are the same size, get the first frame's size\n const [{ texture: { width, height } }] = frames;\n\n this.width = width;\n this.height = height;\n this.frames = frames;\n this.textures = this.frames.map((frame) => frame.texture);\n this.totalFrames = this.frames.length;\n this.duration = this.frames[this.totalFrames - 1].end;\n }\n\n /** Destroy animation data and don't use after this */\n public destroy()\n {\n for (const texture of this.textures)\n {\n texture.destroy(true);\n }\n for (const frame of this.frames)\n {\n frame.texture = null;\n }\n this.frames.length = 0;\n this.textures.length = 0;\n Object.assign(this, {\n frames: null,\n textures: null,\n width: 0,\n height: 0,\n duration: 0,\n totalFrames: 0,\n });\n }\n\n /**\n * Create an animated GIF animation from a GIF image's ArrayBuffer. The easiest way to get\n * the buffer is to use Assets.\n * @example\n * import { GifSource, GifSprite } from 'pixi.js/gif';\n *\n * const buffer = await fetch('./file.gif').then(res => res.arrayBuffer());\n * const source = GifSource.from(buffer);\n * const sprite = new GifSprite(source);\n * @param buffer - GIF image arraybuffer from Assets.\n * @param options - Optional options to use when building from buffer.\n */\n public static from(buffer: ArrayBuffer, options?: GifBufferOptions): GifSource\n {\n if (!buffer || buffer.byteLength === 0)\n {\n throw new Error('Invalid buffer');\n }\n\n // fix https://github.com/matt-way/gifuct-js/issues/30\n const validateAndFix = (gif: any): void =>\n {\n let currentGce = null;\n\n for (const frame of gif.frames)\n {\n currentGce = frame.gce ?? currentGce;\n\n // fix loosing graphic control extension for same frames\n if ('image' in frame && !('gce' in frame))\n {\n frame.gce = currentGce;\n }\n }\n };\n\n const gif = parseGIF(buffer);\n\n validateAndFix(gif);\n const gifFrames = decompressFrames(gif, true);\n const frames: GifFrame[] = [];\n const animWidth = gif.lsd.width;\n const animHeight = gif.lsd.height;\n\n // Temporary canvases required for compositing frames\n const canvas = DOMAdapter.get().createCanvas(animWidth, animHeight);\n const context = canvas.getContext('2d', { willReadFrequently: true });\n const patchCanvas = DOMAdapter.get().createCanvas();\n const patchContext = patchCanvas.getContext('2d');\n\n let time = 0;\n let previousFrame: ImageData | null = null;\n\n // Some GIFs have a non-zero frame delay, so we need to calculate the fallback\n const { fps = 30, ...canvasSourceOptions } = options ?? {};\n const defaultDelay = 1000 / fps;\n\n // Precompute each frame and store as ImageData\n for (let i = 0; i < gifFrames.length; i++)\n {\n // Some GIF's omit the disposalType, so let's assume clear if missing\n const {\n disposalType = 2,\n delay = defaultDelay,\n patch,\n dims: { width, height, left, top },\n } = gifFrames[i] as ParsedFrame;\n\n patchCanvas.width = width;\n patchCanvas.height = height;\n patchContext.clearRect(0, 0, width, height);\n const patchData = patchContext.createImageData(width, height);\n\n patchData.data.set(patch);\n patchContext.putImageData(patchData, 0, 0);\n\n if (disposalType === 3)\n {\n previousFrame = context.getImageData(0, 0, animWidth, animHeight);\n }\n\n context.drawImage(patchCanvas as CanvasImageSource, left, top);\n const imageData = context.getImageData(0, 0, animWidth, animHeight);\n\n if (disposalType === 2)\n {\n context.clearRect(0, 0, animWidth, animHeight);\n }\n else if (disposalType === 3)\n {\n context.putImageData(previousFrame as ImageData, 0, 0);\n }\n\n // Create new texture\n const resource = DOMAdapter.get().createCanvas(\n imageData.width,\n imageData.height\n ) as HTMLCanvasElement;\n const resourceContext = resource.getContext('2d');\n\n resourceContext.putImageData(imageData, 0, 0);\n\n frames.push({\n start: time,\n end: time + delay,\n texture: new Texture({\n source: new CanvasSource({\n resource,\n ...canvasSourceOptions,\n }),\n }),\n });\n time += delay;\n }\n\n // clear the canvases\n canvas.width = canvas.height = 0;\n patchCanvas.width = patchCanvas.height = 0;\n\n return new GifSource(frames);\n }\n}\n\nexport { GifBufferOptions, GifFrame, GifSource };\n"],"names":["gif"],"mappings":"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"}