summaryrefslogtreecommitdiff
path: root/animism-align/frontend/app/utils/image.utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'animism-align/frontend/app/utils/image.utils.js')
-rw-r--r--animism-align/frontend/app/utils/image.utils.js118
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)
+ })
+ })
+}