Permalink
Cannot retrieve contributors at this time
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Sand</title> | |
<script src="myr.js"></script> | |
<script src="convTex.js"></script> | |
</head> | |
<body> | |
<canvas id="renderer" width=1200 height=800></canvas> | |
<script> | |
const canvas = document.getElementById("renderer"); | |
const rect = canvas.getBoundingClientRect(); | |
const mousePrevious = new Myr.Vector(0, 0); | |
const mouseCurrent = new Myr.Vector(0, 0); | |
const myr = new Myr(canvas); | |
const hueStep = 0.211; | |
const brushRadius = 16; | |
const brushSpacing = 6; | |
const scale = 2; | |
const texture = new ConvTex( | |
myr, | |
new myr.Shader( | |
"lowp vec4 get(int dx, int dy) {" + | |
"mediump vec2 location = uv + pixelSize * vec2(dx, dy);" + | |
"if (location.y > 1.0)" + | |
"return vec4(1);" + | |
"else if (location.y < 0.0)" + | |
"return vec4(0);" + | |
"return texture(source, location);" + | |
"}" + | |
"void main() {" + | |
"color = get(0, 0);" + | |
"if (color.a == 0.0) {" + | |
"if (get(0, -1).a == 1.0)" + | |
"color = get(0, -1);" + | |
"else if (get(1, -1).a == 1.0 && get(2, 0).a == 1.0 && get(1, 0).a == 1.0 && !(get(-1, -1).a == 1.0 && get(-2, 0).a == 1.0 && get(-1, 0).a == 1.0))" + | |
"color = get(1, -1);" + | |
"else if (get(-1, -1).a == 1.0 && get(-2, 0).a == 1.0 && get(-1, 0).a == 1.0)" + | |
"color = get(-1, -1);" + | |
"} else if (" + | |
"get(0, 1).a == 0.0 || (" + | |
"(get(-1, 1).a == 0.0 && get(1, 1).a == 1.0 && get(-1, 0).a == 0.0 && !(get(-2, 0).a == 1.0 && get(-3, 1).a == 1.0 && get(-2, 1).a == 1.0)) ||" + | |
"(get(1, 1).a == 0.0 && get(-1, 1).a == 1.0 && get(1, 0).a == 0.0)))" + | |
"color = vec4(0);" + | |
"}", | |
["source"], | |
[] | |
), | |
myr.getWidth() / scale, | |
myr.getHeight() / scale); | |
let brushDown = false; | |
let brushColor = null; | |
let hue = Math.random(); | |
myr.setClearColor(new Myr.Color(0.9, 0.88, 0.84)); | |
myr.utils.loop(function(timeStep) { | |
for (let i = 0; i < 3; ++i) | |
texture.update(); | |
myr.bind(); | |
myr.clear(); | |
texture.getFront().drawScaled(0, 0, scale, scale); | |
myr.flush(); | |
return true; | |
}); | |
canvas.addEventListener("mousedown", event => { | |
brushDown = true; | |
hue = (hue + hueStep) % 1; | |
brushColor = Myr.Color.fromHSV(hue, 0.7, 0.7); | |
}); | |
canvas.addEventListener("mouseup", () => { | |
brushDown = false; | |
}); | |
canvas.addEventListener("mousemove", event => { | |
mousePrevious.x = mouseCurrent.x; | |
mousePrevious.y = mouseCurrent.y; | |
mouseCurrent.x = (event.clientX - rect.left) / scale; | |
mouseCurrent.y = (event.clientY - rect.top) / scale; | |
if (brushDown && !mousePrevious.equals(mouseCurrent)) { | |
const dx = mouseCurrent.x - mousePrevious.x; | |
const dy = mouseCurrent.y - mousePrevious.y; | |
const dl = Math.sqrt(dx * dx + dy * dy); | |
texture.getFront().bind(); | |
for (let d = 0; d < dl; d += brushSpacing) | |
myr.primitives.fillCircle( | |
brushColor, | |
mousePrevious.x + (dx / dl) * d, | |
mousePrevious.y + (dy / dl) * d, | |
brushRadius | |
); | |
} | |
}); | |
</script> | |
</body> | |
</html> |