Skip to content

Instantly share code, notes, and snippets.

@lukem512
Last active July 13, 2016 15:50
Show Gist options
  • Save lukem512/3ec9c877b32b8331576631933fc18278 to your computer and use it in GitHub Desktop.
Save lukem512/3ec9c877b32b8331576631933fc18278 to your computer and use it in GitHub Desktop.
A JavaScript plasma visualiser
<html>
<head>
<title>Plasma</title>
<meta name="author" content="Luke Mitchell" />
<style>
body {
margin: 0;
padding: 0;
}
</style>
<script>
var sleepTime = 100; // ms
var pixelSize = 4;
// PROFILE: 31.5% of time
function drawPixel(r, g, b, x, y, ctx) {
ctx.fillStyle = "rgb("+r+","+g+","+b+")";
ctx.fillRect( x*pixelSize, y*pixelSize, pixelSize, pixelSize );
}
function dist(x1, y1, x2, y2) {
var dx = x1 - x2;
var dy = y1 - y2;
return Math.sqrt(dx * dx + dy * dy)
}
/* Palette's don't work with Canvas... */
// var COEF_R = 32.0,
// COEF_G = 64.0,
// COEF_B = 128.0;
//
// var palette;
//
// function makePalette() {
// var p = new Array(256);
// for(var x = 0; x < 256; x++)
// {
// components = {
// r: Math.round(128.0 + 128 * Math.sin(Math.PI * x / COEF_R)),
// g: Math.round(128.0 + 128 * Math.sin(Math.PI * x / COEF_G)),
// b: Math.round(128.0 + 128 * Math.sin(Math.PI * x / COEF_B))
// }
// p[x] = components;
// }
// return p;
// }
// Shim for Date.now()
if (!Date.now) {
Date.now = function() { return new Date().getTime(); }
}
// See http://lodev.org/cgtutor/plasma.html
// PROFILE: Math.sin is 25% of time
function plasma(w, h, ctx, t) {
var time = t || Date.now();
var dtMax = 3.0;
var ySteps = Math.ceil(h / pixelSize);
var xSteps = Math.ceil(w / pixelSize);
for(var y = 0; y < ySteps; y++) {
for(var x = 0; x < xSteps; x++) {
var value = Math.sin(dist(x + time, y, 128.0, 128.0) / 8.0)
+ Math.sin(dist(x, y, 64.0, 64.0) / 8.0)
+ Math.sin(dist(x, y + time / 7, 192.0, 64) / 7.0)
+ Math.sin(dist(x, y, 192.0, 100.0) / 8.0);
var colour = Math.round((4 + value)) * 32;
drawPixel(colour, colour * 2, 255 - colour, x, y, ctx)
}
}
time = time + Math.random() * dtMax;
setTimeout(function() {
plasma(w, h, ctx, time);
}, sleepTime);
}
</script>
</head>
<body>
<canvas id="myCanvas">
Your browser does not support the canvas element. Please consider upgrading.
</canvas>
<script>
// It begins...
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Resize the canvas to fill browser window dynamically
window.addEventListener('resize', resizeCanvas, false);
function resizeCanvas() {
c.width = window.innerWidth;
c.height = window.innerHeight;
console.log('Canvas was resized to', c.width, 'x', c.height);
}
resizeCanvas();
// Catch keyboard events
document.addEventListener('keydown', keyDownTextField, false);
function keyDownTextField(e) {
switch (e.keyCode) {
// Left arrow
case 37:
if (sleepTime > 10) sleepTime -= 10;
console.log('sleepTime was set to', sleepTime);
break;
// Down arrow
case 38:
if (pixelSize > 1) pixelSize--;
console.log('pixelSize was set to', pixelSize);
break;
// Right arrow
case 39:
sleepTime += 10;
console.log('sleepTime was set to', sleepTime);
break;
// Up arrow
case 40:
pixelSize++;
console.log('pixelSize was set to', pixelSize);
break;
default:
break;
}
}
console.log('Let\'s go plasma!');
plasma(c.width, c.height, ctx);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment