diff options
| author | Jules Laplace <julescarbon@gmail.com> | 2020-11-18 14:57:04 +0100 |
|---|---|---|
| committer | Jules Laplace <julescarbon@gmail.com> | 2020-11-18 14:57:04 +0100 |
| commit | c43adc8a374aaa057a090e99161afba9bbc38286 (patch) | |
| tree | f5c5dc6abcbf52092bcd618f549d29f43f365aef /animism-align/frontend/app/utils | |
| parent | 2c61e3aa88d061e7251b74b71a9006e446a05ae5 (diff) | |
preloading curtain images
Diffstat (limited to 'animism-align/frontend/app/utils')
| -rw-r--r-- | animism-align/frontend/app/utils/annotation.utils.js | 1 | ||||
| -rw-r--r-- | animism-align/frontend/app/utils/image.utils.js | 118 | ||||
| -rw-r--r-- | animism-align/frontend/app/utils/index.js | 79 |
3 files changed, 119 insertions, 79 deletions
diff --git a/animism-align/frontend/app/utils/annotation.utils.js b/animism-align/frontend/app/utils/annotation.utils.js index 76175c9..a055d91 100644 --- a/animism-align/frontend/app/utils/annotation.utils.js +++ b/animism-align/frontend/app/utils/annotation.utils.js @@ -45,6 +45,7 @@ export const thumbnailURL = media => { } export const displayThumbnailURL = media => { + if (!media) return null let image_id switch (media.type) { case 'video': diff --git a/animism-align/frontend/app/utils/image.utils.js b/animism-align/frontend/app/utils/image.utils.js new file mode 100644 index 0000000..dced2d8 --- /dev/null +++ b/animism-align/frontend/app/utils/image.utils.js @@ -0,0 +1,118 @@ +const preloadedImages = {} + +export const preloadImages = urls => batchPromise(urls, 4, preloadImage) + +export const batchPromise = (list, count, fn) => { + // console.log(list, count, fn) + return new Promise((resolve, reject) => { + let index = 0 + let len = list.length + const worker = j => ( + new Promise(resolveWorker => { + const next = () => { + const i = index++ + if (i >= len) { + return resolveWorker() + } + const item = list[i] + // console.log(['worker', j, '=>', i, item].join(' ')) + fn(item) + .then(next) + .catch(err => { + console.error(err, item) + next() + }) + } + next() + }) + ) + const workers = [] + for (let j = 0; j < count; j++) { + workers.push(worker(j)) + } + Promise.all(workers) + .then(resolve) + .catch(reject) + }) +} + +export const preloadImage = (url, anonymous=false) => ( + new Promise((resolve, reject) => { + if (preloadedImages[url] || typeof url === 'object' && url instanceof Image) { + return resolve(url) + } + preloadedImages[url] = true + const image = new Image() + let loaded = false + image.onload = () => { + if (loaded) return + loaded = true + image.onload = null + image.onerror = null + resolve(image) + } + image.onerror = () => { + if (loaded) return + image.onload = null + image.onerror = null + reject(image) + } + // console.log(img.src) + if (anonymous) { + image.crossOrigin = 'anonymous' + } + image.src = url + if (image.complete) { + image.onload() + } + }) +) + +export const cropImage = (url, crop, maxSide) => { + return new Promise((resolve, reject) => { + preloadImage(url, true) + .then(image => { + let { x, y, w, h } = crop + x = parseFloat(x) + y = parseFloat(y) + w = parseFloat(w) + h = parseFloat(h) + const canvas = document.createElement('canvas') + const ctx = canvas.getContext('2d') + const { naturalWidth, naturalHeight } = image + + let width, height + let cropWidth = naturalWidth * w + let cropHeight = naturalHeight * h + + if (maxSide > 0) { + if (cropWidth > cropHeight) { + width = Math.min(maxSide, cropWidth) + height = cropHeight * width / cropWidth + } else { + height = Math.min(maxSide, cropHeight) + width = cropWidth * height / cropHeight + } + } else { + width = cropWidth + height = cropHeight + } + + canvas.width = width + canvas.height = height + + ctx.drawImage( + image, + Math.round(x * naturalWidth), + Math.round(y * naturalHeight), + Math.round(w * naturalWidth), + Math.round(h * naturalHeight), + 0, 0, canvas.width, canvas.height + ) + // console.log(x, y, w, h) + // console.log(naturalWidth, naturalHeight) + // console.log(width, height) + resolve(canvas) + }) + }) +} diff --git a/animism-align/frontend/app/utils/index.js b/animism-align/frontend/app/utils/index.js index d6c1a16..ddbfb7e 100644 --- a/animism-align/frontend/app/utils/index.js +++ b/animism-align/frontend/app/utils/index.js @@ -114,85 +114,6 @@ export const sha256_tree = (sha256, branch_size=2, tree_depth=2) => { return tree } -export const preloadImage = (url, anonymous=false) => ( - new Promise((resolve, reject) => { - if (typeof url === 'object' && url instanceof Image) { - return resolve(url) - } - const image = new Image() - let loaded = false - image.onload = () => { - if (loaded) return - loaded = true - image.onload = null - image.onerror = null - resolve(image) - } - image.onerror = () => { - if (loaded) return - image.onload = null - image.onerror = null - resolve(image) - } - // console.log(img.src) - if (anonymous) { - image.crossOrigin = 'anonymous' - } - image.src = url - if (image.complete) { - image.onload() - } - }) -) - -export const cropImage = (url, crop, maxSide) => { - return new Promise((resolve, reject) => { - preloadImage(url, true) - .then(image => { - let { x, y, w, h } = crop - x = parseFloat(x) - y = parseFloat(y) - w = parseFloat(w) - h = parseFloat(h) - const canvas = document.createElement('canvas') - const ctx = canvas.getContext('2d') - const { naturalWidth, naturalHeight } = image - - let width, height - let cropWidth = naturalWidth * w - let cropHeight = naturalHeight * h - - if (maxSide > 0) { - if (cropWidth > cropHeight) { - width = Math.min(maxSide, cropWidth) - height = cropHeight * width / cropWidth - } else { - height = Math.min(maxSide, cropHeight) - width = cropWidth * height / cropHeight - } - } else { - width = cropWidth - height = cropHeight - } - - canvas.width = width - canvas.height = height - - ctx.drawImage( - image, - Math.round(x * naturalWidth), - Math.round(y * naturalHeight), - Math.round(w * naturalWidth), - Math.round(h * naturalHeight), - 0, 0, canvas.width, canvas.height - ) - // console.log(x, y, w, h) - // console.log(naturalWidth, naturalHeight) - // console.log(width, height) - resolve(canvas) - }) - }) -} export const urlSearchParamsToDict = search => { const params = new URLSearchParams(search) const dict = {} |
