├── public ├── .DS_Store └── js │ ├── harlem-shake.ogg │ ├── shake.js │ └── shake.css ├── start.php └── README.md /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/harlemshake/master/public/.DS_Store -------------------------------------------------------------------------------- /public/js/harlem-shake.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msurguy/harlemshake/master/public/js/harlem-shake.ogg -------------------------------------------------------------------------------- /start.php: -------------------------------------------------------------------------------- 1 | bundle('harlemshake'); 4 | Asset::container('harlemshake')->add('shakejs', 'js/shake.js'); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Harlem Shake V1.0 2 | 3 | Make your site dance, literally. 4 | 5 | ## Installation 6 | 7 | Install using Artisan CLI: 8 | 9 | ```shell 10 | php artisan bundle:install harlemshake 11 | ``` 12 | 13 | Add the following line to application/bundles.php 14 | 15 | ```php 16 | 'harlemshake' => array('auto' => true), 17 | ``` 18 | 19 | Publish the bundle assets to your public folder. 20 | 21 | ```shell 22 | php artisan bundle:publish 23 | ``` 24 | 25 | Add the following to the page where you want Harlem Shake script to be active. 26 | 27 | ```php 28 | {{ Asset::container('harlemshake')->scripts(); }} 29 | ``` 30 | 31 | The script requires jQuery for the Konami Code execution. 32 | 33 | After the bundle assets are published and the script embedded in one of your pages navigate to it and do the Konami Code : 34 | ↑ ↑ ↓ ↓ ← → ← → B A 35 | 36 | That's it! 37 | 38 | Enjoy the Harlem Shake dancing website! 39 | 40 | Plugin published under MIT license -------------------------------------------------------------------------------- /public/js/shake.js: -------------------------------------------------------------------------------- 1 | function harlem_shake(scriptFolder,dom_id_first) { 2 | var MIN_HEIGHT = 30; 3 | var MIN_WIDTH = 30; 4 | var MAX_HEIGHT = 1000; 5 | var MAX_WIDTH = 1000; 6 | var PATH_TO_SONG = scriptFolder +"/harlem-shake.ogg"; 7 | var CSS_BASE_CLASS = "mw-harlem_shake_me" 8 | var CSS_FIRST_CLASS = "im_first"; 9 | var CSS_OTHER_CLASSES = ["im_drunk", "im_baked", "im_trippin", "im_blown"]; 10 | var CSS_STROBE_CLASS = "mw-strobe_light"; 11 | var PATH_TO_CSS = scriptFolder+"/shake.css"; 12 | var FILE_ADDED_CLASS = "mw_added_css"; 13 | 14 | firstNode = document.getElementById(dom_id_first); 15 | if (dom_id_first == undefined || firstNode == null) 16 | { 17 | var allNodes = document.getElementsByTagName("*"); 18 | for (var i = 0; i < allNodes.length; i++) 19 | { 20 | var thisNode = allNodes[i]; 21 | if (withinBounds(thisNode)) 22 | { 23 | firstNode = thisNode; 24 | break; 25 | } 26 | } 27 | } 28 | 29 | function addCSS() { 30 | var css = document.createElement("link"); 31 | css.setAttribute("type", "text/css"); 32 | css.setAttribute("rel", "stylesheet"); 33 | css.setAttribute("href", PATH_TO_CSS); 34 | css.setAttribute("class", FILE_ADDED_CLASS); 35 | document.body.appendChild(css); 36 | } 37 | 38 | function removeAddedFiles() { 39 | var addedFiles = document.getElementsByClassName(FILE_ADDED_CLASS); 40 | for (var i = 0; i < addedFiles.length; i++) { 41 | document.body.removeChild(addedFiles[i]); 42 | } 43 | } 44 | 45 | function flashScreen() { 46 | var flash = document.createElement("div"); 47 | flash.setAttribute("class", CSS_STROBE_CLASS); 48 | document.body.appendChild(flash); 49 | setTimeout(function () { 50 | document.body.removeChild(flash); 51 | }, 100); 52 | } 53 | 54 | function size(node) { 55 | return { 56 | height: node.offsetHeight, 57 | width: node.offsetWidth 58 | } 59 | } 60 | 61 | function withinBounds(node) { 62 | var nodeFrame = size(node); 63 | return (nodeFrame.height > MIN_HEIGHT && nodeFrame.height < MAX_HEIGHT && nodeFrame.width > MIN_WIDTH && nodeFrame.width < MAX_WIDTH); 64 | } 65 | 66 | function posY(elm) { 67 | var test = elm; 68 | var top = 0; 69 | while ( !! test) { 70 | top += test.offsetTop; 71 | test = test.offsetParent; 72 | } 73 | return top; 74 | } 75 | 76 | function viewPortHeight() { 77 | var de = document.documentElement; 78 | if ( !! window.innerWidth) { 79 | return window.innerHeight; 80 | } else if (de && !isNaN(de.clientHeight)) { 81 | return de.clientHeight; 82 | } 83 | return 0; 84 | } 85 | 86 | function scrollY() { 87 | if (window.pageYOffset) { 88 | return window.pageYOffset; 89 | } 90 | return Math.max(document.documentElement.scrollTop, document.body.scrollTop); 91 | } 92 | 93 | var vpH = viewPortHeight(); 94 | var st = scrollY(); 95 | 96 | function isVisible(node) { 97 | var y = posY(node); 98 | return (y >= st && y <= (vpH + st)); 99 | } 100 | 101 | function playSong() { 102 | var audioTag = document.createElement("audio"); 103 | audioTag.setAttribute("class", FILE_ADDED_CLASS); 104 | audioTag.src = PATH_TO_SONG; 105 | audioTag.loop = false; 106 | audioTag.addEventListener("canplay", function () { 107 | setTimeout(function () { 108 | shakeFirst(firstNode); 109 | }, 500); 110 | setTimeout(function () { 111 | stopShakeAll(); 112 | flashScreen(); 113 | for (var i = 0; i < allShakeableNodes.length; i++) { 114 | shakeOther(allShakeableNodes[i]); 115 | } 116 | }, 15500); 117 | }, true); 118 | audioTag.addEventListener("ended", function () { 119 | stopShakeAll(); 120 | removeAddedFiles(); 121 | }, true); 122 | audioTag.innerHTML = "

If you are reading this, it is because your browser does not support the audio element. We recommend that you get a new browser.

" 123 | document.body.appendChild(audioTag); 124 | audioTag.play(); 125 | } 126 | 127 | function shakeFirst(node) { 128 | node.className += " " + CSS_BASE_CLASS + " " + CSS_FIRST_CLASS; 129 | } 130 | 131 | function shakeOther(node) { 132 | node.className += " " + CSS_BASE_CLASS + " " + CSS_OTHER_CLASSES[Math.floor(Math.random() * CSS_OTHER_CLASSES.length)]; 133 | } 134 | 135 | function stopShakeAll() { 136 | var shakingNodes = document.getElementsByClassName(CSS_BASE_CLASS); 137 | var regex = new RegExp('\\b' + CSS_BASE_CLASS + '\\b'); 138 | for (var i = 0; i < shakingNodes.length;) { 139 | shakingNodes[i].className = shakingNodes[i].className.replace(regex, ""); 140 | } 141 | } 142 | var allNodes = document.getElementsByTagName("*"); 143 | addCSS(); 144 | playSong(); 145 | var allShakeableNodes = []; 146 | for (var i = 0; i < allNodes.length; i++) 147 | { 148 | var thisNode = allNodes[i]; 149 | if (withinBounds(thisNode)) 150 | { 151 | allShakeableNodes.push(thisNode); 152 | } 153 | } 154 | if (dom_id_first != undefined && firstNode != null) 155 | { 156 | allShakeableNodes.push(firstNode); 157 | } 158 | } 159 | 160 | var scriptlocs = document.getElementsByTagName("script"), thisscriptsrc = scriptlocs[scriptlocs.length-1].src; 161 | var scriptFolder = thisscriptsrc.substr(0, thisscriptsrc.lastIndexOf( '/' )+1 ); 162 | 163 | 164 | jQuery(function () { 165 | var kkeys = [], konami = "38,38,40,40,37,39,37,39,66,65"; 166 | jQuery(document).keydown(function(e) 167 | { 168 | kkeys.push( e.keyCode ); 169 | if ( kkeys.toString().indexOf( konami ) >= 0 ) 170 | { 171 | jQuery(document).unbind("keydown", arguments.callee); 172 | harlem_shake(scriptFolder, 'shakemefirst'); 173 | } 174 | }); 175 | }); -------------------------------------------------------------------------------- /public/js/shake.css: -------------------------------------------------------------------------------- 1 | /* .im_drunk, .im_baked, .im_trippin, .im_blown */ 2 | 3 | .mw-strobe_light { 4 | position: fixed; 5 | width: 100%; 6 | height: 100%; 7 | top: 0; 8 | left: 0; 9 | z-index: 100000; 10 | background-color: rgba(250,250,250,0.8); 11 | display: block; 12 | } 13 | 14 | .mw-harlem_shake_me { 15 | transition: all 0.8s ease-in-out; 16 | -moz-transition: all 0.8s ease-in-out; 17 | -webkit-transition: all 0.8s ease-in-out; 18 | -o-transition: all 0.8s ease-in-out; 19 | -ms-transition: all 0.8s ease-in-out; 20 | 21 | animation: spin 1s infinite linear; 22 | -moz-animation: spin 1s infinite linear; 23 | -webkit-animation: spin 1s infinite linear; 24 | -o-animation: spin 1s infinite linear; 25 | -ms-animation: spin 1s infinite linear; 26 | } 27 | 28 | /* 29 | Animate.css - http://daneden.me/animate 30 | Licensed under the ☺ license (http://licence.visualidiot.com/) 31 | But we have it modified for our use. 32 | */ 33 | body { 34 | -webkit-backface-visibility: hidden; 35 | } 36 | .animated, .mw-harlem_shake_me { 37 | -webkit-animation-duration: .4s; 38 | -moz-animation-duration: .4s; 39 | -o-animation-duration: .4s; 40 | animation-duration: .4s; 41 | -webkit-animation-fill-mode: both; 42 | -moz-animation-fill-mode: both; 43 | -o-animation-fill-mode: both; 44 | animation-fill-mode: both; 45 | } 46 | 47 | 48 | .flash, .mw-strobe_light { 49 | -webkit-animation-name: flash; 50 | -moz-animation-name: flash; 51 | -o-animation-name: flash; 52 | animation-name: flash; 53 | } 54 | 55 | 56 | 57 | @-webkit-keyframes shake { 58 | 0%, 100% {-webkit-transform: translateX(0);} 59 | 10%, 30%, 50%, 70%, 90% {-webkit-transform: translateX(-10px);} 60 | 20%, 40%, 60%, 80% {-webkit-transform: translateX(10px);} 61 | } 62 | 63 | @-moz-keyframes shake { 64 | 0%, 100% {-moz-transform: translateX(0);} 65 | 10%, 30%, 50%, 70%, 90% {-moz-transform: translateX(-10px);} 66 | 20%, 40%, 60%, 80% {-moz-transform: translateX(10px);} 67 | } 68 | 69 | @-o-keyframes shake { 70 | 0%, 100% {-o-transform: translateX(0);} 71 | 10%, 30%, 50%, 70%, 90% {-o-transform: translateX(-10px);} 72 | 20%, 40%, 60%, 80% {-o-transform: translateX(10px);} 73 | } 74 | 75 | @keyframes shake { 76 | 0%, 100% {transform: translateX(0);} 77 | 10%, 30%, 50%, 70%, 90% {transform: translateX(-10px);} 78 | 20%, 40%, 60%, 80% {transform: translateX(10px);} 79 | } 80 | 81 | .shake, .im_baked { 82 | -webkit-animation-name: shake; 83 | -moz-animation-name: shake; 84 | -o-animation-name: shake; 85 | animation-name: shake; 86 | } 87 | 88 | 89 | 90 | 91 | .swing, .im_drunk { 92 | -webkit-transform-origin: top center; 93 | -moz-transform-origin: top center; 94 | -o-transform-origin: top center; 95 | transform-origin: top center; 96 | -webkit-animation-name: swing; 97 | -moz-animation-name: swing; 98 | -o-animation-name: swing; 99 | animation-name: swing; 100 | } 101 | 102 | @-webkit-keyframes wobble { 103 | 0% { -webkit-transform: translateX(0%); } 104 | 15% { -webkit-transform: translateX(-15%) rotate(-4deg); } 105 | 30% { -webkit-transform: translateX(12%) rotate(3deg); } 106 | 45% { -webkit-transform: translateX(-9%) rotate(-2deg); } 107 | 60% { -webkit-transform: translateX(6%) rotate(2deg); } 108 | 75% { -webkit-transform: translateX(-3%) rotate(-1deg); } 109 | 100% { -webkit-transform: translateX(0%); } 110 | } 111 | 112 | @-moz-keyframes wobble { 113 | 0% { -moz-transform: translateX(0%); } 114 | 15% { -moz-transform: translateX(-15%) rotate(-5deg); } 115 | 30% { -moz-transform: translateX(12%) rotate(3deg); } 116 | 45% { -moz-transform: translateX(-9%) rotate(-3deg); } 117 | 60% { -moz-transform: translateX(6%) rotate(2deg); } 118 | 75% { -moz-transform: translateX(-3%) rotate(-1deg); } 119 | 100% { -moz-transform: translateX(0%); } 120 | } 121 | 122 | @-o-keyframes wobble { 123 | 0% { -o-transform: translateX(0%); } 124 | 15% { -o-transform: translateX(-15%) rotate(-5deg); } 125 | 30% { -o-transform: translateX(12%) rotate(3deg); } 126 | 45% { -o-transform: translateX(-9%) rotate(-3deg); } 127 | 60% { -o-transform: translateX(6%) rotate(2deg); } 128 | 75% { -o-transform: translateX(-3%) rotate(-1deg); } 129 | 100% { -o-transform: translateX(0%); } 130 | } 131 | 132 | @keyframes wobble { 133 | 0% { transform: translateX(0%); }` 134 | 15% { transform: translateX(-15%) rotate(-5deg); } 135 | 30% { transform: translateX(12%) rotate(3deg); } 136 | 45% { transform: translateX(-9%) rotate(-3deg); } 137 | 60% { transform: translateX(6%) rotate(2deg); } 138 | 75% { transform: translateX(-3%) rotate(-1deg); } 139 | 100% { transform: translateX(0%); } 140 | } 141 | 142 | 143 | 144 | 145 | .wobble, .im_first { 146 | -webkit-animation-name: wobble; 147 | -moz-animation-name: wobble; 148 | -o-animation-name: wobble; 149 | animation-name: wobble; 150 | } 151 | 152 | @-webkit-keyframes pulse { 153 | 0% { -webkit-transform: scale(1); } 154 | 50% { -webkit-transform: scale(1.1); } 155 | 100% { -webkit-transform: scale(1); } 156 | } 157 | @-moz-keyframes pulse { 158 | 0% { -moz-transform: scale(1); } 159 | 50% { -moz-transform: scale(1.1); } 160 | 100% { -moz-transform: scale(1); } 161 | } 162 | @-o-keyframes pulse { 163 | 0% { -o-transform: scale(1); } 164 | 50% { -o-transform: scale(1.1); } 165 | 100% { -o-transform: scale(1); } 166 | } 167 | @keyframes pulse { 168 | 0% { transform: scale(1); } 169 | 50% { transform: scale(1.1); } 170 | 100% { transform: scale(1); } 171 | } 172 | 173 | .pulse, .im_blown { 174 | -webkit-animation-name: pulse; 175 | -moz-animation-name: pulse; 176 | -o-animation-name: pulse; 177 | animation-name: pulse; 178 | } 179 | 180 | 181 | 182 | 183 | @-webkit-keyframes bounceIn { 184 | 0% { 185 | opacity: 0; 186 | -webkit-transform: scale(.3); 187 | } 188 | 189 | 50% { 190 | opacity: 1; 191 | -webkit-transform: scale(1.05); 192 | } 193 | 194 | 70% { 195 | -webkit-transform: scale(.9); 196 | } 197 | 198 | 100% { 199 | -webkit-transform: scale(1); 200 | } 201 | } 202 | 203 | @-moz-keyframes bounceIn { 204 | 0% { 205 | opacity: 0; 206 | -moz-transform: scale(.3); 207 | } 208 | 209 | 50% { 210 | opacity: 1; 211 | -moz-transform: scale(1.05); 212 | } 213 | 214 | 70% { 215 | -moz-transform: scale(.9); 216 | } 217 | 218 | 100% { 219 | -moz-transform: scale(1); 220 | } 221 | } 222 | 223 | @-o-keyframes bounceIn { 224 | 0% { 225 | opacity: 0; 226 | -o-transform: scale(.3); 227 | } 228 | 229 | 50% { 230 | opacity: 1; 231 | -o-transform: scale(1.05); 232 | } 233 | 234 | 70% { 235 | -o-transform: scale(.9); 236 | } 237 | 238 | 100% { 239 | -o-transform: scale(1); 240 | } 241 | } 242 | 243 | @keyframes bounceIn { 244 | 0% { 245 | opacity: 0; 246 | transform: scale(.3); 247 | } 248 | 249 | 50% { 250 | opacity: 1; 251 | transform: scale(1.05); 252 | } 253 | 254 | 70% { 255 | transform: scale(.9); 256 | } 257 | 258 | 100% { 259 | transform: scale(1); 260 | } 261 | } 262 | 263 | .bounceIn, .im_trippin { 264 | -webkit-animation-name: bounceIn; 265 | -moz-animation-name: bounceIn; 266 | -o-animation-name: bounceIn; 267 | animation-name: bounceIn; 268 | } --------------------------------------------------------------------------------