1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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)
})
})
}
|