refactor(gif encoder): expose an Event Emitter API

This commit is contained in:
wryk 2019-03-12 20:14:54 +01:00
parent 73d37d2c23
commit 481e30a01c
5 changed files with 47 additions and 51 deletions

19
package-lock.json generated
View file

@ -3095,6 +3095,11 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
"dev": true
},
"eventemitter3": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
"integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA=="
},
"events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
@ -3510,14 +3515,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -3537,8 +3540,7 @@
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
@ -3686,7 +3688,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -3694,8 +3695,7 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"minipass": {
"version": "2.3.5",
@ -3799,8 +3799,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"object-assign": {
"version": "4.1.1",

View file

@ -9,6 +9,7 @@
"lint-fix": "eslint --ext .js,vue . --fix"
},
"dependencies": {
"eventemitter3": "^3.1.0",
"gif-writer": "^0.9.3",
"postcss-modules": "^1.4.1",
"vue": "^2.6.6",

View file

@ -1,40 +1,42 @@
// import EncodeWorker from './encode.worker.js'
import EventEmitter from 'eventemitter3'
const PALETTE_SIZE = 255
export function encode ({ imageDataList, imageWidth, imageHeight, delayTime }) {
return new Promise((resolve, reject) => {
const worker = new Worker('/services/encode.worker.js')
const emitter = new EventEmitter()
const worker = new Worker('/services/encode.worker.js')
worker.onerror = error => reject(error)
worker.onerror = error => emitter.emit('error', error)
worker.onmessageerror = error => emitter.emit('error', error)
worker.onmessage = event => {
const { type, payload } = event.data
worker.onmessage = event => {
const { type, payload } = event.data
switch (type) {
default:
reject(new Error(`Unexpected worker message with type ${type}`))
break
switch (type) {
default:
emitter.emit('error', new Error(`Unexpected worker message with type ${type}`))
break
case 'progress':
console.log(`Encoding progress : ${payload.value}`)
break
case 'progress':
emitter.emit('progress', payload.value)
break
case 'done':
const byteArray = new Uint8Array(payload.buffer)
const blob = new Blob([byteArray], { type: 'image/gif' })
const objectUrl = URL.createObjectURL(blob)
resolve(objectUrl)
break
}
case 'done':
const byteArray = new Uint8Array(payload.buffer)
const blob = new Blob([byteArray], { type: 'image/gif' })
const objectUrl = URL.createObjectURL(blob)
emitter.emit('done', objectUrl)
break
}
}
worker.postMessage({
imageDataList,
imageWidth,
imageHeight,
paletteSize: PALETTE_SIZE,
delayTime
})
worker.postMessage({
imageDataList,
imageWidth,
imageHeight,
paletteSize: PALETTE_SIZE,
delayTime
})
return emitter
}

View file

@ -7,17 +7,13 @@ import {
onmessage = (event) => {
const { imageDataList, imageWidth, imageHeight, paletteSize, delayTime } = event.data
console.log('Write GIF')
const outputStream = new OutputStream()
const writer = new GifWriter(outputStream)
postProgressMessage(0)
console.log(`Write header`)
writer.writeHeader()
console.log(`Write logical screen informations`)
writer.writeLogicalScreenInfo({
width: imageWidth,
height: imageHeight
@ -26,19 +22,16 @@ onmessage = (event) => {
writer.writeLoopControlInfo(0)
const indexedColorImages = imageDataList.map((imageData, index, { length }) => {
console.log(`Convert frame ${index} ImageData to IndexedColorImage`)
const indexedColorImage = imageDataToIndexedColorImage(imageData, paletteSize)
postProgressMessage(calcProgress(0, 0.9, length, index + 1))
return indexedColorImage
})
indexedColorImages.forEach((indexedColorImage, index, { length }) => {
console.log(`Write frame IndexedColorImage ${index}`)
writer.writeTableBasedImageWithGraphicControl(indexedColorImage, { delayTimeInMS: delayTime })
postProgressMessage(calcProgress(0.9, 1, length, index + 1))
})
console.log(`Write trailer`)
writer.writeTrailer()
postDoneMessage(outputStream.buffer)

View file

@ -119,15 +119,16 @@ export default new Vuex.Store({
},
encode ({ commit }, captureData) {
commit('startEncoding')
const encoding = encode(captureData)
console.log(captureData)
encoding.once('error', error => console.error(error))
encode(captureData)
.then(dataUrl => {
commit('stopEncoding')
commit('startDownloading', dataUrl)
})
.catch(error => console.error(error))
encoding.on('progress', value => console.log(`Encoding progress ${Math.round(value * 100)}% (${value})`))
encoding.once('done', objectUrl => {
commit('stopEncoding')
commit('startDownloading', objectUrl)
})
}
}
})