Last active
August 29, 2015 13:57
-
-
Save patcullen/9626197 to your computer and use it in GitHub Desktop.
A boilerplate for starting a JS1k entry. Provides a compression function that allows hand-picking the tokens for replacement while also offering suggested tokens.
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>JS1k Entry</title><meta charset="utf-8" /><style>html, body { margin: 0; padding: 0; border: 0; }#c { display: block; } /* kill scrollbars from hell */</style></head><body><canvas id="c"></canvas><script> | |
var a = document.getElementsByTagName('canvas')[0]; | |
var b = document.body; | |
var d = function(e){ return function(){ e.parentNode.removeChild(e); }; }(a); | |
// unprefix some popular vendor prefixed things (but stick to their original name) | |
var AudioContext = window.AudioContext || window.webkitAudioContext; | |
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(f){ setTimeout(f, 1000/30); }; | |
// fix bug in safari: http://qfox.nl/weblog/218 | |
document.body.clientWidth; | |
// auto resize (original) canvas. call `onresize(w,h) to limit the size of the canvas | |
(window.onorientationchange = window.onresize = function(a){ var mw = Infinity; var mh = Infinity; var min = Math.min; return function(w,h){ if (arguments.length === 2) {mw = w;mh = h;} a.style.width = (a.width = min(mw, innerWidth)) + 'px'; a.style.height = (a.height = min(mh, innerHeight)) + 'px'; }; }(a))(); | |
var c = a.getContext('2d'); | |
</script> | |
<script> | |
// ********************** Code everything to be compressed inside of this js1k() function ************************ | |
js1k = function(){ | |
M=function(){ | |
requestAnimationFrame(M); | |
x=Math.random()*a.width; | |
y=Math.random()*a.height; | |
s=Math.random()*60+40; | |
t=Math.random()*10+10; | |
g=c.createRadialGradient(x,y,s,x,y,s+t); | |
g.addColorStop(.1,'rgba('+~~(Math.random()*255)+','+~~(Math.random()*255)+','+~~(Math.random()*255)+',1)'); | |
g.addColorStop(1,'rgba(255,255,255,0)'); | |
c.fillStyle=g; | |
c.fillRect(x-s*2,y-s*2,s*4,s*4); | |
}; | |
M(); | |
}; | |
var code=''; | |
// --------------------------------------------- Compression of the above function code ----------------------------------------------- | |
compress = function() { | |
console.log('Compressing... (manual)'); | |
var raw = js1k.toString().substring(14); | |
code = raw.substring(0, raw.length-2).replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, '').replace(/\t/g,'').replace(/\n/g,''); | |
// the tokens are the most repetitive portions of characters found in the code. | |
token = [ | |
"255", | |
"a.height", | |
"a.width", | |
"tion", | |
";c.fill", | |
"Math.random()*", | |
";g.addColorStop(", | |
"1,'rgba(", | |
"'+~~(Math.random()*255)+',", | |
"x,y,s", | |
"-s*2," | |
]; | |
var lastLength = 0; | |
for (var i = 0; i < token.length; i++) { | |
var temp = String.fromCharCode(255-token.length+i+1); | |
console.log(i, temp, token[i]); | |
for (var j = i+1; j < token.length; j++) | |
while (token[j].indexOf(token[i]) > -1) | |
token[j] = token[j].replace(token[i], temp); | |
while (code.indexOf(token[i]) > -1) { | |
code = code.replace(token[i], temp); | |
} | |
if (code.length==lastLength) { | |
console.log('Token made no difference', ' v:'+token[i]); | |
} | |
lastLength = code.length; | |
} | |
var these = [/;/g,/\,/g,/\./g,/\[/g,/\{/g]; // some interesting numbers to watch. so many repetitive/wasted bytes | |
for (var i = 0; i < these.length; i++) | |
console.log('count:', these[i], code.match(these[i])?code.match(these[i]).length:'---'); | |
function decompressionCode(flag) { | |
var value = ''; | |
for (var i = 0; i < token.length; i++) | |
value += token[i] + '|'; | |
return 'T="'+code+'";\nV="'+value+(!flag?'".split("|");for(A='+token.length+';A--;)for(Q=99;Q--;)T=T.replace(String.fromCharCode('+(256-token.length)+'+A),V[A]);eval(T);':''); | |
} | |
function suggestion() { | |
var value = ''; | |
for (var i = 0; i < token.length; i++) | |
value += token[i] + '|'; | |
var temp = longestRepeatingSubstring(decompressionCode(true)); | |
eval('T="'+temp+'";\nV="'+value+'".split("|");for(A='+token.length+';A--;)for(Q=99;Q--;)T=T.replace(String.fromCharCode('+(256-token.length)+'+A),V[A]);console.log("["+T+"]");'); | |
} | |
function notOneLineOfCode() { | |
var display = ''; | |
for (var i = 0; i < code.length; i+=100) | |
display += code.substring(i, i+100) + '\n'; | |
return display; | |
} | |
// compressed result | |
console.log('Next Longest Repeated Substring: '); suggestion(); | |
console.log('===========================================================: '); | |
var decomp = decompressionCode(); | |
console.log('Raw length: ', raw.length, ' Packed Length: ', decomp.length, '(Previous: '+localStorage['last_decomp_size']+')', ' Compression: ', ((decomp.length)/raw.length)); | |
console.log('Packed source: ', '\n\n'+decomp); | |
eval(decompressionCode()); | |
localStorage['last_decomp_size'] = decomp.length; | |
} | |
compress(); | |
// function to find the longest repeating substring - thanks to peoples of interwebs- http://stackoverflow.com/questions/3898083/find-longest-repeating-substring-in-javascript-using-regular-expressions | |
function longestRepeatingSubstring(input) { | |
var reg = /(?=((.+)(?:.*?\2)+))/g; | |
var sub = ""; //somewhere to stick temp results | |
var maxstr = ""; // our maximum length repeated string | |
reg.lastIndex = 0; // because reg previously existed, we may need to reset this | |
sub = reg.exec(input); // find the first repeated string | |
while (!(sub == null)){ | |
if ((!(sub == null)) && (sub[2].length > maxstr.length)) | |
maxstr = sub[2]; | |
sub = reg.exec(input); | |
reg.lastIndex++; // start searching from the next position | |
} | |
return maxstr; | |
} | |
</script> | |
</body> | |
</html> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment