Last active
June 2, 2018 09:46
-
-
Save geelen/1f9ebc3ee6a1c159f76e48f6a7ca935c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(async () => { | |
const cols = 44 | |
const rows = 36 | |
const size = 90 | |
const speedX = 0.02 | |
const speedY = 0.0 | |
const loadImage = url => { | |
const img = document.createElement('img') | |
img.crossOrigin = true | |
return new Promise(resolve => { | |
img.onload = () => resolve(img) | |
img.src = url | |
}) | |
} | |
document.body.innerHTML = '' | |
document.body.style = 'margin: 0; background: palegoldenrod; display: flex; flex-direction: column; justify-content: center; align-items: center;' | |
// const img = await loadImage('https://i.imgur.com/umlMniN.png') | |
// const img = await loadImage('https://i.imgur.com/AVjtBoG.png') | |
const img = await loadImage('https://i.imgur.com/VhXMCPu.png') | |
const imgHeight = Math.round(size / img.width * img.height) | |
window.img = img | |
const canvas = document.createElement('canvas') | |
window.canvas = canvas | |
canvas.width = size * Math.ceil(cols / size) | |
canvas.height = imgHeight * Math.ceil(rows / imgHeight) | |
const ctx = canvas.getContext('2d') | |
window.ctx = ctx | |
document.body.appendChild(canvas) | |
const textarea = document.createElement('textarea') | |
textarea.addEventListener('click', textarea.select) | |
document.body.appendChild(textarea) | |
const output = document.createElement('canvas') | |
output.width = cols | |
output.height = rows | |
output.style = 'background: white; width: 440px; height: 360px; image-rendering: pixelated' | |
const ctx2 = output.getContext('2d') | |
document.body.appendChild(output) | |
ctx.fillStyle = 'black' | |
ctx.fillRect(0,0, canvas.width, canvas.height) | |
// ctx.imageSmoothingEnabled = false | |
const tile = (img, size, offset = 0) => { | |
let x = offset | |
while (x <= canvas.width) { | |
let y = offset | |
while (y <= canvas.height) { | |
ctx.drawImage(img, x, y, size, imgHeight) | |
y += imgHeight | |
} | |
x += size | |
} | |
} | |
tile(img, size) | |
const { data, width, height } = ctx.getImageData(0, 0, canvas.width, canvas.height) | |
const json = JSON.stringify({ | |
width, height, data: [...data], | |
speedX, speedY | |
}) | |
textarea.value = `const texture = ${json}` | |
// REPLACE THIS WITH THE JSON | |
const texture = JSON.parse(json) | |
// RENDER TO THE ARCH | |
function paintTexture(frame, rows, cols, frameX, frameY) { | |
const x_frac = frameX - Math.floor(frameX) | |
const y_frac = frameY - Math.floor(frameY) | |
const lerp = (line, j, x_a, x_b, y_a, y_b) => { | |
for (let i = 0; i < 3; i++) { | |
line[j * 3 + i] = ( | |
x_frac * y_frac * texture.data[y_b + x_b + i] + | |
(1 - x_frac) * y_frac * texture.data[y_b + x_a + i] + | |
x_frac * (1 - y_frac) * texture.data[y_a + x_b + i] + | |
(1 - x_frac) * (1 - y_frac) * texture.data[y_a + x_a + i] | |
) | |
} | |
} | |
for (let i = 0; i < rows; i++) { | |
const texRowA = texture.width * 4 * (Math.floor(i + frameY) % texture.height) | |
const texRowB = texture.width * 4 * (Math.ceil (i + frameY) % texture.height) | |
const lineSize = cols * 3; | |
const line = frame.subarray(lineSize * i, lineSize* (i + 1)); | |
for (let j = 0; j < cols; j++) { | |
const texColA = 4 * (Math.floor(j + frameX) % texture.width) | |
const texColB = 4 * (Math.ceil (j + frameX) % texture.width) | |
lerp(line, j, texColA, texColB, texRowA, texRowB) | |
} | |
} | |
} | |
/*export*/ function transform(buffer, rows, cols, frameCount, fps, isFirst) { | |
const frameSize = 3 * rows * cols; | |
for (let i = 0; i < frameCount; i++) { | |
const second = i / fps; | |
const frame = new Uint8Array(buffer, frameSize * i, frameSize); | |
paintTexture(frame, rows, cols, 10000 + i * texture.speedX, 10000 + i * texture.speedY) | |
} | |
} | |
/* | |
export default function () { | |
return Promise.resolve({ | |
transform, | |
}) | |
} | |
*/ | |
// END RENDER CODE | |
const frameCount = 35 * 2 | |
const frameSize = 3 * 36 * 44 | |
const fps = 35 | |
const buffer = new ArrayBuffer(rows * cols * 3 * frameCount) | |
transform(buffer, rows, cols, frameCount, fps, false) | |
window.buffer = buffer | |
if (window.lastTimeout) clearTimeout(window.lastTimeout) | |
let frameNr = 0 | |
const draw = () => { | |
window.lastTimeout = setTimeout(draw, Math.round(1000 / fps)) | |
const frame = new ImageData(44, 36) | |
const image = new Uint8Array(buffer, frameNr * frameSize, frameSize) | |
for (let i = 0; i < frameSize; i++) { | |
frame.data[i * 4 + 0] = image[i * 3 + 0] | |
frame.data[i * 4 + 1] = image[i * 3 + 1] | |
frame.data[i * 4 + 2] = image[i * 3 + 2] | |
frame.data[i * 4 + 3] = 255 | |
} | |
ctx2.putImageData(frame, 0, 0) | |
frameNr = (frameNr + 1) % frameCount | |
} | |
draw() | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment