From d49ede2b86ab6f4f8e4a5d838c7c03999567a74a Mon Sep 17 00:00:00 2001 From: Nikolai Kristiansen Date: Sun, 8 May 2011 21:08:58 +0200 Subject: [PATCH] Dare to listen to a tetris tune! --- oliver_screen/static/brick1.png | Bin 0 -> 749 bytes oliver_screen/static/brick2.png | Bin 0 -> 692 bytes oliver_screen/static/brick3.png | Bin 0 -> 681 bytes oliver_screen/static/brick4.png | Bin 0 -> 661 bytes oliver_screen/static/falling_pieces.js | 125 ++++++++++++++++++ oliver_screen/static/screen.css | 73 +++++++++- oliver_screen/templates/public/index.html | 22 ++- .../templates/public/now_playing.html | 4 +- oliver_screen/tracks/views.py | 5 +- 9 files changed, 210 insertions(+), 19 deletions(-) create mode 100644 oliver_screen/static/brick1.png create mode 100644 oliver_screen/static/brick2.png create mode 100644 oliver_screen/static/brick3.png create mode 100644 oliver_screen/static/brick4.png create mode 100644 oliver_screen/static/falling_pieces.js diff --git a/oliver_screen/static/brick1.png b/oliver_screen/static/brick1.png new file mode 100644 index 0000000000000000000000000000000000000000..cbafff1989e39764cdb09088a656a7f21b74f5e3 GIT binary patch literal 749 zcmeAS@N?(olHy`uVBq!ia0vp^CxEz_gAK$w9%2ZjSc;uILpXq-h9ji|$mcBZh%9Dc zPyi}c2x7bv_x}@6P_o1|q9iy!t)x7$D3zhSyj(9cFS|H7u^?41zbJk7I~yqm2Bs`e z7srr_IdAV6<~>P~Xn1(uZ;5W0!^Ez(q}8p_0Y$9m7>{~ID+Ly?@g3mRusjszV)BHA z!%HfOOC)oOhQ0{rys7iui$06b^Z&Nzll`R=r{A96eAZF-bdBBm?eqPvZ+rdp{LIRY z=UskBZTp#Icf0ORbzkwOceV_3j2j&UI9RX{EvMCOZ(qIcU$yJY?eg;_k4m3CT0HY~ zfBLoQ#^T||uiK4Zvm4jf{P&rEa_1+O$_MZE&pv%}W1n}a&pRuY#y_i5-!tBr=$`jn@{$rat(^bJ;WrDlzX9XcXcLf0!CPz|;hnexVzjD?y|FzFGuK)Y*{K1En zO*ov6%{wS!J7T6)ZvHN?d*|Hv_xifG_ssp;d0+h7zKG}3_qtn{pWc>ReV!rxv>11j zgMv))dRbuTt+squ`ZMuo$!^Qo8|$X~r#(A8_u0+6f%`e0&IX3-cLD24b7S-G*W%8e q*=~KNNGxZg0tX9F_aGz=-9NKlGk~FD-veOMWbkzLb6Mw<&;$U`c>#$4 literal 0 HcmV?d00001 diff --git a/oliver_screen/static/brick2.png b/oliver_screen/static/brick2.png new file mode 100644 index 0000000000000000000000000000000000000000..f29d1d8680585564c61f204776e133146739019b GIT binary patch literal 692 zcmeAS@N?(olHy`uVBq!ia0vp^CxEzxgAGVtJ(SW3q*#ibJVQ8upoSx*1IXtr@Q5sC zU{Ib0!imtv~nev;Jy#naPu{GC!EX z$Mvi5kF}TDpD=s3>mS{1J8QLXwtLG37+$Zg zul<|%XHxFFEKh#@Vu$4`^=cUo%n{@eP!LdXP;h8)Xkch$U}R!sVqs$8VBrwJDsfHK zdT-^=?{>c*O|q-K>-X=cdiLe+<5TCw&zxtw;!8>Ht|(9K)AjHBCEs_aCN(iMy0RvH z-*#Z7m?%d<9#(UKDjp%L5R>lUf2||#tv4k)N8ys8(1I(Am>K=P-e);v;MjSSeNu5! zzdd`=o~N&mG$w84UvlN&qdRl61*goeRj^e5o|wfG*t49ycfpZ0%!QtsDFPF}eQV6;HD`rMK!1lRw?leJK$(``7wo zF;i#WS#s)Eccro1yN3JPTuaWze)loix8WUgVealf_a~~nowQn3&ExSht({iJYuh}u z+&I-VxSsre_b2`O!@kLNv2m&X0_CPBL)2d$UpHSUx5)JH;m2Xu)@y64aj4D6RoKVB z|o#;s4##3*5`J8n=>bs1gqb@GTlx{=U~qJB*tQ3 c3_VbH+kaZJ^|!SSFj+Bpy85}Sb4q9e0AYp{_W%F@ literal 0 HcmV?d00001 diff --git a/oliver_screen/static/brick4.png b/oliver_screen/static/brick4.png new file mode 100644 index 0000000000000000000000000000000000000000..f7b75e2896920372e67297378af35baad70d3e63 GIT binary patch literal 661 zcmeAS@N?(olHy`uVBq!ia0vp^CxEz_gAK$w9%2ZjSc;uILpXq-h9ji|$mcBZh%9Dc zP?rK>#`ChXz5)d$OI#yLg7ec#$`gxH8OqDc^)mCai<1)zQuXqS(r3T30jg#a@^ocRyU(->Cm2y(yPaQIV(-nNA&-A^?8 zTrTgEG5l$Ka=N7H>D`+bm%dq<8aaPo#h0I#uWp_E`SJ5)S$VZyliS~?_xrz(i>;`y z`;rnny?-;?thWi@7z!qHvNSm;aNs3m-t9VgxO)A+qcYcP{(k$m{|$HjVO}Oj1pyY) zh{WgdzJKfvhEbP0l+XkK?J3WP literal 0 HcmV?d00001 diff --git a/oliver_screen/static/falling_pieces.js b/oliver_screen/static/falling_pieces.js new file mode 100644 index 0000000..95cd06c --- /dev/null +++ b/oliver_screen/static/falling_pieces.js @@ -0,0 +1,125 @@ +/* */ +function is_tetris_song() { + var test; + $("#now_playing").filter(function(){ + test = /Tetris|Korobeiniki/i.test( $(this).text() ); + }); + return test; +} + +function play_tetris() { + /* http://www.webkit.org/blog-files/bricks/ and kak-logos */ + $("#gameContainer").show(); +} +function dont_play_tetris() { + $("#gameContainer").hide(); +} + +/* Define the number of bricks to be used in the animation */ +const NUMBER_OF_BRICKS = 15; + +/* + Called when the "Falling Bricks" page is completely loaded. +*/ +function init() +{ + /* Get a reference to the element that will contain the bricks */ + var container = document.getElementById('brickContainer'); + /* Fill the empty container with new bricks */ + for (var i = 0; i < NUMBER_OF_BRICKS; i++) + { + container.appendChild(createABrick()); + } +} + +function randomRotation() { + if(Math.random() <= 0.25) { + return "deg0"; + } else if(Math.random() <= 0.5) { + return "deg90"; + } else if(Math.random() <= 0.75) { + return "deg180"; + } else { + return "deg270"; + } +} + +/* + Receives the lowest and highest values of a range and + returns a random integer that falls within that range. +*/ +function randomInteger(low, high) +{ + return low + Math.floor(Math.random() * (high - low)); +} + + +/* + Receives the lowest and highest values of a range and + returns a random float that falls within that range. +*/ +function randomFloat(low, high) +{ + return low + Math.random() * (high - low); +} + + +/* Receives a number and returns its CSS pixel value. */ +function pixelValue(value) +{ + return value + 'px'; +} + + +/* Returns a duration value for the falling animation. */ + +function durationValue(value) +{ + return value + 's'; +} + + +/* Uses an img element to create each brick. */ +function createABrick() +{ + /* Start by creating a wrapper div, and an empty img element */ + var brickDiv = document.createElement('div'); + var image = document.createElement('img'); + + /* Randomly choose a brick image and assign it to the newly created element */ + /* FIXME: this url should be dynamic */ + image.src = '/static/brick' + randomInteger(1, 5) + '.png'; + + brickDiv.style.top = "-150px"; + + /* Position the brick at a random location along the screen */ + brickDiv.style.left = pixelValue(randomInteger(0, 450)); + + /* Set a random rotation for the brick */ + /* FIXME: this does'nt work */ + //brickDiv.style.webkitTranslateRotate = randomRotation(); + //brickDiv.className = randomRotation(); + //console.log(brickDiv.style); + + /* Set the -webkit-animation-name property with these values */ + brickDiv.style.webkitAnimationName = 'fade, drop'; + + /* Set the duration for the fade and drop animations */ + var fadeAndDropDuration = durationValue(10.0); + + /* Set the -webkit-animation-duration property with these values */ + brickDiv.style.webkitAnimationDuration = fadeAndDropDuration + ', ' + fadeAndDropDuration; + + var brickDelay = durationValue(randomFloat(0, 10)); + brickDiv.style.webkitAnimationDelay = brickDelay + ', ' + brickDelay; + + // add the to the
+ brickDiv.appendChild(image); + + /* Return this img element so it can be added to the document */ + return brickDiv; +} + + +/* Calls the init function when the "Falling Bricks" page is full loaded */ +window.addEventListener('load', init, false); diff --git a/oliver_screen/static/screen.css b/oliver_screen/static/screen.css index 0a9ccf9..422f8bd 100644 --- a/oliver_screen/static/screen.css +++ b/oliver_screen/static/screen.css @@ -22,7 +22,6 @@ div#container { width:1200px; height:950px; position:relative; - overflow:hidden; } div#content { display:table-cell; @@ -47,9 +46,77 @@ div#last_track { #spinner { display: none; position: fixed; - top:20px; - left:20px; + top:20px; + left:20px; width:20px; height:20px; } +/* Falling tetris pieces */ + +/* rotation-classes */ +.deg0 { + -webkit-transform:rotate(0deg); +} +.deg90 { + -webkit-transform:rotate(90deg); +} +.deg180 { + -webkit-transform:rotate(180deg); +} +.deg270 { + -webkit-transform:rotate(270deg); +} + +#gameContainer { + right:0px; + top:0px; + position: absolute; + height: 950px; + width: 500px; + margin: 0px; + overflow: hidden; + display:none; +} + +/* Defines the position and dimensions of the brickContainer div */ +#brickContainer +{ + position: absolute; + width: 100%; + height: 100%; +} + +/* This CSS rule is applied to all div elements in the brickContainer div. + It styles and animates each brickDiv. +*/ +#brickContainer > div +{ + position: absolute; + + /* We use the following properties to apply the fade and drop animations to each brick. + Each of these properties takes two values. These values respectively match a setting + for fade and drop. + */ + -webkit-animation-iteration-count: infinite, infinite; + -webkit-animation-direction: normal, normal; + -webkit-animation-timing-function: linear, ease-in; +} + +/* Makes a brick fall from -200 to 950 pixels in the y-axis */ +@-webkit-keyframes drop +{ + /* Move a brick to -200 pixels in the y-axis at the start of the animation */ + 0% { -webkit-transform: translate(0px, -200px); } + /* Move a brick to 950 pixels in the y-axis at the end of the animation */ + 100% { -webkit-transform: translate(0px, 950px); } +} + +/* Hides a brick towards the very end of the animation */ +@-webkit-keyframes fade +{ + /* Show a brick while into or below 95 percent of the animation and hide it, otherwise */ + 0% { opacity: 1; } + 95% { opacity: 1; } + 100% { opacity: 0; } +} diff --git a/oliver_screen/templates/public/index.html b/oliver_screen/templates/public/index.html index 124d860..d0f0474 100644 --- a/oliver_screen/templates/public/index.html +++ b/oliver_screen/templates/public/index.html @@ -6,6 +6,7 @@ + @@ -74,5 +64,9 @@
--> +
+
+
+ diff --git a/oliver_screen/templates/public/now_playing.html b/oliver_screen/templates/public/now_playing.html index 71c07b6..cf0a098 100644 --- a/oliver_screen/templates/public/now_playing.html +++ b/oliver_screen/templates/public/now_playing.html @@ -1,5 +1,7 @@ {% if now_playing %} -
+ {% if now_playing.image %} +
+ {% endif %} {{ now_playing.artist}} - {{ now_playing.title }} ♪♫
{% else %}
diff --git a/oliver_screen/tracks/views.py b/oliver_screen/tracks/views.py index d45ab63..d5f3a03 100644 --- a/oliver_screen/tracks/views.py +++ b/oliver_screen/tracks/views.py @@ -37,7 +37,10 @@ def get_now_playing(request): now_playing = [] if not track is None: artist = track.get_artist() - now_playing = { 'artist': artist.get_name(), 'title': track.get_title(), 'image': artist.get_images(limit=1)[0].sizes.original} + image = artist.get_images(limit=1) + if len(image) > 0: + image = image[0].sizes.original + now_playing = { 'artist': artist.get_name(), 'title': track.get_title(), 'image': image} return render_to_response("public/now_playing.html", {'now_playing':now_playing}, context_instance=RequestContext(request)); # Mock views