/*! modernizr 3.2.0 (Custom Build) | MIT * * http://modernizr.com/download/?-csstransitions-prefixedcss !*/ !function(e,n,t){function r(e,n){return typeof e===n}function o(){var e,n,t,o,i,s,a;for(var f in C)if(C.hasOwnProperty(f)){if(e=[],n=C[f],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(t=0;td;d++)if(v=e[d],h=N.style[v],f(v,"-")&&(v=a(v)),N.style[v]!==t){if(i||r(o,"undefined"))return s(),"pfx"==n?v:!0;try{N.style[v]=o}catch(g){}if(N.style[v]!=h)return s(),"pfx"==n?v:!0}return s(),!1}function h(e,n,t,o,i){var s=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+b.join(s+" ")+s).split(" ");return r(n,"string")||r(n,"undefined")?v(a,n,o,i):(a=(e+" "+P.join(s+" ")+s).split(" "),p(a,n,t))}function y(e,n,r){return h(e,t,t,n,r)}var g=[],C=[],x={_version:"3.2.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var t=this;setTimeout(function(){n(t[e])},0)},addTest:function(e,n,t){C.push({name:e,fn:n,options:t})},addAsyncTest:function(e){C.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=x,Modernizr=new Modernizr;var _=n.documentElement,w="svg"===_.nodeName.toLowerCase(),S="Moz O ms Webkit",b=x._config.usePrefixes?S.split(" "):[];x._cssomPrefixes=b;var E=function(n){var r,o=prefixes.length,i=e.CSSRule;if("undefined"==typeof i)return t;if(!n)return!1;if(n=n.replace(/^@/,""),r=n.replace(/-/g,"_").toUpperCase()+"_RULE",r in i)return"@"+n;for(var s=0;o>s;s++){var a=prefixes[s],f=a.toUpperCase()+"_"+r;if(f in i)return"@-"+a.toLowerCase()+"-"+n}return!1};x.atRule=E;var P=x._config.usePrefixes?S.toLowerCase().split(" "):[];x._domPrefixes=P;var z={elem:l("modernizr")};Modernizr._q.push(function(){delete z.elem});var N={style:z.elem.style};Modernizr._q.unshift(function(){delete N.style}),x.testAllProps=h;var T=x.prefixed=function(e,n,t){return 0===e.indexOf("@")?E(e):(-1!=e.indexOf("-")&&(e=a(e)),n?h(e,n,t):h(e,"pfx"))};x.prefixedCSS=function(e){var n=T(e);return n&&s(n)};x.testAllProps=y,Modernizr.addTest("csstransitions",y("transition","all",!0)),o(),i(g),delete x.addTest,delete x.addAsyncTest;for(var j=0;j t1) return curveY(t1); // Fallback to the bisection method for reliability. while (t0 < t1){ x2 = curveX(t2); if (Math.abs(x2 - x) < epsilon) return curveY(t2); if (x > x2) t0 = t2; else t1 = t2; t2 = (t1 - t0) * .5 + t0; } // Failure return curveY(t2); }; }, getRandomNumber = function(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }, throttle = function(fn, delay) { var allowSample = true; return function(e) { if (allowSample) { allowSample = false; setTimeout(function() { allowSample = true; }, delay); fn(e); } }; }, // from https://davidwalsh.name/vendor-prefix prefix = (function () { var styles = window.getComputedStyle(document.documentElement, ''), pre = (Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o']))[1], dom = ('WebKit|Moz|MS|O').match(new RegExp('(' + pre + ')', 'i'))[1]; return { dom: dom, lowercase: pre, css: '-' + pre + '-', js: pre[0].toUpperCase() + pre.substr(1) }; })(); var support = {transitions : Modernizr.csstransitions}, transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' }, transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ], onEndTransition = function( el, callback, propTest ) { var onEndCallbackFn = function( ev ) { if( support.transitions ) { if( ev.target != this || propTest && ev.propertyName !== propTest && ev.propertyName !== prefix.css + propTest ) return; this.removeEventListener( transEndEventName, onEndCallbackFn ); } if( callback && typeof callback === 'function' ) { callback.call(this); } }; if( support.transitions ) { el.addEventListener( transEndEventName, onEndCallbackFn ); } else { onEndCallbackFn(); } }, // the main component element/wrapper shzEl = document.querySelector('.component'), // the initial button shzCtrl = shzEl.querySelector('div.button--start'), // total number of notes/symbols moving towards the listen button totalNotes = 50, // the notes elements notes, // the note“s speed factor relative to the distance from the note element to the button. // if notesSpeedFactor = 1, then the speed equals the distance (in ms) notesSpeedFactor = 4.5, // window sizes winsize = {width: window.innerWidth, height: window.innerHeight}, // button offset shzCtrlOffset = shzCtrl.getBoundingClientRect(), // button sizes shzCtrlSize = {width: shzCtrl.offsetWidth, height: shzCtrl.offsetHeight}, // tells us if the listening animation is taking place isListening = false, // audio player element playerEl = shzEl.querySelector('.player'); // close player control //playerCloseCtrl = playerEl.querySelector('.button--close'); function init() { // create the music notes elements - the musical symbols that will animate/move towards the listen button createNotes(); // star animation listen(); } /** * creates [totalNotes] note elements (the musical symbols that will animate/move towards the listen button) */ function createNotes() { var notesEl = document.createElement('div'), notesElContent = ''; notesEl.className = 'notes'; for(var i = 0; i < totalNotes; ++i) { // we have 6 different types of symbols (icon--note1, icon--note2 ... icon--note6) var j = (i + 1) - 6 * Math.floor(i/6); notesElContent += '
'; } notesEl.innerHTML = notesElContent; shzEl.insertBefore(notesEl, shzEl.firstChild) // reference to the notes elements notes = [].slice.call(notesEl.querySelectorAll('.note')); } /** * transform the initial button into a circle shaped one that "listens" to the current song.. */ function listen() { isListening = true; showNotes(); } /** * stop the ripples and notes animations */ function stopListening() { isListening = false; // music notes animation stops... hideNotes(); } /** * show the notes elements: first set a random position and then animate them towards the button */ function showNotes() { notes.forEach(function(note) { // first position the notes randomly on the page positionNote(note); // now, animate the notes torwards the button animateNote(note); }); } /** * fade out the notes elements */ function hideNotes() { notes.forEach(function(note) { note.style.opacity = 0; }); } /** * positions a note/symbol randomly on the page. The area is restricted to be somewhere outside of the viewport. * @param {Element Node} note - the note element */ function positionNote(note) { // we want to position the notes randomly (translation and rotation) outside of the viewport var x = getRandomNumber(-2*(shzCtrlOffset.left + shzCtrlSize.width/2), 2*(winsize.width - (shzCtrlOffset.left + shzCtrlSize.width/2))), y, rotation = getRandomNumber(-30, 30); if( x > -1*(shzCtrlOffset.top + shzCtrlSize.height/2) && x < shzCtrlOffset.top + shzCtrlSize.height/2 ) { y = getRandomNumber(0,1) > 0 ? getRandomNumber(-2*(shzCtrlOffset.top + shzCtrlSize.height/2), -1*(shzCtrlOffset.top + shzCtrlSize.height/2)) : getRandomNumber(winsize.height - (shzCtrlOffset.top + shzCtrlSize.height/2), winsize.height + winsize.height - (shzCtrlOffset.top + shzCtrlSize.height/2)); } else { y = getRandomNumber(-2*(shzCtrlOffset.top + shzCtrlSize.height/2), winsize.height + winsize.height - (shzCtrlOffset.top + shzCtrlSize.height/2)); } // first reset transition if any note.style.WebkitTransition = note.style.transition = 'none'; // apply the random transforms note.style.WebkitTransform = note.style.transform = 'translate3d(' + x + 'px,' + y + 'px,0) rotate3d(0,0,1,' + rotation + 'deg)'; // save the translation values for later note.setAttribute('data-tx', Math.abs(x)); note.setAttribute('data-ty', Math.abs(y)); } /** * animates a note torwards the button. Once that's done, it repositions the note and animates it again until the component is no longer listening. * @param {Element Node} note - the note element */ function animateNote(note) { setTimeout(function() { if(!isListening) return; // the transition speed of each note will be proportional to the its distance to the button // speed = notesSpeedFactor * distance var noteSpeed = notesSpeedFactor * Math.sqrt(Math.pow(note.getAttribute('data-tx'),2) + Math.pow(note.getAttribute('data-ty'),2)); // apply the transition note.style.WebkitTransition = '-webkit-transform ' + noteSpeed + 'ms ease, opacity 0.8s'; note.style.transition = 'transform ' + noteSpeed + 'ms ease-in, opacity 0.8s'; // now apply the transform (reset the transform so the note moves to its original position) and fade in the note note.style.WebkitTransform = note.style.transform = 'translate3d(0,0,0)'; note.style.opacity = 1; // after the animation is finished, var onEndTransitionCallback = function() { // reset transitions and styles note.style.WebkitTransition = note.style.transition = 'none'; note.style.opacity = 0; if(!isListening) return; positionNote(note); animateNote(note); }; onEndTransition(note, onEndTransitionCallback, 'transform'); }, 60); } init(); })(window);