-
-
Save edco/695435f902b187686274205527ed2fc6 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
<!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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cool generalization!