-
Notifications
You must be signed in to change notification settings - Fork 8
/
main.js
96 lines (73 loc) · 2.46 KB
/
main.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
const sourceCanvas = document.getElementById('source')
const resultCanvas = document.getElementById('result')
const fileInput = document.getElementById('file-input')
const sourceCtx = sourceCanvas.getContext('2d')
const resultCtx = resultCanvas.getContext('2d')
const HEIGHT = 700
let imageWidth = 0
let imageHeight = 0
const updateCanvasSize = () => {
sourceCanvas.width = imageWidth
sourceCanvas.height = imageHeight
resultCanvas.width = imageWidth
resultCanvas.height = imageHeight
}
const readAsDataUrl = (file) => new Promise((resolve) => {
const reader = new FileReader()
reader.onload = (e) => resolve(e.target.result)
reader.readAsDataURL(file)
})
const loadImage = (src) => new Promise((resolve) => {
const img = new Image()
img.onload = () => resolve(img)
img.src = src
})
const decel = (x) => 1-(x-1)*(x-1) // easing
fileInput.addEventListener('input', async (e) => {
console.log(e)
if (fileInput.files && fileInput.files[0]) {
console.log(fileInput.files[0])
const dataUrl = await readAsDataUrl(fileInput.files[0])
const img = await loadImage(dataUrl)
imageWidth = Math.floor(img.width * HEIGHT / img.height)
imageHeight = HEIGHT
updateCanvasSize()
sourceCtx.drawImage(img, 0, 0, imageWidth, imageHeight)
const imgd = sourceCtx.getImageData(0, 0, imageWidth, imageHeight)
const pix = imgd.data
const n = pix.length
for (let i = 0; i < n; i += 4) {
const grayscale = pix[i + 3] === 0 ? 255 : pix[i] * .3 + pix[i + 1] * .59 + pix[i + 2] * .11
pix[i] = grayscale
pix[i + 1] = grayscale
pix[i + 2] = grayscale
pix[i + 3] = 255
}
// let points = []
resultCtx.fillStyle = '#ffffff'
resultCtx.fillRect(0, 0, imageWidth, imageHeight)
for (let y = 0; y < 50; ++y) {
resultCtx.beginPath()
resultCtx.lineWidth = 2
resultCtx.lineJoin = 'round'
let l = 0;
for (let x = 0; x < imageWidth; ++x) {
const c = pix[((y * imageHeight / 50 + 6) * imageWidth + x)*4]
// points.push([x, y * imageHeight / 50 + 6])
l += (255 - c) / 255
const m = (255 - c) / 255
resultCtx.lineTo(
x,
(y + 0.5) * imageHeight / 50 + Math.sin(l * Math.PI / 2) * 5 * decel(m)
)
}
resultCtx.stroke()
}
// resultCtx.fillStyle = 'red'
// points.forEach(([x, y]) => {
// resultCtx.beginPath()
// resultCtx.arc(x, y, 1, 0, 2 * Math.PI)
// resultCtx.fill()
// })
}
})