Skip to content

Instantly share code, notes, and snippets.

@edco
Forked from antirez/fizzlefade.html
Last active December 30, 2017 13:42
Show Gist options
  • Save edco/695435f902b187686274205527ed2fc6 to your computer and use it in GitHub Desktop.
Save edco/695435f902b187686274205527ed2fc6 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head><title>Javascript RT</title></head>
<style>canvas {width: 1280px; height: 768px}</style>
<body>
<canvas id="framebuffer"></canvas>
<script type="text/javascript">
/* Fizzlefade using a Feistel network.
* Copyright (C) 2017 Salvatore Sanfilippo <[email protected]>
* This softare is released under the terms of the BSD two-clause license.
* See http://fabiensanglard.net/fizzlefade/index.php for more info. */
var ctx;
var pixels;
var screen_width = 3480;
var screen_height = 2160;
var frame = 0;
/* Here is a very ugly thing that calms my laptop's fan */
var timerKiller = {
timer: null,
ended: false,
setTimer: function (newTimer) {
timer = newTimer;
if(ended) {
clearInterval(timer);
}
},
end: function () {
if(timer != null) {
clearInterval(timer);
}
ended = true;
}
};
/* Create a context where we can easily write pixels. */
function init() {
fb = document.getElementById('framebuffer');
fb.width = screen_width;
fb.height = screen_height;
ctx = fb.getContext('2d');
pixels = ctx.createImageData(screen_width, screen_height);
timerKiller.setTimer(setInterval(draw, 1, timerKiller));
};
/* Write a pixel, just set alpha and RGB channels. */
function setPixel(x,y) {
var offset = x*4+y*4*screen_width;
pixels.data[offset+3] = 255;
pixels.data[offset+0] = 255;
pixels.data[offset+1] = 0;
pixels.data[offset+2] = 0;
}
/* Transforms the n bit input into another seemingly pseudo random number
* in the same range. Every input n bit input will generate a different
* n bit output. This is called a Feistel network. */
function feistelNet(input, bits) {
var mask = Math.pow(2, bits) - 1;
var halfBits = bits/2;
var halfMask = Math.pow(2, halfBits) - 1;
var l = input & halfMask;
var r = input >> halfBits;
for (var i = 0; i < 5; i++) {
var nl = r;
var F = (((r * 19) + (r >> 1)) ^ r) & halfMask;
r = l ^ F;
l = nl;
}
return ((r << halfBits) | l) & mask;
}
/* Called once every millisecond (or as fast as your browser allows), sets many
* pixels. */
function draw(killer) {
var j;
var bits = 2 * Math.ceil(Math.log2(screen_width * screen_height) / 2);
var lastFrame = Math.pow(2, bits)
/* Set many pixels per iteration otherwise it's too slow. */
for (j = 0; j < (lastFrame / 200); j++) {
if (frame >= lastFrame) {
killer.end();
break;
}
var fn = feistelNet(frame, bits);
var x = fn % screen_width;
var y = Math.floor(fn / screen_width);
if (x < screen_width && y < screen_height) {
setPixel(x,y);
}
frame++;
}
ctx.putImageData(pixels, 0, 0);
}
init();
</script>
</body>
</html>
@antirez
Copy link

antirez commented Aug 30, 2017

Cool generalization!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment