Created
January 31, 2025 10:12
-
-
Save AnoRebel/90195498ea17839c10412169b3bbfcf4 to your computer and use it in GitHub Desktop.
Water ripples effect by github.com/jumpp14
This file contains hidden or 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
const canvas = document.getElementById('canvas'); | |
const canvasContext = canvas.getContext('2d'); | |
let columns, rows, current = [], previous = [], damping = 0.99, isMouseDown = false, isStarted = false; | |
const make2DArray = (array, columns, rows) => { | |
for(let i = 0; i < rows; i++){ | |
array.push([]); | |
for(let j = 0; j < columns * 4; j++){ | |
if(j % 4 == 3){ | |
// specifies the color is fully opaque | |
array[i][j] = 255; | |
} | |
else { | |
// initialize the array with color black | |
array[i][j] = 0; | |
} | |
} | |
} | |
return array; | |
} | |
const init = () => { | |
columns = canvas.width; | |
rows = canvas.height; | |
current = make2DArray(current, columns, rows); | |
previous = make2DArray(previous, columns, rows); | |
isStarted = false; | |
window.requestAnimationFrame(draw); | |
} | |
const draw = () => { | |
canvasContext.fillStyle = "black"; | |
canvasContext.fillRect(0, 0, canvas.width, canvas.height); | |
const imageData = canvasContext.getImageData(0, 0, canvas.width, canvas.height); | |
const data = imageData.data; | |
if(isStarted == true){ | |
for(let i = 1; i < (rows - 1); i++){ | |
for(let j = 4; j < (columns - 1) * 4; j++){ | |
if(j % 4 == 3){ | |
if(current[i][j] != 255){ | |
current[i][j] = (previous[i-1][j] + previous[i+1][j] + previous[i][j-4] + previous[i][j+4]) / 2 - current[i][j]; | |
current[i][j] = current[i][j] * damping; | |
const index = j + i * columns * 4; | |
data[index] = current[i][j]; | |
} | |
} | |
else { | |
current[i][j] = (previous[i-1][j] + previous[i+1][j] + previous[i][j-4] + previous[i][j+4]) / 2 - current[i][j]; | |
current[i][j] = current[i][j] * damping; | |
const index = j + i * columns * 4; | |
data[index] = current[i][j]; | |
} | |
} | |
} | |
} | |
canvasContext.putImageData(imageData, 0, 0); | |
const temp = previous; | |
previous = current; | |
current = temp; | |
window.requestAnimationFrame(draw); | |
} | |
init(); | |
canvas.addEventListener('click', (event) => { | |
isStarted = true; | |
const mouseX = event.pageX - canvas.offsetLeft; | |
const mouseY = event.pageY - canvas.offsetTop; | |
previous[mouseY][mouseX*4] = 159; | |
previous[mouseY][mouseX*4+1] = 250; | |
previous[mouseY][mouseX*4+2] = 255; | |
previous[mouseY][mouseX*4+3] = 255; | |
}); | |
canvas.addEventListener("mousedown", () => { | |
isMouseDown = true; | |
isStarted = true; | |
}); | |
canvas.addEventListener("mousemove", (event) => { | |
if(isMouseDown == true){ | |
const mouseX = event.pageX - canvas.offsetLeft; | |
const mouseY = event.pageY - canvas.offsetTop; | |
colorGenerator(color); | |
previous[mouseY][mouseX*4] = color.r; | |
previous[mouseY][mouseX*4+1] = color.g; | |
previous[mouseY][mouseX*4+2] = color.b; | |
previous[mouseY][mouseX*4+3] = 255; | |
} | |
}); | |
canvas.addEventListener("mouseup", () => { | |
isMouseDown = false; | |
}); | |
const color = { | |
r: 255, | |
g: 255, | |
b: 255, | |
}; | |
const colorGenerator = (color) => { | |
const red = (150 + Math.floor(Math.random() * 150)) * 5; | |
const green = (240 + Math.floor(Math.random() * 150)) * 5; | |
const blue = (250 + Math.floor(Math.random() * 200)) * 5; | |
color.r = red; | |
color.g = green; | |
color.b = blue; | |
return color; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment