pinafore/src/routes/_utils/blurhash.js
Sorin Davidoi 77bb784efd feat(media): Blurhash (#1381)
* chore(npm): Install blurhash

* feat(media): Show blurhash

* fix(media/blurhash): Better sensitive video handling

* feat(media): Preference for using blurhash

* chore(utils/blurhash): Add performance marks

* fix(utils/blurhash): Performance marks

* fix(utils/blurhash): Use correct dimension

* refactor(utils/blurhash): Use constant for number of pixels

* refactor(media): Simplify logic for displaying blurhash

* chore(tests/spec): Attempt to adjust sensitivity tests for blurhash

* chore(tests/spec): Update sensitivity tests for blurhash

* chore(tests/spec): Check for sensitive

* fix(media/blurhash): Handle videos

* fix: Video handling

* fix: Videos

* minor refactoring, fix Svelte warning

* fix: Large inline images and videos

* feat(settings): Rename blurhash setting

* refactor: Use toBlob, block media rendering until blurhash ready

* refactor: Move computations to Web Worker

* fix(workers/blurhash): More error handling

* feat(workers/blurhash): Use quick-lru for caching

* fix: Don't create Context2D needlessly

* fix(workers/blurhash): Increase cache size to 100

* fix(workers/blurhash): Don't resolve promise twice

* fix(utils/decode-image): Ignore data URLs

Throws exception which prevents the image from loading.
2019-08-17 10:54:45 -07:00

52 lines
1.2 KiB
JavaScript

import BlurhashWorker from 'worker-loader!../_workers/blurhash' // eslint-disable-line
const RESOLUTION = 32
let worker
let canvas
let canvasContext2D
export function init () {
worker = worker || new BlurhashWorker()
}
export async function decode (blurhash) {
return new Promise((resolve, reject) => {
try {
init()
const onMessage = ({ data: { encoded, decoded, imageData, error } }) => {
if (encoded !== blurhash) {
return
}
worker.removeEventListener('message', onMessage)
if (error) {
return reject(error)
}
if (decoded) {
resolve(decoded)
} else {
if (!canvas) {
canvas = document.createElement('canvas')
canvas.height = RESOLUTION
canvas.width = RESOLUTION
canvasContext2D = canvas.getContext('2d')
}
canvasContext2D.putImageData(imageData, 0, 0)
canvas.toBlob(blob => {
resolve(URL.createObjectURL(blob))
})
}
}
worker.addEventListener('message', onMessage)
worker.postMessage({ encoded: blurhash })
} catch (e) {
reject(e)
}
})
}