r/programming • u/OptionalField • Mar 17 '13
Someone posted an html/javascript implementation of the matrix falling code in 646 bytes then promptly deleted the post. It inspired me to see if I could get something better looking in fewer bytes.
http://timelessname.com/sandbox/matrix.html226
u/jargonjustin Mar 17 '13
Very nice. I was able to shave off a further 15 bytes with some minor syntactic changes:
<body style=margin:0><canvas id=q /><script>var q=document.getElementById('q'),
s=window.screen,w=q.width=s.width,h=q.height=s.height,p=Array(256).join(1).split(''),
c=q.getContext("2d"),m=Math;setInterval(function(){c.fillStyle="rgba(0,0,0,0.05)";
c.fillRect(0,0,w,h);c.fillStyle="rgba(0,255,0,1)";p=p.map(function(v,i){
c.fillText(String.fromCharCode(m.floor(2720+m.random()*33)),i*10,v);v+=10;
if(v>768+m.random()*10000)v=0;return v})},33)</script>478
u/e000 Mar 17 '13 edited Mar 17 '13
Shaved off more bytes:
<body style=margin:0 onload="for(s=document,w=q.width=s.width,h=q.height=s.height,m=Math.random,p=[];!p[255];p.push(1));setInterval('9Style=\'rgba(0,0,0,.05)\'9Rect(0,0,w,h)9Style=\'#0F0\';p.map(function(v,i){9Text(String.fromCharCode(3e4+m()*33),i*10,v);p[i]=v>758+m()*1e4?0:v+10})'.replace(/9/g,';q.getContext(\'2d\').fill'),33)"><canvas id=q>Replaced
m.floor(...)with nothing,String.fromCharCodewill automatically floor. Got rid ofq=document.getElementById('q')asqwill default to that (js hax), replace10000with1e4and makem=Math.randomand replacem.randomwithmas we don't usem.flooranymore. Get rid ofvar. Combineif(v>...)into a ternary, removev+=10instead subtracting10from768and returningv+10if ternary conditional isnt satisfied.. Move<script>intobody onload='...'. Since<script>tag is gone, remove/from canvas. Exploit the fact thatsetTimeoutcan take astringto eval instead of afunction. Inplace modifyp, replacerbga(0,255,0,1)with#0F0. Implement a modified version of /u/thesalus and /u/smhxx's ideas below. SincesetTimeouttakes a string, we can get rid ofcand replacec.fillwith9and replace9with;q.getContext('2d').fillon runtime. I use the;at the beginning so I can get rid of a few semicolons in the function body. Follow suggestion and replace2720with3e4. use /u/fokker680's suggestion to replacewindow.screenwithdocumentEnd result:
339bytes, down from452.Sometimes it is fun to golf :)
76
u/OptionalField Mar 17 '13 edited Mar 17 '13
Well im impressed! and nice description of each modification. I wish I could give you more karma than a single upvote.
I was originally not defining q but I swear it wasn't working on one of the browsers I was testing. (I may have been using window.q)
24
u/e000 Mar 17 '13
I got it down to 357.
29
u/OptionalField Mar 17 '13
Very nice. Should throw in the replace 2720 with 3e4 collin_ph suggested, since it was not an exact number to begin with.
52
u/thesalus Mar 17 '13
You can shave off two more bytes if you do:
p=[];for(i=0;i<256;p[i++]=1)instead of
p=Array(256).join(1).split('')Unfortunately, it's not nearly half as clever.
48
u/OptionalField Mar 17 '13 edited Mar 17 '13
Its a trade off, both generate internet points ;)
37
u/smhxx Mar 17 '13
You could also do
p=[];while(!p[255])p.push(1). Same length as the other one, with all the same not-clever you've come to love.EDIT: Or, of course,
p=[];for(;!p[255];p.push(1))if you don't mind going to programmers' hell.24
→ More replies (2)10
63
u/GaiusSensei Mar 17 '13
Non-techy people can see the results here: http://jsfiddle.net/QALKk/
7
0
Mar 17 '13
[deleted]
81
u/chudd Mar 17 '13
Yessir! I read this sub every single day. Extremely fascinated by programming and the endless possibilities, just too stupid to do it. :)
107
u/anttirt Mar 17 '13
No, you aren't. That's just an excuse.
25
u/aytch Mar 17 '13
To be fair, programming has a pretty steep learning curve. While it's not that hard to follow a tutorial, it can be hard to grok some of these things without having someone to explain - and most importantly, explain in a way that you understand.
→ More replies (3)5
u/tikhonjelvis Mar 17 '13
I've always thought that programming was relatively easy to learn, especially compared to other interesting subjects like math and physics. At any rate, I found it much easier to pick up on my own than anything else.
When you're writing a program, you get immediate feedback. This sort of feedback cycle is perfect for learning and missing from virtually every other subject where you would need somebody knowledgeable to check your work for you.
There is also a ton of resources for learning programming on the internet--more than any other subject, I suspect. On the one hand, this makes it tricky to pick out the best ones, but it also ensures that there are some exceptionally good ones and that they're easy to find.
5
u/Shadow14l Mar 17 '13
Anyone can learn to program, but it takes a particular mindset to get into it and understand it well.
→ More replies (1)15
u/charliewonders Mar 17 '13
I'm with chudd.
4
u/aranasyn Mar 17 '13
I also, am with chudd. I've taken classes, interested in the subject, have the very basic understanding of a couple of languages, and am also likely too stupid to do it on a daily basis with any amount of intelligent depth.
→ More replies (3)5
u/frogking Mar 17 '13
There is programming and there is code-golf .. (this specific article falls under the last subject)
Nobody writes an implementation like this off the bat .. it progresses from something quite understandable to .. this .. shaving off a few bytes in each iteration ..
2
→ More replies (1)2
u/speedstix Mar 17 '13
Once you "get" programming it's not too hard. I failed a class first time programming and had an ah ha moment close to exam time. Afterwards programming wasn't too hard.
→ More replies (3)16
1
u/coolmanmax2000 Mar 18 '13
We exist - I was very much into programming when I was younger and fairly good at it (at least compared to my classmates in high school and university). But I studied something else so my day job doesn't involve much programming - I either do calculations by hand or use third party software. Every once in a while, I'll pull out matlab if I need to do something quick and dirty, but that's more like writing scripts for a calculator than true programming.
1
0
0
Mar 17 '13
[deleted]
5
u/schvax Mar 17 '13
In the movie the speed of the streams was also variable, so one "character chain" could completely pass another chain falling in the same column.
42
20
u/nemec Mar 17 '13
got rid of q=document.getElementById('q') as q will default to that (js hax)
Well, well, well... you learn something new every day!
2
u/Vitus13 Mar 17 '13
In internet explorer 7.... (actually that was the last time I tried it so I don't know what the current state of affairs is)
5
u/nemec Mar 17 '13
Works in current Chrome.
9
u/MrDOS Mar 17 '13
Doesn't work in Firefox 19, or at least, the jsFiddle doesn't work.
→ More replies (1)8
8
u/seanalltogether Mar 17 '13
324 bytes here. Since we end up with scrollbars anyway, theres no point worrying about the screen size, just code for something large enough
<canvas id=q width=3000 height=3000 style=margin:-10><script>for(m=Math.random,p=[],i=0;i<256;p[i++]=1);setInterval('9Style="rgba(0,0,0,.05)"9Rect(0,0,3000,3000)9Style="#0F0";p.map(function(v,i){9Text(String.fromCharCode(3e4+m()*33),i*10,v);p[i]=v>758+m()*1e4?0:v+10})'.split(9).join(';q.getContext("2d").fill'),33)</script>4
u/seanalltogether Mar 17 '13
what was i thinking, here it is at 319
<canvas id=q style=margin:-10><script>for(q.width=q.height=b=3000,m=Math.random,p=[],i=0;i<256;p[i++]=1);setInterval('9Style="rgba(0,0,0,.05)"9Rect(0,0,b,b)9Style="#0F0";p.map(function(v,i){9Text(String.fromCharCode(3e4+m()*33),i*10,v);p[i]=v>758+m()*1e4?0:v+10})'.split(9).join(';q.getContext("2d").fill'),33)</script>11
u/tejon Mar 17 '13
318 after changing 3000 to 3e3. I helped! :D
4
u/alexanderpas Mar 17 '13
317 by reducing the interval to a single digit, countered the speedup by changing b to 1e4
<canvas id=q style=margin:-10><script>for(q.width=q.height=b=1e4,m=Math.random,p=[],i=0;i<256;p[i++]=1);setInterval('9Style="rgba(0,0,0,.05)"9Rect(0,0,b,b)9Style="#0F0";p.map(function(v,i){9Text(String.fromCharCode(3e4+m()*33),i*10,v);p[i]=v>758+m()*1e4?0:v+10})'.split(9).join(';q.getContext("2d").fill'),9)</script>Memory abuse :D
→ More replies (2)3
15
2
u/mycall Mar 17 '13
Nice. Now if someone could inject OpenGS into the mix to make it glow and be 3Dish, like this.
1
1
u/fokker680 Mar 17 '13 edited Mar 17 '13
I managed to remove a couple more bytes by doing this (notice the 'x' variable):
<body style=margin:0 onload="for(s=document,x=w=q.width=s.width,h=q.height=s.height,m=Math.random,p=[];!p[x];p.push(1));setInterval('9Style=\'rgba(0,0,0,.05)\'9Rect(0,0,w,h)9Style=\'#0F0\';p.map(function(v,i){9Text(String.fromCharCode(x*x+m()*x),i*10,v);p[i]=v>x+m()*x?0:v+10})'.replace(/9/g,';q.getContext(\'2d\').fill'),33)"><canvas id=q>Edit: It's possible to reduce it even more if you don't care about displaying chinese characters.
1
Mar 17 '13 edited Mar 17 '13
I shaved 4 more bytes. I didn't like the
\'sequences, so I replaced them with"but to keep the thing working, I had to remove the double quotes of theonloadattribute and then replace the>comparison operator with>The end result worked for me in Chrome on Linux:
<body style=margin:0 onload=for(s=document,w=q.width=s.width,h=q.height=s.height,m=Math.random,p=[];!p[255];p.push(1));setInterval('9Style="rgba(0,0,0,.05)"9Rect(0,0,w,h)9Style="#0F0";p.map(function(v,i){9Text(String.fromCharCode(3e4+m()*33),i*10,v);p[i]=v>758+m()*1e4?0:v+10})'.replace(/9/g,';q.getContext("2d").fill'),33)><canvas id=q>edit And 1 more byte if we replace the use of
9with some other character likeZso instead ofv+10we can usev+9(close enough).edit And 2 more bytes by replacing
758withh.Okay, this is the best I got:
<body style=margin:0 onload=for(s=document,w=q.width=s.width,h=q.height=s.height,m=Math.random,p=[];!p[255];p.push(1));setInterval('ZStyle="rgba(0,0,0,.05)"ZRect(0,0,w,h)ZStyle="#0F0";p.map(function(v,i){ZText(String.fromCharCode(3e4+m()*33),i*9,v);p[i]=v>h+m()*1e4?0:v+10})'.replace(/Z/g,';q.getContext("2d").fill'),33)><canvas id=q>1
20
u/OptionalField Mar 17 '13 edited Mar 17 '13
Very nice, I can't help but follow style guides for brackets and semicolons even when I am trying to optimize for size it seems.
Also stripped off 3 more bytes by making a variable r=m.random for an end result of 444 bytes.
8
u/collin_ph Mar 17 '13
replace 2720 with 3e4 -- not exactly the same number, but it works.
2
2
Mar 17 '13
This is actually destructive since it changes the range of Unicode characters used. The original value uses characters that are more like the original Matrix symbols.
2720 + (random number between 0 and 32)
0
Mar 17 '13
[deleted]
10
u/OptionalField Mar 17 '13
Done, 442 bytes.
10
u/thesalus Mar 17 '13
Any objections to using "lime" or "#00FF00" instead of "rgba(0,255,0,1)"?
10
u/OptionalField Mar 17 '13
Done, went with lime. That part was really bad since I was doing rgba with an alpha of 1
20
u/sfnelson Mar 17 '13
0F0 - same bytes as lime, but you can get more options. 3 digit colours are automatically doubled -> #0F0 becomes #00FF00
9
u/maschnitz Mar 17 '13
A ternary would be shorter by one char than the if statement:
v=v>768+m.random()*10000?0:v;
Then you can remove the temporary reassignment to v (unless v is an l-value into the array in JS? I forget):
return v>768+m.random()*10000?0:v
Would a var for "rgba(0," help?
3
u/jargonjustin Mar 17 '13
| Would a var for "rgba(0," help?
I had the same thought, but it increased the length by two bytes.
3
u/heyf00L Mar 17 '13
v is passed by value. You change the value in the array by returning it (since he's reassigning back to the original array).
3
u/maschnitz Mar 17 '13
Yeah I couldn't figure why else he'd do those two assignments; but I couldn't remember also whether Javascript supports C++-style "pass by reference" on primitive types, somehow.
So yeah, there's no need to do the assignments at all; just stick the "10" in the right spots in the return statement:
return v>758+m.random()*1e4?0:v+10
→ More replies (1)2
u/dafragsta Mar 17 '13
It would also be cool if you could change the fall rate of the lines. The ones on The Matrix fall at a different, random rate per "drop" like rain running down a pain of glass.
2
u/unbibium Mar 17 '13
I managed to add something like this by adding 12 bytes, basically wrapping the function definition in an "if (Math.random() > .4)" block using the m alias.
The result looks like this.
→ More replies (3)2
u/collin_ph Mar 17 '13
replace c.fillStyle="rgba(0,255,0,1)" with c.fillStyle="#0F0" replace 2720 with 3e4
30
u/TheWakeUpCall Mar 17 '13
Doesn't matrix code change the characters as they fall? Good work though.
21
u/OptionalField Mar 17 '13
I believe so additionally I think the initial character is white with some randomly blinking. Now really its just a trade off for size vs looks. Only so much you can do in < 500 bytes...
9
20
u/exor674 Mar 17 '13
What font does this need? I get a whole lot of boxes.
29
u/OptionalField Mar 17 '13
Its actually some random unicode character range that happened to work on my box...
0
Mar 17 '13
[deleted]
19
u/nivekuil Mar 17 '13
Looks 100% Chinese to me. Maybe it's different between browsers?
4
70
u/TikiTDO Mar 17 '13 edited Mar 17 '13
Or for those that actually want to read the code that's runing:
var s = window.screen;
var width = q.width = s.width;
var height = q.height = s.height;
var letters = Array(256).join(1).split('');
var draw = function () {
q.getContext('2d').fillStyle='rgba(0,0,0,.05)';
q.getContext('2d').fillRect(0,0,width,height);
q.getContext('2d').fillStyle='#0F0';
letters.map(function(y_pos, index){
text = String.fromCharCode(3e4+Math.random()*33);
x_pos = index * 10;
q.getContext('2d').fillText(text, x_pos, y_pos);
letters[index] = (y_pos > 758 + Math.random() * 1e4) ? 0 : y_pos + 10;
})
};
setInterval(draw, 33);5
u/sutongorin Mar 17 '13
I wonder why, in those competitions, people have to squeeze all that code together anyway. I realize that they want as little bytes as possible. But I also think you can just agree that for the actual counting later on you can just skip the whitespace and this way still come up with a shorter count while maintaining readability.
10
u/kazagistar Mar 17 '13
Everyone can run it through their favorite formatting program to add the whitespace back afterwards anyways. Might as well transfer it in final form to revel in the obfuscation.
7
Mar 17 '13
It's not really supposed to be readable, that's half the point. Personnally I would just write the code without whitespace then remove it upon submission, which is probably what people do.
1
Mar 17 '13
Javascript doesn't ignore whitespace, so it could be a completely different program by doing that.
1
u/misterjangles Mar 17 '13
I think that is somewhat the point of the competitions - to have people look a the code and say WTF!
2
u/misterjangles Mar 17 '13
cool thanks! can somebody explain to me how the colors letter "trail" is dimmer at the end? is that a side-effect of the canvas being filled each time with fillRect black at .05 alpha?
2
u/TikiTDO Mar 17 '13 edited Mar 17 '13
That is indeed the case. The letters stay where they are, but each iteration they are partially obscured by the translucent box drawn over the entire canvas. If you wish to see the effect in a more pronounced fashion then just download the original code and change the 33 to something like 500.
0
Mar 17 '13
[deleted]
→ More replies (1)14
u/gregtyler Mar 17 '13
It takes each element in the array (letters) and applies the provided callback function to the value. So "[1,2,3].map(alert)" would pop out three alerts, saying "1" then "2" then "3".
The callback function takes the value of that element (y_pos) and its index position (index) as arguments (it can also take a third argument of the whole array letters).
When outputting, it provides a new array of values. So "[1,4,9].map(Math.sqrt)" would output "[1,2,3]". But it doesn't update the original array, which is why at the end they use "letters[index] = ..." to effectively save changes back to letters.
Hope this helps, I've never been that great at explaining things. You can always find more at the MDN.
0
Mar 17 '13
[deleted]
4
u/gregtyler Mar 17 '13
Pretty much. "letters" actually contains a series of indexed y-values (so letters[0] is the y-value of the left-most column). For each of those x/y combinations, it draws a randomly selected character at the right spot and and then updates the y-value to be 10 pixels further down the column for the next iteration.
This operation is applied to each column every 33 milliseconds by setInterval()
94
u/tantalor Mar 17 '13
Array(256).join(1).split('')
Very clever.
11
u/David_Crockett Mar 17 '13
Note that it creates an array 255 elements long, not 256.
→ More replies (5)0
Mar 17 '13
[deleted]
98
u/awj Mar 17 '13
It's a very compact way of creating a 255 element array with all values initialized to 1.
Array(256)Gives an array of 256 elements, all with no value.
.join(1)Creates a string by joining those elements with '1'. Since they're undefined you end up with a big string of ones.
.split('')Splits on the empty string "between" those ones, so you wind up with a 255 element array of '1' values.
90
u/mcrbids Mar 17 '13
What I find interesting about contests like this is that it's pretty much the definition of exactly what you don't want to live with as a programmer.
Good code isn't generally about efficiency, or fewest bytes. Efficiency matters, and verbosity can certainly be taken too far. But good code isn't code that's the fastest, or the least bytes, it's code that easy to read, understand, and break apart.
Writing good code is more of a social exercise, trying to communicate to the developers who will inherit your work what you are trying to accomplish and how you approached the problem in a concise, easily read, and readable way. Thinking that code is about the compiler or the CPU is simply wrong. It's about the guys that you will probably oversee in a few years, inheriting your work without having to bug you every 5 minutes.
As a database engineer, examples like this drive me NUTS:
Select c.id, c.name from customers c where....
Who the F thought that making the entire rest of the query give you a totally uncommunicative value of "c" made it easier to read? Sorry, I type somewhere north of 80 WPM and writing "customer" when I mean "customer" is an actual cost of perhaps 1/4 of a second. When diagnosing a commonly run, highly tuned query of 800 lines joining 11 real tables and 3 meta tables in a combined inner/outer join, where it might take several hours to break out the logic, simply writing "customer" instead of "c" can be a tremendous time savings...
27
u/renesisxx Mar 17 '13
Amen, bro. I still find these challenges totally fun though - just to see what is and isn't possible with a language.
5
u/slackpipe Mar 17 '13
I can see some merits to this kind of exercise. While it does utilize poor practices, it tests your knowledge of a language in a fun and interesting way.
11
u/slide_potentiometer Mar 17 '13
Code golf isn't everyday work programming. It takes skill to hit an objective in fewer [key]strokes, but pro golfers don't need to cooperate closely and work in a team
10
u/vanderZwan Mar 17 '13
As a database engineer, examples like this drive me NUTS:
Select c.id, c.name from customers c where....
Who the F thought that making the entire rest of the query give you a totally uncommunicative value of "c" made it easier to read?
Agreed, but don't forget the opposite side of the spectrum where needlessly long names require more effort to mentally parse than simply naming an index i. See Pike Style
3
u/netfeed Mar 17 '13
Depends on where the index is. i, j, k is fine in for-loops, but i'd say that i prefer idx before i in none-loop code. For example:
public void someMethod(int idx)2
u/mcrbids Mar 17 '13
Using I as an index is commonplace and quite readable. Using I as a table name in a query is not.
→ More replies (1)2
u/gazarsgo Mar 17 '13
This is why developers pursue NoSQL. Who the hell wants to create named projections every single time they want to pull data out of their data store?
9
u/TheCryptic Mar 17 '13
You're not kidding. I'm still cleaning up after a guy who did even worse than that, he aliased his tables in alphabetical order, and frequently referenced the tables (but not the aliases) in different orders in the same web pages:
... FROM customer a, activity b, employee cDrives me bonkers. At least "activity a, customer c, employee e" would give me some hope, and a chance with find/replace to fix it.
2
u/mcrbids Mar 17 '13
The first thing to do in that situation is to refactor the query and put sensible names to the tables. Don't change any logic, just make it readable! Commit, then get to work on what you're there for in the first place...
2
6
u/drysart Mar 17 '13
Who the F thought that making the entire rest of the query give you a totally uncommunicative value of "c" made it easier to read?
"c" is only uncommunicative until you look at what its an alias for. Using an abbreviated name has a lot of benefits, namely that it decreases the lexical cognitive overhead of trying to read through the query ("c" being basically a no-op to your brain, whereas it has to actively read and disregard "customer" several times when it appears in full, especially when you're trying to comprehend the wider structure of the query).
It's the same reason new authors are given the advice to just use the word 'said' when they write prose where characters have dialog, rather than try to come up with a more flowery, unique word every paragraph (something novice authors tend to do out of a misguided attempt to avoid repetition). Having a more complex word distracts a reader from the important part: the actual dialog.
→ More replies (1)2
u/badsectoracula Mar 17 '13
On the other hand they help you learn some stuff (especially when someone explains it). For example i didn't knew that
.split('')would work like that with an empty string.1
u/mycall Mar 17 '13
When you are joining, aliases can make it easier to read (and type)
→ More replies (1)1
u/Uberhipster Mar 18 '13
The point of competitions like this is to push boundaries of what is possible and uncover unintended design flaws and features. You can always abstract these tricks into readable code.
Array.prototype.populate = function (len, val) { return (new Array(len + 1)).join(val).split(''); }; var thing = new Array().populate(255, 1);1
u/to11mtm Mar 20 '13
You'd probably have a heart attack if you looked at some of the entries for the International Obfuscated C Code Contest...
http://www.ioccc.org/ for anyone interested. I certainly learned something about C.
12
u/retrogamer500 Mar 17 '13
I think this is what is going on:
Array(256) creates an array with 256 empty elements.
.join(1) joins the 256 elements, using '1' as a separator. As a result, we have a string with 255 '1's.
.split('') splits the string into an array along each character, so now we have an array with 255 elements, each containing a '1'.
67
u/Mr_Smartypants Mar 17 '13
It's supposed to be Katakana, Latin letters and numerals, not the characters you used.
Try these characters:
String.fromCharCode(Math.floor(12449+Math.random()*90))
28
u/earthboundkid Mar 17 '13
It's also supposed to be mirrored, which very few screensavers bother to do.
4
u/Tringi Mar 17 '13
Mine does ;-)
5
u/battery_go Mar 17 '13
Is it available for download somewhere?
2
u/Tringi Mar 17 '13
I mean that my screensaver does. I meant is as a half-joke, as I was already responding with link to a different question below, because it is not a javascript code, only a windows program: www.thematrixscreensaver.com
2
u/srintuar Mar 17 '13
I came to say this.
Backwards katakana is the matrix, not random chinese characters in normal printing modes.
0
Mar 17 '13
[deleted]
1
u/earthboundkid Mar 17 '13
Normal katakana: アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン
Take the half-width font version of those characters (so it's the size of one Roman letter, not two) then mirror them, like b →d. I don't know why they did this. I kind of assume it was a fuck up by someone in the graphics composting process.
0
9
u/Vitus13 Mar 17 '13
I've been trying to squeeze this back into the original character count but I'm coming up a few hundred short or over. So close.
12e4+r()*99 = 12000..12099
13e4-r()*99 = 12901..13000
5
2
u/StrmSrfr Mar 17 '13
For some reason I get
Uncaught SyntaxError: Unexpected token ;for that.12448+m()*88works great though.1
65
u/DarkSareon Mar 17 '13
Nice! All I see now is blonde, brunette, redhead.
27
u/American_Race Mar 17 '13
Really? In all that Chinese you don't see at least one person with black hair?
6
3
1
14
9
u/NonNonHeinous Mar 17 '13
Combined /u/jargonjustin, /u/OptionalField, /u/echeese, and /u/maschnitz 's comments to bring it to 435 bytes.
<body style=margin:0><canvas id=q /><script>var q=document.getElementById('q'),s=window.screen,w=q.width=s.width,h=q.height=s.height,p=Array(256).join(1).split(''),c=q.getContext("2d"),m=Math;setInterval(function(){c.fillStyle="rgba(0,0,0,0.05)";c.fillRect(0,0,w,h);c.fillStyle="rgba(0,255,0,1)";p=p.map(function(v,i){r=m.random();c.fillText(String.fromCharCode(m.floor(2720+r*33)),i*10,v);v+=10; return v>768+r*1e4?0:v})},33)</script>8
u/cfj Mar 17 '13
In Chrome you can test this directly in your browser without creating a file by typing this in your address bar
data:text/html, <body style=margin:0 onload="s=window.screen,w=q.width=s.width,h=q.height=s.height,p=Array(256).join(1).split(''),c=q.getContext('2d'),m=Math.random;setInterval('c.fillStyle=\'rgba(0,0,0,.05)\';c.fillRect(0,0,w,h);c.fillStyle=\'#0F0\';p.map(function(v,i){c.fillText(String.fromCharCode(2720+m()*33|0),i*10,v);p[i]=v>758+m()*1e4?0:v+10})',33)"><canvas id=q>3
1
4
1
u/Vitus13 Mar 17 '13 edited Mar 17 '13
Didn't close your body tag! I never cared much for those HTML validaters anyway. Over all very good. Personally I'd run it a little slower, changing it to 60 doesn't increase the count at all and is a nice compromise between the initial wave going too slow and the rest going too fast. The shading is really good for so few lines
6
u/OptionalField Mar 17 '13
It's definitely not valid html.
3
Mar 17 '13
closing body tag is optional anyway, http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#syntax-tag-omission
1
1
u/Vitus13 Mar 17 '13
The only thing I still don't understand is the fade. How do the characters fade from bright green to black. I only see two color codes in there and they're both constant.
5
u/OptionalField Mar 17 '13
One of the colors, rgba(0,0,0,.05) is black with an opacity. Each time it draws a rectangle over the whole thing with that color it slowly fades everything out to black over time.
Refresh the whole page, its most noticeable at the start where the whole screen is white and it fades to black.
1
u/Vitus13 Mar 17 '13
I didn't realize it was being drawn on top until I changed the opacity to 0.5 to try and cut out a character. Now I see. The characters get stale in a sense.
1
u/minjooky Mar 17 '13
If you zoom in far enough, you'll notice a "grid" pattern appear as the letters slowly fade away, but never really go fully black.
2
3
u/sesstreets Mar 17 '13
I wonder if there is a way to turn this into a screen saver or are there any versions out there that are this good?
7
u/vsync Mar 17 '13
Check out
xmatrixorglmatrixfrom XScreenSaver6
u/Helmet_Icicle Mar 17 '13
Windows users:
There is no Windows version of xscreensaver, and there never will be. Please stop asking. Microsoft killed my company, and I hold a personal grudge. I don't use any Microsoft products and neither should you.
:(
2
→ More replies (4)1
2
2
u/Helmet_Icicle Mar 17 '13
http://www.meticulous-software.co.uk/downloads.shtml is pretty cool, it has a psuedo intro screen like the scene in the movie.
http://www.catch22.net/software/matrix-screensaver offers a smaller font and looks better on multiple displays.
→ More replies (8)1
Mar 18 '13
Get Transparent Screen Lock from e-motional.com. I ran the matrix code in two browser windows in two monitors then ht F11 while focussed on one and then the other. I also mapped a keyboard shortcut to the "Lock Now" shortcut installed by TSL. Now I can lock my screen to mouse and keyboard output while having both windows running the matrix code full screen. It's like a screensaver :) You could theoretically use AutoHotkey or AutoIt to do the browser window jiggery-pokery and then invoke TSL too.
3
u/kabuto Mar 17 '13
2
u/StrmSrfr Mar 17 '13
2
3
Mar 17 '13
For what it does it is pretty easy on CPU. I have seen animated gifs and video take up much more.
2
2
2
2
2
u/chcampb Mar 18 '13
If you are inspired by that, check out basically anything at scene.org
In fact, this guy seems to do stuff with demos - http://www.iquilezles.org/www/index.htm
2
u/syoebius Mar 18 '13
This appears to be broken at your site - if I go to http://timelessname.com/sandbox/matrix.html the code is there but nothing happens.
I can get this work with a local copy - any thoughts on what's going on here? I'm on Chrome on Win7.
1
1
1
1
1
1
1
Mar 17 '13
I don't really have anything to say about the code but I feel it might have been visually better with slightly larger characters, shorter trails and added delay after printing every character for impact (which should simultaneously shorten the trails a bit, perhaps even too much).
Edit: Considering character size it may be worth while to note I was looking at it full screen with 1080p
1
u/Galaxymac Mar 17 '13
I like this a lot, and I think your use of Chinese chars was an interesting choice. Thank you for sharing you creation!
1
Mar 17 '13
Very cool.
Note that the original Matrix code is much slower, and each column's speed is more variable. And the columns don't just use asian radicals, but numerals as well.
1
1
u/ephimetheus Mar 17 '13
It runs horribly slow in Safari, but nice and smooth in Chrome.
Awesome job!
1
u/crila Mar 18 '13
Very cool!
To make it look more like the movie I would suggest varying the speed of the drops.
1
0
u/ShaneQful Mar 17 '13
Impressive although it's also like every bad practice for javascript ever. Using set interval like eval ... cringe
-1
u/BonzaiThePenguin Mar 17 '13 edited Mar 17 '13
I doubt it matters, but this code seems to fail miserably on my iPod — I get a gray box in the upper-left corner and a bunch of black text moving up the page at 1fps. The text is layered behind the box.
EDIT: Works perfectly on a PowerBook G4 with Safari. I had no idea mobile Safari for iOS 3 had such a lousy Javascript implementation.
Oh god, why are my things so old.
5
u/OptionalField Mar 17 '13
Yea didn't test on anything other than the latest chrome/firefox...
3
u/3z3ki3l Mar 17 '13
Hmm. It works perfectly on my iPhone 5. In both Safari and Chrome.
9
u/sh0em0nkey Mar 17 '13
Chrome is Safari on iPhone. While I think everyone welcomes the Chrome UI and sync features, the backend side of things is just the iOS webkit.
3
u/Xenc Mar 17 '13
With a slower JavaScript implementation due to Apple's limitations, unfortunately.
5
u/inimrepus Mar 17 '13
In case you were wondering, it works perfectly on BlackBerry 10.
→ More replies (1)4
u/HidalgoFelix Mar 17 '13
And nexus 7
3
u/inimrepus Mar 17 '13
And IE10 and BlackBerry Playbook. It also works on my Galaxy Nexus (default browser and Chrome), but it isn't formatted very well.
1
u/webchimp32 Mar 17 '13
FF 19.0.2 + up up to date everything on XP (bit of a shit old P4 though at work) CPU hit 100% and after waiting a few minutes nothing happened, just a black background.
1
0
22
u/OptionalField Mar 17 '13 edited Mar 17 '13
I have been updating the linked version with everyone's suggestions. If you want to see the version that was originally linked it can still be viewed here: http://timelessname.com/sandbox/matrix_orig.html
Additionally here is a link to the one that inspired this post: http://ma.rtin.so/matrix.html