-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.js
111 lines (98 loc) · 4.21 KB
/
util.js
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
export const createEmpty = _ => {
return Array.from({ length: 64 }, _ => Array.from({ length: 64 }, _ => [0, 0, 0, 0]))
}
export const clearCanvas = (ctx) => {
let imageData = ctx.createImageData(64, 64)
for (let i = 0; i < 64 * 64; i++) imageData.data[i * 4 + 3] = 0
ctx.putImageData(imageData, 0, 0)
}
export const applyColor = async (url, color) => {
if (!color) return url
let img = new Image(64, 64)
img.src = url
await new Promise((resolve, _) => img.onload = _ => resolve())
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0)
let imageData = ctx.getImageData(0, 0, 64, 64)
let data = imageData.data
for (let i = 0; i < data.length; i += 4) {
if (data[i + 3] < 10) continue
data[i] *= color[0] / 0xFF
data[i + 1] *= color[1] / 0xFF
data[i + 2] *= color[2] / 0xFF
data[i + 3] *= color[3] / 0xFF
}
ctx.putImageData(imageData, 0, 0);
return canvas.toDataURL('image/png')
}
export const drawImage = async (ctxes, url, color) => {
let img = new Image(64, 64)
img.src = await applyColor(url, color)
await new Promise((resolve, _) => img.onload = _ => resolve())
ctxes.forEach(ctx => ctx.drawImage(img, 0, 0))
}
export const setPoint = (data, x, y, color) => {
let index = (y * 64 + x) * 4
data.data[index] = color[0] // R
data.data[index + 1] = color[1] // G
data.data[index + 2] = color[2] // B
data.data[index + 3] = color[3] // 不透明
}
export const interpolateColor = (color1, color2, t) => {
t = Math.min(Math.max(t, 0), 1)
let r = Math.round(color1[0] + (color2[0] - color1[0]) * t)
let g = Math.round(color1[1] + (color2[1] - color1[1]) * t)
let b = Math.round(color1[2] + (color2[2] - color1[2]) * t)
let a = Math.round(color1[3] + (color2[3] - color1[3]) * t)
return [r, g, b, a]
}
export const fill = (data, source, allow = _ => true, color) => {
fillRange(data, source, 0, 0, 63, 63, allow, color)
}
export const fillRange = (data, source, minX, minY, maxX, maxY, allow = _ => true, color) => {
for (let i = minX; i <= maxX; i++)
for (let j = minY; j <= maxY; j++)
if (source[i][j][3] && allow(i, j))
setPoint(data, i, j, color ? color : source[i][j])
}
export const smooth = (colorMap, minX, minY, maxX, maxY) => {
for (let i = minX; i < maxX; i++)
for (let j = minY; j < maxY; j++) {
if (isAlone(colorMap, i, j))
colorMap[i][j] = [0, 0, 0, 0]
else if (isHole(colorMap, i, j))
colorMap[i][j] = average(colorMap, i, j)
}
}
const isAlone = (colorMap, i, j) => {
if (colorMap[i + 1]?.[j]?.[3] ?? 0) return false
if (colorMap[i - 1]?.[j]?.[3] ?? 0) return false
if (colorMap[i]?.[j + 1]?.[3] ?? 0) return false
if (colorMap[i]?.[j - 1]?.[3] ?? 0) return false
return true
}
const isHole = (colorMap, i, j) => {
if (!(colorMap[i + 1]?.[j]?.[3] ?? 0)) return false
if (!(colorMap[i - 1]?.[j]?.[3] ?? 0)) return false
if (!(colorMap[i]?.[j + 1]?.[3] ?? 0)) return false
if (!(colorMap[i]?.[j - 1]?.[3] ?? 0)) return false
return true
}
const average = (colorMap, i, j) => {
let a = colorMap[i + 1][j] ?? [0, 0, 0, 0], b = colorMap[i - 1][j] ?? [0, 0, 0, 0], c = colorMap[i][j + 1] ?? [0, 0, 0, 0], d = colorMap[i][j - 1] ?? [0, 0, 0, 0]
let cnt = (a == null ? 0 : 1) + (b == null ? 0 : 1) + (c == null ? 0 : 1) + (d == null ? 0 : 1)
return [(a[0] + b[0] + c[0] + d[0]) / cnt, (a[1] + b[1] + c[1] + d[1]) / cnt, (a[2] + b[2] + c[2] + d[2]) / cnt, (a[3] + b[3] + c[3] + d[3]) / cnt]
}
export const parseColorString = (c1) => [parseInt(c1.substring(1, 3), 16), parseInt(c1.substring(3, 5), 16), parseInt(c1.substring(5, 7), 16), 0xFF]
export const downloadCanvas = canvas => {
let filename = Date.now() + '.png'
let imgdata = canvas.toDataURL()
let link = document.createElement('a')
link.href = imgdata
link.download = filename
let event = document.createEvent('MouseEvents')
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
link.dispatchEvent(event)
}
window.saveCanvas = canvas => downloadCanvas(canvas)