Last active
March 24, 2018 17:24
-
-
Save friendlyanon/c63fe71a01001ce744b94cb65a8fca1e to your computer and use it in GitHub Desktop.
Worker addition for gif-engine-js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const getDisposals = frameObj => frameObj.graphicExtension && frameObj.graphicExtension.disposalMethod || 0; | |
const getDelays = frameObj => frameObj.graphicExtension && frameObj.graphicExtension.delay - 1 || 0; | |
const copyColorsTransparent = async (source, target, fWidth, fHeight, oLeft, oTop, cWidth, flag) => { | |
for (let row = 0, pointer = -1; fHeight > row; ++row) | |
for (let column = 0; fWidth > column; ++column) { | |
let offset = (column + oLeft + (row + oTop) * cWidth) * 4; | |
if (flag && source[pointer + 4] === 0) { | |
pointer += 4; | |
continue; | |
} | |
target[ offset] = source[++pointer]; | |
target[++offset] = source[++pointer]; | |
target[++offset] = source[++pointer]; ++pointer; | |
target[++offset] = flag ? source[pointer] : 255; | |
} | |
}; | |
const copyColors = async (source, target, fWidth, fHeight, oLeft, oTop, cWidth) => { | |
for (let row = 0, pointer = -1; fHeight > row; ++row) | |
for (let column = 0; fWidth > column; ++column) { | |
let offset = (column + oLeft + (row + oTop) * cWidth) * 4; | |
target[++pointer] = source[ offset]; | |
target[++pointer] = source[++offset]; | |
target[++pointer] = source[++offset]; | |
target[++pointer] = source[++offset]; | |
} | |
}; | |
const messageHandler = async e => { | |
const o = await GIF( | |
await ( | |
await fetch(e.data, { headers: { pragma: "no-cache", "cache-control": "no-cache" }}) | |
).arrayBuffer() | |
); | |
const frameCount = o.frames.length; | |
const compiledFrames = new Array(frameCount); | |
const delays = o.frames.map(getDelays); | |
const canvasWidth = o.descriptor.width; | |
const canvasHeight = o.descriptor.height; | |
const disposals = o.frames.map(getDisposals); | |
const canvas = new Uint8ClampedArray(canvasWidth * canvasHeight * 4); | |
let index = 0; | |
do { | |
const frame = o.frames[index]; | |
const transparentColorFlag = frame.graphicExtension && frame.graphicExtension.transparentColorFlag; | |
const [ | |
{ | |
data: frameImageData, | |
width: frameWidth, | |
height: frameHeight | |
}, | |
offsetLeft, | |
offsetTop | |
] = await o.toImageData(index); | |
switch(disposals[index]) { | |
case 2: | |
for (let row = 0; frameHeight > row; ++row) | |
for (let column = 0; frameWidth > column; ++column) { | |
let offset = (column + offsetLeft + (row + offsetTop) * canvasWidth) * 4; | |
canvas[ offset] = 0; | |
canvas[++offset] = 0; | |
canvas[++offset] = 0; | |
canvas[++offset] = transparentColorFlag ? 0 : 255; | |
} break; | |
case 3: | |
if (index > 0) { | |
const [ | |
{ | |
data: frameImageData, | |
width: frameWidth, | |
height: frameHeight | |
}, | |
offsetLeft, | |
offsetTop | |
] = compiledFrames[index - 1]; | |
await copyColors(frameImageData, canvas, frameWidth, frameHeight, offsetLeft, offsetTop, canvasWidth); | |
} break; | |
} | |
await copyColorsTransparent(frameImageData, canvas, frameWidth, frameHeight, offsetLeft, offsetTop, canvasWidth, transparentColorFlag); | |
await copyColors(canvas, frameImageData, frameWidth, frameHeight, offsetLeft, offsetTop, canvasWidth); | |
compiledFrames[index] = [new ImageData(frameImageData, frameWidth, frameHeight), offsetLeft, offsetTop]; | |
} while(++index < frameCount); | |
postMessage([compiledFrames, delays, canvasWidth, canvasHeight]); | |
}; | |
(global => { | |
global.onmessage = messageHandler; | |
global.onerror = e => { | |
postMessage(["log", e]); | |
}; | |
})((() => this)()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment