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.5 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 } 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\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 defaultDelay = 1000 / (options?.fps ?? 30);\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 }),\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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"}