Skip to content

Instantly share code, notes, and snippets.

@vsecoder-old-account
Created April 30, 2020 15:15
Show Gist options
  • Save vsecoder-old-account/0e1e183435cfa0f13c5f02a006c9316d to your computer and use it in GitHub Desktop.
Save vsecoder-old-account/0e1e183435cfa0f13c5f02a006c9316d to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>50 линий</title>
<style>
#source {
display: none;
position: fixed;
z-index: -1;
left: -1000vw;
}
</style>
</head>
<body>
<canvas id="source"></canvas>
<canvas id="result"></canvas>
<input type="file" accept="image/*" id="file-input">
<script>
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
}
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]
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()
}
}
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment