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/image.utils.js | |
| parent | 2c61e3aa88d061e7251b74b71a9006e446a05ae5 (diff) | |
preloading curtain images
Diffstat (limited to 'animism-align/frontend/app/utils/image.utils.js')
| -rw-r--r-- | animism-align/frontend/app/utils/image.utils.js | 118 |
1 files changed, 118 insertions, 0 deletions
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) + }) + }) +} |
