Guest User

Untitled

a guest
Mar 28th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 58.58 KB | None | 0 0
  1. /////////////////////////////////////////////////////////////////////////////////////////////////////
  2.  
  3. (function () {
  4.  
  5. var root = this; // use global context rather than window object
  6. var waveform_array, old_waveform, objectUrl, metaHide, micStream; // raw waveform data from web audio api
  7. var WAVE_DATA = []; // normalized waveform data used in visualizations
  8.  
  9. // main app/init stuff //////////////////////////////////////////////////////////////////////////
  10. var a = {};
  11. a.init = function() {
  12. console.log("a.init fired");
  13.  
  14. // globals & state
  15. var s = {
  16. version: '1.6.0',
  17. debug: (window.location.href.indexOf("debug") > -1) ? true : false,
  18. // preziotte.com/partymode playlist
  19. //playlist: ['forgot.mp3', 'chaos.mp3', 'stop.mp3', 'bless.mp3', 'benares.mp3', 'radio.mp3', 'selftanner.mp3', 'startshootin.mp3', 'track1.mp3', 'holdin.m4a', 'waiting.mp3', 'dawn.mp3', 'analog.mp3', 'settle.mp3', 'crackers.mp3', 'nuclear.mp3', 'madness.mp3', 'magoo.mp3', 'around.mp3', 'where.mp3', 'bird.mp3', 'notes.mp3'],
  20. //playListLinks: ['https://soundcloud.com/mononome', 'https://soundcloud.com/sixfingerz/sixfingerz-out-of-chaos-sttb', 'http://odesza.com/', 'https://soundcloud.com/keithkenniff', 'http://www.holbaumann.com/', 'http://www.holbaumann.com/', 'http://www.blackmothsuperrainbow.com/', 'http://www.littlepeoplemusic.com/', 'https://en.wikipedia.org/wiki/The_1UP_Show', 'https://soundcloud.com/hermitude/holdin-on-hermitude-remix', 'https://soundcloud.com/ceiling_fan', 'http://www.iamsirch.com/', 'http://prettylightsmusic.com/', 'https://soundcloud.com/saycet'],
  21. // example playlist
  22. //playlist: ['dawn.mp3', 'forgot.mp3'],
  23. //playListLinks: ['http://www.iamsirch.com/', 'https://soundcloud.com/mononome'],
  24. width : 900,
  25. height : 900,
  26. sliderVal: 50, // depricated -- value of html5 slider
  27. canKick: true, // rate limits auto kick detector
  28. metaLock: false, // overrides .hideHUD() when song metadata needs to be shown
  29. fastHide : (h.getURLParameter('fastHide')) ? 100 : null,
  30. shuffle : false,
  31.  
  32. vendors : ['-webkit-', '-moz-', '-o-', ''],
  33. protocol : window.location.protocol,
  34.  
  35. drawInterval: 1000/24, // 1000ms divided by max framerate
  36. then: Date.now(), // last time a frame was drawn
  37. trigger: 'circle', // default visualization
  38.  
  39. hud: 1, // is hud visible?
  40. active: null, // active visualization (string)
  41. vizNum: 0, // active visualization (index number)
  42. thumbs_init: [0,0,0,0,0,0,0,0], // are thumbnails initialized?
  43. theme: 0, // default color palette
  44. currentSong : 0, // current track
  45.  
  46. soundCloudURL: null,
  47. soundCloudData: null,
  48. soundCloudTracks: null,
  49.  
  50. audioURL: null,
  51.  
  52. loop: 1, // current loop index
  53. loopDelay: [null,20000,5000,1000], // array of loop options
  54. loopText: ['off', 'every 20s', 'every 5s', 'every 1s'],
  55. changeInterval: null // initialize looping setInterval id
  56.  
  57. };
  58. root.State = s;
  59.  
  60.  
  61. root.context = new (window.AudioContext || window.webkitAudioContext)();
  62.  
  63. // append main svg element
  64. root.svg = d3.select("body").append("svg").attr('id', 'viz')
  65. .attr("width", State.width)
  66. .attr("height", State.height);
  67. $("svg").css("margin-left", ($(window).width() / 2) - 450);
  68. a.bind(); // attach all the handlers
  69. a.keyboard(); // bind all the shortcuts
  70.  
  71. if (window.location.protocol.search('chrome-extension') >= 0) {
  72. a.findAudio();
  73. return;
  74. }
  75. a.soundCloudManual("https://soundcloud.com/westviewmke/sets/lapse");
  76.  
  77. if (State.fastHide)
  78. h.toggleMenu();
  79. };
  80. a.bind = function() {
  81. console.log("a.bind fired");
  82. var click = (Helper.isMobile()) ? 'touchstart' : 'click';
  83.  
  84. $('.menu, .icon-menu').on('mouseenter touchstart', function() { h.toggleMenu('open'); });
  85. $('.menu').on('mouseleave', function() { h.toggleMenu('close'); });
  86. $('.menu').on(click, 'li', function() { h.vizChange(+$(this).attr('viz-num')); });
  87. $('.menu').on(click, '.clicker', function() { h.vizChange(+$(this).closest('li').attr('viz-num')); });
  88. $('.buffer').on(click, function() { window.location.href='http://preziotte.com' });
  89. $('.song-metadata').on(click, h.songGo);
  90. $('.wrapper').on(click, function() { h.toggleMenu('close'); });
  91. $('.icon-pause').on(click, h.togglePlay);
  92. $('.icon-play').on(click, h.togglePlay);
  93. $('.icon-forward2').on(click, function() { h.changeSong('n'); });
  94. $('.icon-backward2').on(click, function() { h.changeSong('p'); });
  95. $('.icon-expand').on(click, h.toggleFullScreen);
  96. $('.icon-soundcloud').on(click, function() { h.showModal('#modal-soundcloud'); });
  97. $('.icon-microphone').on(click, a.microphone);
  98. $('.sc_import').on(click, a.soundCloud);
  99. $('.icon-question').on(click, function() { h.showModal('#modal-about'); });
  100. $('.icon-keyboard2').on(click, function() { h.showModal('#modal-keyboard'); });
  101. $('.icon-volume-medium').on(click, function() { audio.muted = (audio.muted == true) ? false : true; });
  102. $('.icon-github2').on(click, function() { window.open('http://github.com/preziotte/party-mode','_blank'); });
  103. $('.icon-loop-on').on(click, function() {
  104. $(this).find('b').text(State.loopText[(State.loop)%4]);
  105. h.infiniteChange(State.loopDelay[(State.loop++)%4]);
  106. });
  107. $('.md-close').on(click, h.hideModals);
  108. $('.dotstyle').on(click, 'li', function() { h.themeChange($(this).find('a').text()); });
  109. $('#slider').on('input change', function() { analyser.smoothingTimeConstant = 1-(this.value/100); });
  110. $('#slider').on('change', function() { $('#slider').blur(); });
  111. $('#slider-volume').on('input change', function() { audio.volume = (this.value/100); });
  112. $('#slider-volume').on('change', function() { $('#slider-volume').blur(); });
  113. $('.i').on('mouseenter', h.tooltipReplace);
  114. $('.i').on('mouseleave', h.tooltipUnReplace);
  115.  
  116. $(document).on('dragenter', h.stop );
  117. $(document).on('dragover', h.stop);
  118. $(document).on('drop', h.handleDrop );
  119.  
  120. document.addEventListener("waveform", function (e) {
  121. //console.log(e.detail);
  122. waveform_array = e.detail;
  123. //audio = this;
  124. }, false);
  125.  
  126.  
  127. // hide HUD on idle mouse
  128. $('body').on('touchstart mousemove',function() {
  129. h.showHUD();
  130. clearTimeout(hide);
  131. hide = setTimeout(function() { h.hideHUD(); }, State.fastHide || 2000);
  132. });
  133. hide = setTimeout(function() { h.hideHUD(); }, State.fastHide || 2000);
  134.  
  135. // update state on window resize
  136. window.onresize = function(event) { h.resize(); };
  137. $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange', h.resize); //http://stackoverflow.com/a/9775411
  138.  
  139.  
  140. };
  141. a.keyboard = function() {
  142. console.log("a.keyboard fired");
  143.  
  144. Mousetrap.bind('esc', h.hideModals);
  145. Mousetrap.bind('space', h.togglePlay);
  146. Mousetrap.bind('f', h.toggleFullScreen);
  147. Mousetrap.bind('m', function() { h.toggleMenu('toggle') });
  148. Mousetrap.bind('c', function() { h.changeSong(); });
  149. Mousetrap.bind('l', function() { $('.icon-loop-on').trigger('click'); });
  150. Mousetrap.bind('k', function() { $('.icon-keyboard2').trigger('click'); });
  151. Mousetrap.bind('s', function() { h.showModal('#modal-soundcloud'); });
  152. Mousetrap.bind('v', function() { h.changeSong('n'); });
  153. Mousetrap.bind('x', function() { h.changeSong('p'); });
  154. Mousetrap.bind('r', function() { h.toggleShuffle(); });
  155.  
  156. Mousetrap.bind('1', function() { State.trigger = 'circle'; });
  157. Mousetrap.bind('2', function() { State.trigger = 'chop'; });
  158. Mousetrap.bind('3', function() { State.trigger = 'icosahedron'; });
  159. Mousetrap.bind('4', function() { State.trigger = 'grid'; });
  160. Mousetrap.bind('5', function() { State.trigger = 'equal'; });
  161. Mousetrap.bind('6', function() { State.trigger = 'spin'; });
  162. Mousetrap.bind('7', function() { State.trigger = 'hexbin'; });
  163. Mousetrap.bind('8', function() { State.trigger = 'voronoi'; });
  164.  
  165. Mousetrap.bind('up', function() { h.vizChange(State.vizNum-1); });
  166. Mousetrap.bind('down', function() { h.vizChange(State.vizNum+1); });
  167. Mousetrap.bind('left', function() { h.themeChange(State.theme-1); });
  168. Mousetrap.bind('right', function() { h.themeChange(State.theme+1); });
  169.  
  170. };
  171.  
  172. a.loadSound = function() {
  173. console.log("a.loadSound fired");
  174.  
  175. if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) {
  176. console.log(" -- sound loaded via ajax request");
  177. $('.menu-controls').hide();
  178. a.loadSoundAJAX();
  179. }
  180. else {
  181. console.log(" -- sound loaded via html5 audio");
  182. var path = 'mp3/'+State.playlist[0];
  183. a.loadSoundHTML5(path);
  184. h.readID3(path);
  185. }
  186.  
  187. };
  188. a.loadSoundAJAX = function() {
  189. console.log('a.loadSoundAJAX fired');
  190.  
  191. audio = null;
  192. var request = new XMLHttpRequest();
  193. request.open("GET", "mp3/"+State.playlist[0], true);
  194. request.responseType = "arraybuffer";
  195.  
  196. request.onload = function(event) {
  197. var data = event.target.response;
  198. a.audioBullshit(data);
  199. audio.crossOrigin = "anonymous"
  200. };
  201.  
  202. request.send();
  203.  
  204. };
  205. a.loadSoundHTML5 = function(f) {
  206. console.log('a.loadSoundHTML5 fired');
  207. audio = new Audio();
  208. //audio.remove();
  209. audio.src = f;
  210. //audio.controls = true;
  211. //audio.loop = true;
  212. audio.autoplay = true;
  213. audio.crossOrigin = "anonymous";
  214. audio.addEventListener('ended', function() { h.songEnded(); }, false);
  215. // audio.addEventListener('loadedmetadata', loadedMetadata, false);
  216.  
  217. $('#audio_box').empty();
  218. document.getElementById('audio_box').appendChild(audio);
  219. a.audioBullshit();
  220.  
  221. };
  222.  
  223. a.loadAudioFromURL = function(url) {
  224. State.audioURL = url;
  225. if (State.audioURL) {
  226. a.loadSoundHTML5(url);
  227. return;
  228. }
  229. };
  230. a.soundCloudManual = function(location){
  231.  
  232. console.log('a.soundCloud fired');
  233. State.soundCloudURL = location;
  234.  
  235. if (State.soundCloudURL == null) return;
  236.  
  237. State.currentSong = 0
  238.  
  239. // use /resolve to get tracks/playlists/whatever from url
  240. $.get(
  241. 'http://api.soundcloud.com/resolve.json?url=' + State.soundCloudURL + '&client_id=67129366c767d009ecc75cec10fa3d0f',
  242. function (result) {
  243. State.soundCloudData = result;
  244. console.log(result);
  245. console.log(result.kind);
  246.  
  247. if (result.kind == "user") {
  248. console.log(result.id);
  249.  
  250. // https://stackoverflow.com/questions/10159802/getting-specific-users-track-list-with-soundcloud-api
  251. // get all tracks from user via /users/{user_id}/tracks
  252. SC.initialize({
  253. client_id: '67129366c767d009ecc75cec10fa3d0f'
  254. });
  255.  
  256. SC.get("/users/"+result.id+"/tracks", function(sound) {
  257. State.soundCloudTracks = sound.length;
  258. State.soundCloudData = sound;
  259. sound = sound[0];
  260. console.log(sound);
  261. console.log(sound.title)
  262. console.log(sound.user.permalink)
  263. //sound.uri = sound.uri.replace(/.*?:\/\//g, "http://www.corsproxy.com/");
  264.  
  265. h.renderSongTitle(sound);
  266. a.loadSoundHTML5(sound.uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  267.  
  268. });
  269.  
  270. }
  271.  
  272. if (result.kind == "track") {
  273. State.soundCloudTracks = 1;
  274. State.soundCloudData = result;
  275. console.log(result.uri);
  276. console.log(result.title);
  277. console.log(result.user.username);
  278.  
  279. // http://www.corsproxy.com/
  280. //result.uri = result.uri.replace(/.*?:\/\//g, "http://www.corsproxy.com/");
  281. a.loadSoundHTML5(result.uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  282. h.renderSongTitle(result);
  283.  
  284. }
  285.  
  286. if (result.kind == "playlist") {
  287. State.soundCloudTracks = result.tracks.length;
  288. State.soundCloudData = result.tracks;
  289. console.log(result.tracks.length);
  290. console.log(result.title);
  291. console.log(result.user.username);
  292. h.renderSongTitle(result.tracks[0]);
  293. a.loadSoundHTML5(result.tracks[0].uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  294.  
  295. }
  296. }
  297. );
  298. return;
  299.  
  300. // to get tracks /users/{user_id}/tracks
  301.  
  302. SC.initialize({
  303. client_id: '67129366c767d009ecc75cec10fa3d0f'
  304. });
  305.  
  306. SC.get("/tracks/115225139", function(sound) {
  307. console.log(sound);
  308. console.log(sound.title)
  309. $('.song-metadata').html(sound.title);
  310. $('.song-metadata').addClass("show-meta");
  311.  
  312. State.metaLock = true;
  313.  
  314. // in 3 seconds, remove class unless lock
  315. metaHide = setTimeout(function() {
  316. State.metaLock = false;
  317. $('.song-metadata').removeClass("show-meta");
  318.  
  319. }, 3000);
  320. a.loadSoundHTML5(sound.uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  321.  
  322. });
  323.  
  324. };
  325. a.soundCloud = function() {
  326. console.log('a.soundCloud fired');
  327.  
  328. // if mozilla or safar, just loadsound instead
  329. if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) {
  330. a.loadSound();
  331. return;
  332. }
  333. if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
  334. a.loadSound();
  335. return;
  336. }
  337.  
  338. State.soundCloudURL = $('#sc_input').val() || h.getURLParameter('sc');
  339. $('#sc_input').val(State.soundCloudURL);
  340. $('#sc_url span').html(State.soundCloudURL);
  341.  
  342. if (State.soundCloudURL == null) return;
  343.  
  344. State.currentSong = 0
  345.  
  346. // use /resolve to get tracks/playlists/whatever from url
  347. $.get(
  348. 'https://api.soundcloud.com/resolve.json?url=' + State.soundCloudURL + '&client_id=67129366c767d009ecc75cec10fa3d0f',
  349. function (result) {
  350. State.soundCloudData = result;
  351. console.log(result);
  352. console.log(result.kind);
  353.  
  354. if (result.kind == "user") {
  355. console.log(result.id);
  356.  
  357. // https://stackoverflow.com/questions/10159802/getting-specific-users-track-list-with-soundcloud-api
  358. // get all tracks from user via /users/{user_id}/tracks
  359. SC.initialize({
  360. client_id: '67129366c767d009ecc75cec10fa3d0f'
  361. });
  362.  
  363. SC.get("/users/"+result.id+"/tracks", function(sound) {
  364. State.soundCloudTracks = sound.length;
  365. State.soundCloudData = sound;
  366. sound = sound[0];
  367. console.log(sound);
  368. console.log(sound.title)
  369. console.log(sound.user.permalink)
  370. //sound.uri = sound.uri.replace(/.*?:\/\//g, "http://www.corsproxy.com/");
  371.  
  372. h.renderSongTitle(sound);
  373. a.loadSoundHTML5(sound.uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  374.  
  375. });
  376.  
  377. }
  378.  
  379. if (result.kind == "track") {
  380. State.soundCloudTracks = 1;
  381. State.soundCloudData = result;
  382. console.log(result.uri);
  383. console.log(result.title);
  384. console.log(result.user.username);
  385.  
  386. // http://www.corsproxy.com/
  387. //result.uri = result.uri.replace(/.*?:\/\//g, "http://www.corsproxy.com/");
  388. a.loadSoundHTML5(result.uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  389. h.renderSongTitle(result);
  390.  
  391. }
  392.  
  393. if (result.kind == "playlist") {
  394. State.soundCloudTracks = result.tracks.length;
  395. State.soundCloudData = result.tracks;
  396. console.log(result.tracks.length);
  397. console.log(result.title);
  398. console.log(result.user.username);
  399. h.renderSongTitle(result.tracks[0]);
  400. a.loadSoundHTML5(result.tracks[0].uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  401.  
  402. }
  403. }
  404. );
  405. return;
  406.  
  407. // to get tracks /users/{user_id}/tracks
  408.  
  409. SC.initialize({
  410. client_id: '67129366c767d009ecc75cec10fa3d0f'
  411. });
  412.  
  413. SC.get("/tracks/115225139", function(sound) {
  414. console.log(sound);
  415. console.log(sound.title)
  416. $('.song-metadata').html(sound.title);
  417. $('.song-metadata').addClass("show-meta");
  418.  
  419. State.metaLock = true;
  420.  
  421. // in 3 seconds, remove class unless lock
  422. metaHide = setTimeout(function() {
  423. State.metaLock = false;
  424. $('.song-metadata').removeClass("show-meta");
  425.  
  426. }, State.fastHide || 3000);
  427. a.loadSoundHTML5(sound.uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  428.  
  429. });
  430. // SC.get("/tracks/75868018", {}, function(sound){
  431. // console.log(sound);
  432. // console.log("Sound URI: "+sound.uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f'); // append to sound.uri --> /stream?client_id=YOUR_ID
  433. //$("#audio-test").attr("src", sound.uri);
  434. // a.loadSoundHTML5(sound.uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  435. // });
  436.  
  437. // SC.stream("/tracks/75868018", function(sound){
  438. // $("audio-test").attr("src", sound.uri);
  439. // });
  440. };
  441. a.microphone = function() {
  442. // this will only work over an https connection (or running the app locally)
  443. console.log('a.microphone fired');
  444. if (State.protocol.indexOf('https') == -1) {
  445. console.log("WARNING:: Accessing the microphone is only available using https://");
  446. }
  447. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
  448.  
  449. if (!micStream) {
  450. if (navigator.getUserMedia) {
  451. navigator.getUserMedia({audio: true, video: false}, function(stream) {
  452. micStream = true;
  453. console.log(" --> audio being captured");
  454. context = new (window.AudioContext || window.webkitAudioContext)();
  455. source = context.createMediaStreamSource(stream);
  456. analyser = context.createAnalyser();
  457. source.connect(analyser);
  458. console.log(micStream);
  459. audio.pause();
  460. }, h.microphoneError);
  461. } else {
  462. // fallback.
  463. }
  464. }
  465. else {
  466. console.log(" --> turning off")
  467. source.disconnect();
  468. micStream = false;
  469. audio.play();
  470. }
  471.  
  472. };
  473.  
  474. a.audioBullshit = function (data) {
  475. // uses web audio api to expose waveform data
  476. console.log("a.audioBullshit fired");
  477.  
  478. root.analyser = context.createAnalyser();
  479. //analyser.smoothingTimeConstant = .4; // .8 default
  480.  
  481. if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) {
  482. root.source = context.createBufferSource();
  483. source.buffer = context.createBuffer(data, false);
  484. source.loop = true;
  485. source.noteOn(0);
  486. }
  487. else {
  488. // https://developer.mozilla.org/en-US/docs/Web/API/AudioContext.createScriptProcessor
  489. root.source = context.createMediaElementSource(audio); // doesn't seem to be implemented in safari :(
  490. //root.source = context.createMediaStreamSource()
  491. //root.source = context.createScriptProcessor(4096, 1, 1);
  492.  
  493. }
  494.  
  495. source.connect(analyser);
  496. analyser.connect(context.destination);
  497.  
  498. a.frameLooper();
  499. };
  500. a.findAudio = function() {
  501. // unused.
  502. console.log("a.findAudio fired");
  503.  
  504. $('video, audio').each(function() {
  505. //h.loadSoundHTML5(this.src);
  506. // if .src? if playing?
  507. audio = this;
  508. a.audioBullshit();
  509. });
  510.  
  511. //$('object')
  512. //swf? SWFObject?
  513. // can use soundmanager2 -- > http://schillmania.com/projects/soundmanager2/
  514. // waveformData in sound object gives 256 array. just multiply by 4?
  515.  
  516. };
  517. a.frameLooper = function(){
  518. //console.log("a.frameLooper fired");
  519.  
  520. // recursive function used to update audio waveform data and redraw visualization
  521.  
  522. window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
  523. window.requestAnimationFrame(a.frameLooper);
  524.  
  525. now = Date.now();
  526. delta = now - State.then;
  527.  
  528. if (audio)
  529. $('#progressBar').attr('style','width: '+(audio.currentTime/audio.duration)*100+"%");
  530.  
  531. // some framerate limiting logic -- http://codetheory.in/controlling-the-frame-rate-with-requestanimationframe/
  532. if (delta > State.drawInterval) {
  533. State.then = now - (delta % State.drawInterval);
  534.  
  535. // update waveform data
  536. if (h.detectEnvironment() != 'chrome-extension') {
  537. waveform_array = new Uint8Array(analyser.frequencyBinCount);
  538. analyser.getByteFrequencyData(waveform_array);
  539. //analyser.getByteTimeDomainData(waveform_array);
  540. }
  541.  
  542. // if (c.kickDetect(95)) {
  543. // h.themeChange(Math.floor(Math.random() * 6));
  544. // h.vizChange(Math.floor(Math.random() * 7));
  545. // }
  546.  
  547. // draw all thumbnails
  548. r.circle_thumb();
  549. r.chop_thumb();
  550. r.icosahedron_thumb();
  551. r.grid_thumb();
  552. r.equal_thumb();
  553. r.spin_thumb();
  554. r.hexbin_thumb();
  555.  
  556. // draw active visualizer
  557. switch (State.trigger) {
  558. case "circle": case 0:
  559. State.vizNum = 0;
  560. r.circle();
  561. break;
  562. case "chop": case 1:
  563. State.vizNum = 1;
  564. r.chop();
  565. break;
  566. case "icosahedron": case 2:
  567. State.vizNum = 2;
  568. r.icosahedron();
  569. break;
  570. case "grid": case 3:
  571. State.vizNum = 3;
  572. r.grid();
  573. break;
  574. case "equal": case 4:
  575. State.vizNum = 4;
  576. r.equal();
  577. break;
  578. case "spin": case 5:
  579. State.vizNum = 5;
  580. r.spin();
  581. break;
  582. case "hexbin": case 6:
  583. State.vizNum = 6;
  584. r.hexbin();
  585. break;
  586. case "voronoi": case 7:
  587. State.vizNum = 7;
  588. r.voronoi();
  589. break;
  590. default:
  591. State.vizNum = 0;
  592. r.circle();
  593. break;
  594. };
  595.  
  596. }
  597.  
  598. }
  599. root.App = a;
  600.  
  601. // manipulating/normalizing waveform data ///////////////////////////////////////////////////////
  602. var c = {};
  603. c.kickDetect = function(threshold) {
  604. var kick = false;
  605.  
  606. var deltas = $(waveform_array).each(function(n,i) {
  607. if (!old_waveform) return 0;
  608. else return old_waveform[i]-n;
  609. });
  610. var s = d3.sum(deltas)/1024;
  611.  
  612. if (s>threshold && State.canKick) {
  613. kick = true;
  614. State.canKick = false;
  615. setTimeout(function(){
  616. State.canKick = true;
  617. }, 5000);
  618. }
  619.  
  620. root.old_waveform = waveform_array;
  621.  
  622. return kick;
  623. };
  624. c.normalize = function(coef, offset, neg) {
  625.  
  626. //https://stackoverflow.com/questions/13368046/how-to-normalize-a-list-of-positive-numbers-in-javascript
  627.  
  628. var coef = coef || 1;
  629. var offset = offset || 0;
  630. var numbers = waveform_array;
  631. var numbers2 = [];
  632. var ratio = Math.max.apply( Math, numbers );
  633. var l = numbers.length
  634.  
  635. for (var i = 0; i < l; i++ ) {
  636. if (numbers[i] == 0)
  637. numbers2[i] = 0 + offset;
  638. else
  639. numbers2[i] = ((numbers[i]/ratio) * coef) + offset;
  640.  
  641. if (i%2 == 0 && neg)
  642. numbers2[i] = -Math.abs(numbers2[i]);
  643. }
  644. return numbers2;
  645.  
  646. };
  647. c.normalize_binned = function(binsize, coef, offset, neg) {
  648.  
  649. var numbers = [];
  650. var temp = 0;
  651. for (var i = 0; i < waveform_array.length; i++) {
  652. temp += waveform_array[i];
  653. if (i%binsize==0) {
  654. numbers.push(temp/binsize);
  655. temp = 0;
  656. }
  657. }
  658.  
  659. var coef = coef || 1;
  660. var offset = offset || 0;
  661. var numbers2 = [];
  662. var ratio = Math.max.apply( Math, numbers );
  663. var l = numbers.length
  664.  
  665. for (var i = 0; i < l; i++ ) {
  666. if (numbers[i] == 0)
  667. numbers2[i] = 0 + offset;
  668. else
  669. numbers2[i] = ((numbers[i]/ratio) * coef) + offset;
  670.  
  671. if (i%2 == 0 && neg)
  672. numbers2[i] = -Math.abs(numbers2[i]);
  673. }
  674. return numbers2;
  675.  
  676. };
  677. c.total = function() { return Math.floor(d3.sum(waveform_array)/waveform_array.length); };
  678. c.total_normalized = function() {};
  679. c.bins_select = function(binsize) {
  680. var copy = [];
  681. for (var i = 0; i < 500; i++) {
  682. if (i%binsize==0)
  683. copy.push(waveform_array[i]);
  684. }
  685. return copy;
  686. };
  687. c.bins_avg = function(binsize) {
  688. var binsize = binsize || 100;
  689. var copy = [];
  690. var temp = 0;
  691. for (var i = 0; i < waveform_array.length; i++) {
  692. temp += waveform_array[i];
  693. if (i%binsize==0) {
  694. copy.push(temp/binsize);
  695. temp = 0;
  696. }
  697. }
  698. //console.log(copy);
  699. return copy;
  700. };
  701. root.Compute = c;
  702.  
  703. // rendering svg based on normalized waveform data //////////////////////////////////////////////
  704. var r = {};
  705. r.circle = function() {
  706.  
  707. if (State.active != 'circle') {
  708. State.active = 'circle';
  709. $('body > svg').empty();
  710. }
  711.  
  712. WAVE_DATA = c.bins_select(70);
  713.  
  714. var x = d3.scale.linear()
  715. .domain([0, d3.max(WAVE_DATA)])
  716. .range([0, 420]);
  717.  
  718. var slideScale = d3.scale.linear()
  719. .domain([1, 100])
  720. .range([0, 2]);
  721.  
  722. root.bars = svg.selectAll("circle")
  723. .data(WAVE_DATA, function(d) { return d; });
  724.  
  725. // bars.attr("r", function(d) { return x(d) + ""; })
  726. // .attr('transform', "scale("+slideScale(State.sliderVal)+")")
  727. // .attr("cy", function(d, i) { return '50%'; })
  728. // .attr("cx", function(d, i) { return '50%'; });
  729.  
  730. bars.enter().append("circle")
  731. .attr('transform', "scale("+slideScale(State.sliderVal)+")")
  732. .attr("cy", function(d, i) { return '50%'; })
  733. .attr("cx", function(d, i) { return '50%'; })
  734. .attr("r", function(d) { return x(d) + ""; });
  735.  
  736. bars.exit().remove();
  737.  
  738. };
  739. r.circle_thumb = function() {
  740.  
  741. if (State.thumbs_init[0] != 'init') {
  742. State.thumbs_init[0] = 'init';
  743. root.svg_thumb_one = d3.select("#circle").append("svg")
  744. .attr("width", '100%')
  745. .attr("height", '100%');
  746. }
  747.  
  748. WAVE_DATA = c.bins_select(200);
  749.  
  750. var x_t1 = d3.scale.linear()
  751. .domain([0, d3.max(WAVE_DATA)])
  752. .range([0, 80]);
  753.  
  754. var bars_t1 = svg_thumb_one
  755. .selectAll("circle")
  756. .data(WAVE_DATA, function(d) { return d; });
  757.  
  758. // bars_t1.attr("r", function(d) { return x_t1(d) + ""; })
  759. // .attr("cy", function(d, i) { return '50%'; })
  760. // .attr("cx", function(d, i) { return '50%'; });
  761.  
  762. bars_t1.enter().append("circle")
  763. .attr("cy", function(d, i) { return '50%'; })
  764. .attr("cx", function(d, i) { return '50%'; })
  765. .attr("r", function(d) { return x_t1(d) + ""; });
  766.  
  767. bars_t1.exit().remove();
  768. }
  769. r.chop = function() {
  770.  
  771. if (State.active != 'chop') {
  772. State.active = 'chop';
  773. $('body > svg').empty();
  774. }
  775.  
  776. WAVE_DATA = c.bins_select(70);
  777.  
  778. var x = d3.scale.linear()
  779. .domain([0, d3.max(WAVE_DATA)])
  780. .range([0, 1000]);
  781.  
  782. var bars = svg.selectAll("rect")
  783. .data(WAVE_DATA, function(d) { return d; });
  784.  
  785. bars.attr("width", function(d) { return '200%'; })
  786. .attr("height", function(d) { return x(d) + ""; })
  787. .attr("y", function(d, i) { return '0%'; })
  788. .attr("x", function(d, i) { return '-50%'; });
  789.  
  790. bars.enter().append("rect")
  791. .attr("y", function(d, i) { return '0%'; })
  792. .attr("x", function(d, i) { return '-50%'; })
  793. .attr("width", function(d) { return '200%'; })
  794. .attr("height", function(d) { return x(d) + ""; });
  795.  
  796. bars.exit().remove();
  797. };
  798. r.chop_thumb = function() {
  799.  
  800. if (State.thumbs_init[1] != 'init') {
  801. State.thumbs_init[1] = 'init';
  802. root.svg_thumb_two = d3.select("#chop").append("svg")
  803. .attr("width", '100%')
  804. .attr("height", '100%');
  805. }
  806.  
  807. WAVE_DATA = c.bins_select(200);
  808.  
  809. var x = d3.scale.linear()
  810. .domain([0, d3.max(WAVE_DATA)])
  811. .range([10, 200]);
  812.  
  813. var bars = svg_thumb_two.selectAll("rect")
  814. .data(WAVE_DATA, function(d) { return d; });
  815.  
  816. // bars.attr("width", function(d) { return '200%'; })
  817. // .attr("height", function(d) { return x(d) + ""; })
  818. // .attr("y", function(d, i) { return '0%'; })
  819. // .attr("x", function(d, i) { return '-60%'; });
  820.  
  821. bars.enter().append("rect")
  822. .attr("y", function(d, i) { return '-20%'; })
  823. .attr("x", function(d, i) { return '-50%'; })
  824. .attr("width", function(d) { return '250%'; })
  825. .attr("height", function(d) { return x(d) + ""; });
  826.  
  827. bars.exit().remove();
  828. }
  829. r.icosahedron = function() {
  830.  
  831. // http://bl.ocks.org/mbostock/7782500
  832.  
  833. if (State.active == 'icosahedron') {
  834.  
  835. var time = Date.now() - t0;
  836. var xx = c.total()/100;
  837. h.applyStyles("body > svg path","transform: scale("+xx+","+xx+"); ");
  838. //$('body > svg path').attr("style", "transform: skew("+xx+"deg,"+xx+"deg)");
  839.  
  840. // 1
  841. projection.rotate([time * velocity[0], time * velocity[1]]);
  842. face
  843. .each(function(d) { d.forEach(function(p, i) { d.polygon[i] = projection(p); }); })
  844. .style("display", function(d) { return d.polygon.area() > 0 ? null : "none"; })
  845. .attr("d", function(d) { return "M" + d.polygon.join("L") + "Z"; })
  846.  
  847. // 2
  848. projection2.rotate([time * velocity2[0], time * velocity2[1]]);
  849. face2
  850. .each(function(d) { d.forEach(function(p, i) { d.polygon[i] = projection2(p); }); })
  851. .style("display", function(d) { return d.polygon.area() > 0 ? null : "none"; })
  852. .attr("d", function(d) { return "M" + d.polygon.join("L") + "Z"; })
  853.  
  854. // 3
  855. projection3.rotate([time * velocity3[0], time * velocity3[1]]);
  856. face3
  857. .each(function(d) { d.forEach(function(p, i) { d.polygon[i] = projection3(p); }); })
  858. .style("display", function(d) { return d.polygon.area() > 0 ? null : "none"; })
  859. .attr("d", function(d) { return "M" + d.polygon.join("L") + "Z"; })
  860.  
  861. return;
  862. }
  863.  
  864. State.active = 'icosahedron';
  865. $('body > svg').empty();
  866.  
  867. width = State.width;
  868. height = State.height;
  869. root.velocity = [.10, .005];
  870. root.velocity2 = [-.10, -.05];
  871. root.velocity3 = [.10, .1];
  872. t0 = Date.now();
  873.  
  874. // 1
  875. root.projection = d3.geo.orthographic()
  876. .scale(height/2)
  877. .translate([width/2, height/2])
  878. .center([0, 0]);
  879.  
  880. svg = d3.select("body").append("svg")
  881. .attr("class", "isoco1")
  882. .attr("width", width)
  883. .attr("height", height);
  884.  
  885. root.face = svg.selectAll("path")
  886. .data(h.icosahedronFaces)
  887. .enter()
  888. .append("path").attr("class", "isoco")
  889. .each(function(d) { d.polygon = d3.geom.polygon(d.map(projection)); });
  890.  
  891. // 2
  892. root.projection2 = d3.geo.orthographic()
  893. .scale(height/4)
  894. .translate([width/2, height/2])
  895. .center([0, 0]);
  896.  
  897. svg2 = d3.select("body").append("svg")
  898. .attr("class", "isoco2")
  899. .attr("width", width)
  900. .attr("height", height);
  901.  
  902. root.face2 = svg2.selectAll("path")
  903. .data(h.icosahedronFaces)
  904. .enter()
  905. .append("path").attr("class", "isoco")
  906. .each(function(d) { d.polygon = d3.geom.polygon(d.map(projection2)); });
  907.  
  908. // 3
  909. root.projection3 = d3.geo.orthographic()
  910. .scale(height/1)
  911. .translate([width/2, height/2])
  912. .center([0, 0]);
  913.  
  914. svg3 = d3.select("body").append("svg")
  915. .attr("class", "isoco3")
  916. .attr("width", width)
  917. .attr("height", height);
  918.  
  919. root.face3 = svg3.selectAll("path")
  920. .data(h.icosahedronFaces)
  921. .enter()
  922. .append("path").attr("class", "isoco")
  923. .each(function(d) { d.polygon = d3.geom.polygon(d.map(projection3)); });
  924.  
  925. };
  926. r.icosahedron_thumb = function() {
  927.  
  928. if (State.thumbs_init[2] == 'init') {
  929.  
  930. var xx_t0 = c.total()/100;
  931. var time_t0 = Date.now() - t0_thumb;
  932. h.applyStyles("#icosahedron svg path","transform: scale("+xx_t0+","+xx_t0+"); ")
  933.  
  934. projection_thumb.rotate([time_t0 * velocity_thumb[0], time_t0 * velocity_thumb[1]]);
  935.  
  936. face_thumb
  937. .each(function(d) { d.forEach(function(p, i) { d.polygon[i] = projection_thumb(p); }); })
  938. .style("display", function(d) { return d.polygon.area() > 0 ? null : "none"; })
  939. .attr("d", function(d) { return "M" + d.polygon.join("L") + "Z"; })
  940.  
  941. return;
  942. }
  943.  
  944. State.thumbs_init[2] = 'init';
  945.  
  946. var width = $('#icosahedron').width();
  947. var height = $('#icosahedron').height();
  948. root.velocity_thumb = [.01, .05];
  949. root.t0_thumb = Date.now();
  950.  
  951. root.projection_thumb = d3.geo.orthographic()
  952. .scale(height*1.5)
  953. .translate([width/2, height/2])
  954. .center([0, 0]);
  955.  
  956. root.svg_thumb_three = d3.select("#icosahedron").append("svg")
  957. .attr("width", width)
  958. .attr("height", height);
  959.  
  960. root.face_thumb = svg_thumb_three.selectAll("path")
  961. .data(h.icosahedronFaces)
  962. .enter().append("path")
  963. .each(function(d) { d.polygon = d3.geom.polygon(d.map(projection_thumb)); });
  964.  
  965. };
  966. r.grid2 = function(data) {
  967. // http://bl.ocks.org/mbostock/5731578
  968.  
  969. if (State.active == 'grid') {
  970.  
  971. var dt = Date.now() - time;
  972. projection.rotate([rotate[0] + velocity[0] * dt, rotate[1] + velocity[1] * dt]);
  973. feature.attr("d", path);
  974.  
  975. return;
  976. }
  977. $('body > svg').empty();
  978. State.active = 'grid';
  979.  
  980. root.rotate = [10, -10],
  981. root.velocity = [.03, -.01],
  982. root.time = Date.now();
  983.  
  984. root.projection = d3.geo.orthographic()
  985. .scale(240)
  986. .translate([State.width / 2, State.height / 2])
  987. .clipAngle(90 + 1e-6)
  988. .precision(.3);
  989.  
  990. root.path = d3.geo.path()
  991. .projection(projection);
  992.  
  993. graticule = d3.geo.graticule().minorExtent([[-180, -89], [180, 89 + 1e-4]]);
  994.  
  995.  
  996. svg.append("path")
  997. .datum({type: "Sphere"})
  998. .attr("class", "sphere")
  999. .attr("d", path);
  1000.  
  1001. svg.append("path")
  1002. .datum(graticule)
  1003. .attr("class", "graticule")
  1004. .attr("d", path);
  1005.  
  1006. // svg.append("path")
  1007. // .datum({type: "LineString", coordinates: [[-180, 0], [-90, 0], [0, 0], [90, 0], [180, 0]]})
  1008. // .attr("class", "equator")
  1009. // .attr("d", path);
  1010.  
  1011. root.feature = svg.selectAll("path");
  1012.  
  1013. };
  1014. r.grid = function(data) {
  1015.  
  1016. if (State.active == 'grid') {
  1017.  
  1018. var xx = c.total()/100 + 1;
  1019. xx = (xx<1) ? 1 : xx;
  1020. xx = (xx>1.1) ? 1.1 : xx;
  1021.  
  1022. var style = '';
  1023. for (var i = 0; i < State.vendors.length; i++) {
  1024. style += State.vendors[i]+"transform: scale("+xx+","+xx+"); ";
  1025. }
  1026. $('body > svg path').attr("style", style);
  1027.  
  1028. projection.rotate([Ξ»(p), Ο†(p)]);
  1029. //projection.rotate([Ξ»(p), 0]);
  1030. svg.selectAll("path").attr("d", path);
  1031. p=p+5;
  1032. //((c.total()/100)*10);
  1033.  
  1034. step = Math.floor((c.total()/100)*60);
  1035. step = (step<5) ? 5 : step;
  1036.  
  1037. graticule = d3.geo.graticule()
  1038. .minorStep([step, step])
  1039. .minorExtent([[-180, -90], [180, 90 + 1e-4]]);
  1040.  
  1041. grat.datum(graticule)
  1042. .attr("class", "graticule")
  1043. .attr("d", path);
  1044.  
  1045. return;
  1046. }
  1047.  
  1048. p = 0;
  1049. State.active = 'grid';
  1050. $('body > svg').empty();
  1051.  
  1052. projection = d3.geo.gnomonic()
  1053. .clipAngle(80)
  1054. .scale(500);
  1055.  
  1056. path = d3.geo.path()
  1057. .projection(projection);
  1058.  
  1059. graticule = d3.geo.graticule()
  1060. .minorStep([5, 5])
  1061. .minorExtent([[-180, -90], [180, 90 + 1e-4]]);
  1062.  
  1063. // lamda / longitude
  1064. Ξ» = d3.scale.linear()
  1065. .domain([0, State.width])
  1066. .range([-180, 180]);
  1067.  
  1068. // phi / latitude
  1069. Ο† = d3.scale.linear()
  1070. .domain([0, State.height])
  1071. .range([90, -90]);
  1072.  
  1073. grat = svg.append("path")
  1074. .datum(graticule)
  1075. .attr("class", "graticule")
  1076. .attr("d", path);
  1077.  
  1078. };
  1079. r.grid_thumb = function(data) {
  1080.  
  1081. var width = $('#grid').width();
  1082. var height = $('#grid').height();
  1083.  
  1084. if (State.thumbs_init[3] == 'init') {
  1085.  
  1086. var xx = c.total()/100 + 1;
  1087. xx = (xx==1) ? 0 : xx;
  1088. // xx = (xx>1.4) ? 1.4 : xx;
  1089.  
  1090. var style = '';
  1091. for (var i = 0; i < State.vendors.length; i++) {
  1092. style += State.vendors[i]+"transform: scale("+xx+","+xx+"); ";
  1093. }
  1094. $('#grid svg path').attr("style", style);
  1095.  
  1096. // step = Math.floor((c.total()/100)*5);
  1097. // step = (step<1) ? 1 : step;
  1098.  
  1099. // graticule = d3.geo.graticule()
  1100. // .minorStep([step, step])
  1101. // .minorExtent([[-180, -90], [180, 90 + 1e-4]]);
  1102.  
  1103. // grat.datum(graticule)
  1104. // .attr("class", "graticule")
  1105. // .attr("d", path);
  1106.  
  1107. return;
  1108. }
  1109.  
  1110. State.thumbs_init[3] = 'init';
  1111. $('#grid svg').empty();
  1112.  
  1113. projection = d3.geo.gnomonic()
  1114. .clipAngle(80);
  1115. //.scale(50)
  1116.  
  1117. path = d3.geo.path()
  1118. .projection(projection);
  1119.  
  1120. graticule = d3.geo.graticule()
  1121. .minorStep([2, 2])
  1122. .minorExtent([[-180, -90], [180, 90 + 1e-4]]);
  1123.  
  1124. svg_thumb_four = d3.select("#grid").append("svg")
  1125. .attr("width", width)
  1126. .attr("height", height);
  1127.  
  1128. grat = svg_thumb_four.append("path")
  1129. .datum(graticule)
  1130. .attr("class", "graticule")
  1131. .attr("d", path);
  1132.  
  1133. };
  1134. r.equal = function() {
  1135.  
  1136. if (State.active != 'equal') {
  1137. State.active = 'equal';
  1138. }
  1139.  
  1140. $('body > svg').empty();
  1141. var marginX = Math.floor(State.width/10);
  1142. var marginY = Math.floor(State.height/10);
  1143. var w = Math.floor((State.width - marginX*2)/21);
  1144.  
  1145. WAVE_DATA = c.normalize_binned(50);
  1146.  
  1147. var x = d3.scale.linear()
  1148. .domain([0, WAVE_DATA.length])
  1149. .range([marginX, State.width-marginX]);
  1150.  
  1151. var y = d3.scale.linear()
  1152. .domain([0, 1])
  1153. .range([0,State.height-marginY*3]);
  1154.  
  1155. var opacity = d3.scale.sqrt()
  1156. .domain([0, 1])
  1157. .range([.25, .8]);
  1158.  
  1159. root.squares = svg.selectAll("g")
  1160. .data(WAVE_DATA, function(d) { return d; });
  1161.  
  1162. squares.enter()
  1163. .append("g")
  1164. .attr("transform", function(d,i) { return "translate(" + ((i*w)+marginX) + "," + ((State.height/2)-(y(d)/2)) + ")"; })
  1165. .attr("opacity", function(d) { return opacity(d); })
  1166. .append("rect")
  1167. .attr("class", "equal")
  1168. .attr("width", w-7 +'px')
  1169. .attr("height", function(d,i) { return y(d) + "px" });
  1170.  
  1171. squares.exit().remove();
  1172.  
  1173. };
  1174. r.equal_thumb = function() {
  1175.  
  1176. if (State.thumbs_init[4] != 'init') {
  1177. State.thumbs_init[4] = 'init';
  1178. root.svg_thumb_five = d3.select("#equal").append("svg")
  1179. .attr("width", '100%')
  1180. .attr("height", '100%');
  1181. }
  1182.  
  1183. $('#equal svg').empty();
  1184. var width = $('#equal').width();
  1185. var height = $('#equal').height();
  1186. var marginX = Math.floor(width/10);
  1187. var marginY = Math.floor(height/10);
  1188. var w = Math.floor((width - marginX*2)/5);
  1189.  
  1190. WAVE_DATA = c.normalize_binned(200);
  1191. WAVE_DATA = WAVE_DATA.slice(1);
  1192.  
  1193. var x = d3.scale.linear()
  1194. .domain([0, WAVE_DATA.length])
  1195. .range([marginX, width-marginX]);
  1196.  
  1197. var y = d3.scale.linear()
  1198. .domain([0, 1])
  1199. .range([0,height-marginY*3]);
  1200.  
  1201. var opacity = d3.scale.sqrt()
  1202. .domain([0, 1])
  1203. .range([.25, .8]);
  1204.  
  1205. root.squares = svg_thumb_five.selectAll("g")
  1206. .data(WAVE_DATA, function(d) { return d; });
  1207.  
  1208. squares.enter()
  1209. .append("g")
  1210. .attr("transform", function(d,i) { return "translate(" + ((i*w)+marginX) + "," + ((height/2)-(y(d)/2)) + ")"; })
  1211. .attr("opacity", function(d) { return opacity(d); })
  1212. .append("rect")
  1213. .attr("class", "equal")
  1214. .attr("width", w-7 +'px')
  1215. .attr("height", function(d,i) { return y(d) + "px" });
  1216.  
  1217. squares.exit().remove();
  1218.  
  1219. };
  1220. r.spin = function() {
  1221.  
  1222. if (State.active == 'spin') {
  1223.  
  1224. WAVE_DATA = c.total()*2;
  1225. //WAVE_DATA = c.normalize_binned(200,1000,10);
  1226. var $c = $('body > svg circle');
  1227.  
  1228. $c.attr("style", "stroke-width: "+WAVE_DATA*4+"px");
  1229. $c.attr("stroke-dashoffset", WAVE_DATA+"px");
  1230. $c.attr("stroke-dasharray", WAVE_DATA/6+"px");
  1231. $c.attr("opacity", WAVE_DATA/2200);
  1232.  
  1233. return;
  1234. }
  1235.  
  1236. State.active = 'spin';
  1237. $('body > svg').empty();
  1238.  
  1239. var elems = [
  1240. { id: 'c1', radius: 300 },
  1241. { id: 'c4', radius: 10 },
  1242. { id: 'c2', radius: 100 },
  1243. { id: 'c3', radius: 50 }
  1244. ];
  1245.  
  1246. bars = svg.selectAll("circle")
  1247. .data(elems, function(d,i) { return i; });
  1248.  
  1249. bars.enter().append("circle")
  1250. .attr("class", "spin")
  1251. .attr("cy", "50%")
  1252. .attr("cx", "50%")
  1253. .attr("id", function(d) { return d.id; })
  1254. .attr("r", function(d) { return d.radius + ""; });
  1255.  
  1256. bars.exit().remove();
  1257.  
  1258. };
  1259. r.spin_thumb = function() {
  1260.  
  1261. if (State.thumbs_init[5] == 'init') {
  1262.  
  1263. WAVE_DATA = c.total()*2;
  1264. //WAVE_DATA = c.normalize_binned(200,1000,10);
  1265. var $c = $('#spin svg circle');
  1266.  
  1267. $c.attr("style", "stroke-width: "+WAVE_DATA*4+"px");
  1268. $c.attr("stroke-dashoffset", WAVE_DATA+"px");
  1269. $c.attr("stroke-dasharray", WAVE_DATA/6+"px");
  1270. $c.attr("opacity", WAVE_DATA/2200);
  1271.  
  1272. return;
  1273. }
  1274.  
  1275. $('#spin svg').empty();
  1276. State.thumbs_init[5] = 'init';
  1277. root.svg_thumb_six = d3.select("#spin").append("svg")
  1278. .attr("width", '100%')
  1279. .attr("height", '100%');
  1280.  
  1281. var elems = [
  1282. // { id: 'c1', radius: 300 },
  1283. { id: 'c4', radius: 10 },
  1284. // { id: 'c2', radius: 100 },
  1285. { id: 'c3', radius: 50 }
  1286. ];
  1287.  
  1288. bars_t6 = svg_thumb_six.selectAll("circle")
  1289. .data(elems, function(d,i) { return i; });
  1290.  
  1291. bars_t6.enter().append("circle")
  1292. .attr("class", "spin")
  1293. .attr("cy", "50%")
  1294. .attr("cx", "50%")
  1295. .attr("id", function(d) { return d.id; })
  1296. .attr("r", function(d) { return d.radius + ""; });
  1297.  
  1298. bars_t6.exit().remove();
  1299.  
  1300. };
  1301. r.hexbin = function() {
  1302.  
  1303. // http://bl.ocks.org/mbostock/4248145
  1304. // http://bl.ocks.org/mbostock/4248146
  1305.  
  1306. $('body > svg').empty();
  1307.  
  1308. if (State.active != 'hexbin') {
  1309. randomX = d3.random.normal(State.width/2, 700),
  1310. ps = d3.range(1024).map(function() { return randomX(); });
  1311. }
  1312.  
  1313. State.active = 'hexbin';
  1314. points = d3.zip(ps, c.normalize(State.height, 0));
  1315. //randomY = d3.random.normal(height / 2, 300),
  1316. //points = d3.range(2000).map(function() { return [randomX(), randomY()]; });
  1317.  
  1318. color = d3.scale.linear()
  1319. .domain([0, 20])
  1320. //.range(["black", "white"])
  1321. .range([$('.dotstyle li.current a').css('background-color'), $('.dotstyle li.current a').css('background-color')])
  1322. .interpolate(d3.interpolateLab);
  1323.  
  1324. hexbin = d3.hexbin()
  1325. .size([State.width, State.height])
  1326. .radius(50);
  1327.  
  1328. radius = d3.scale.linear()
  1329. .domain([0, 20])
  1330. .range([0, 130]);
  1331.  
  1332. svg.append("g")
  1333. .selectAll(".hexagon")
  1334. .data(hexbin(points))
  1335. .enter().append("path")
  1336. .attr("class", "hexagon")
  1337. .attr("id", "hexx")
  1338. .attr("d", function(d) { return hexbin.hexagon(radius(d.length)); })
  1339. .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
  1340. .style("fill", function(d) { return color(d.length); })
  1341. .style("opacity", function(d) { return 0.8-(radius(d.length)/180); });
  1342.  
  1343. };
  1344. r.hexbin_thumb = function() {
  1345.  
  1346. // http://bl.ocks.org/mbostock/4248145
  1347. // http://bl.ocks.org/mbostock/4248146
  1348.  
  1349. var width = $('#hexbin').width();
  1350. var height = $('#hexbin').height();
  1351.  
  1352. if (State.thumbs_init[6] != 'init') {
  1353. root.svg_thumb_seven = d3.select("#hexbin").append("svg")
  1354. .attr("width", '100%')
  1355. .attr("height", '100%');
  1356.  
  1357. State.thumbs_init[6] = 'init';
  1358. randomX_t7 = d3.random.normal(width/2, 50),
  1359. ps_t7 = d3.range(1024).map(function() { return randomX_t7(); });
  1360. }
  1361.  
  1362. $('#hexbin svg').empty();
  1363. points_t7 = d3.zip(ps_t7, c.normalize(height*1.5, -20));
  1364.  
  1365. color_t7 = d3.scale.linear()
  1366. .domain([0, 50])
  1367. .range(["black", "white"])
  1368. .interpolate(d3.interpolateLab);
  1369.  
  1370. hexbin_t7 = d3.hexbin()
  1371. .size([width, height])
  1372. .radius(15);
  1373.  
  1374. radius_t7 = d3.scale.linear()
  1375. .domain([0, 10])
  1376. .range([0, 15]);
  1377.  
  1378. svg_thumb_seven.append("g")
  1379. .selectAll(".hexagon")
  1380. .data(hexbin_t7(points_t7))
  1381. .enter().append("path")
  1382. .attr("class", "hexagon")
  1383. .attr("d", function(d) { return hexbin_t7.hexagon(15); })
  1384. .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
  1385. .style("fill", function(d) { return color_t7(d.length); });
  1386.  
  1387. };
  1388. r.voronoi = function() {
  1389.  
  1390. // http://bl.ocks.org/mbostock/4060366
  1391.  
  1392. if (State.active == 'voronoi') {
  1393. redraw();
  1394. return;
  1395. }
  1396.  
  1397. State.active = 'voronoi';
  1398. width = State.width;
  1399. height = State.height;
  1400.  
  1401. vertices = d3.range(100).map(function(d) {
  1402. return [Math.random() * width, Math.random() * height];
  1403. });
  1404.  
  1405. voronoi = d3.geom.voronoi()
  1406. .clipExtent([[0, 0], [width, height]]);
  1407.  
  1408. svg = d3.select("body").append("svg")
  1409. .attr("width", width)
  1410. .attr("height", height);
  1411.  
  1412. path = svg.append("g").selectAll("path");
  1413.  
  1414. svg.selectAll("circle")
  1415. .data(vertices.slice(1))
  1416. .enter().append("circle")
  1417. .attr("transform", function(d) { return "translate(" + d + ")"; })
  1418. .attr("r", 1.5);
  1419.  
  1420. redraw();
  1421.  
  1422. function redraw() {
  1423.  
  1424. vertices = d3.range(100).map(function(d) {
  1425. return [Math.random() * width, Math.random() * height];
  1426. });
  1427.  
  1428. path = path.data(voronoi(vertices), polygon);
  1429.  
  1430. path.exit().remove();
  1431.  
  1432. path.enter().append("path")
  1433. .attr("class", function(d, i) { return "q" + (i % 9) + "-9"; })
  1434. .attr("d", polygon);
  1435.  
  1436. path.order();
  1437. };
  1438.  
  1439. function polygon(d) {
  1440. return "M" + d.join("L") + "Z";
  1441. };
  1442.  
  1443. };
  1444. root.Render = r;
  1445.  
  1446. // helper methods ///////////////////////////////////////////////////////////////////////////////
  1447. var h = {};
  1448. h.toggleMenu = function(x) {
  1449. console.log('h.toggleMenu');
  1450.  
  1451. if (x == 'toggle')
  1452. x = ($('.menu').hasClass('menu-open')) ? 'close' : 'open';
  1453.  
  1454. if (x == 'open') {
  1455. $('.menu').addClass('menu-open');
  1456. $('.icon-menu').addClass('fadeOut');
  1457. //$("body > svg").attr("class", "svg-open");
  1458. }
  1459. else {
  1460. $('.menu').removeClass('menu-open');
  1461. //$("body > svg").attr("class", "svg-closed");
  1462. }
  1463.  
  1464. };
  1465. h.toggleFullScreen = function() {
  1466. console.log("h.toggleFullScreen fired");
  1467.  
  1468. // thanks mdn
  1469.  
  1470. if (!document.fullscreenElement && // alternative standard method
  1471. !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) { // current working methods
  1472.  
  1473. $('.icon-expand').addClass('icon-contract');
  1474. if (document.documentElement.requestFullscreen) {
  1475. document.documentElement.requestFullscreen();
  1476. } else if (document.documentElement.msRequestFullscreen) {
  1477. document.documentElement.msRequestFullscreen();
  1478. } else if (document.documentElement.mozRequestFullScreen) {
  1479. document.documentElement.mozRequestFullScreen();
  1480. } else if (document.documentElement.webkitRequestFullscreen) {
  1481. document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  1482. }
  1483. } else {
  1484. $('.icon-expand').removeClass('icon-contract');
  1485. if (document.exitFullscreen) {
  1486. document.exitFullscreen();
  1487. } else if (document.msExitFullscreen) {
  1488. document.msExitFullscreen();
  1489. } else if (document.mozCancelFullScreen) {
  1490. document.mozCancelFullScreen();
  1491. } else if (document.webkitExitFullscreen) {
  1492. document.webkitExitFullscreen();
  1493. }
  1494. }
  1495. }
  1496. h.hideHUD = function() {
  1497. //$('.icon-knobs').is(':hover') ||
  1498. if ($('#mp3_player').is(':hover') || $('.dotstyle').is(':hover') || $('#slider').is(':hover') || $('#slider-volume').is(':hover') || $('.icon-expand').is(':hover') || $('.icon-github2').is(':hover') || $('.icon-loop-on').is(':hover') || $('.icon-question').is(':hover') || $('.icon-keyboard2').is(':hover') || $('.song-metadata').is(':hover') || $('.icon-forward2').is(':hover') || $('.icon-backward2').is(':hover') || $('.icon-pause').is(':hover') || $('.schover').is(':hover'))
  1499. return;
  1500.  
  1501. $('#mp3_player').addClass('fadeOut');
  1502. $('.icon-menu').addClass('fadeOut');
  1503. $('.menu-wide').addClass('fadeOut');
  1504. $('.menu').addClass('fadeOut');
  1505. $('.menu-controls').addClass('fadeOut');
  1506. $('#progressBar').addClass('fadeOut');
  1507. $('html').addClass('noCursor');
  1508. if (State.metaLock == false)
  1509. $('.song-metadata').removeClass("show-meta");
  1510.  
  1511. State.hud = 0;
  1512. }
  1513. h.showHUD = function() {
  1514.  
  1515. $('#mp3_player').removeClass('fadeOut');
  1516. $('.icon-menu').removeClass('fadeOut');
  1517. $('.menu-wide').removeClass('fadeOut');
  1518. $('.menu').removeClass('fadeOut');
  1519. $('.menu-controls').removeClass('fadeOut');
  1520. $('#progressBar').removeClass('fadeOut');
  1521. $('html').removeClass('noCursor');
  1522. $('.song-metadata').addClass("show-meta");
  1523.  
  1524. State.hud = 1;
  1525.  
  1526. }
  1527. h.showModal = function(id) {
  1528. if ($(id).hasClass('md-show')) {
  1529. h.hideModals();
  1530. return;
  1531. }
  1532.  
  1533. if ($('.md-show').length > 0) {
  1534. h.hideModals();
  1535. }
  1536.  
  1537. $(id).addClass('md-show');
  1538.  
  1539. };
  1540. h.hideModals = function() {
  1541. $('.md-modal').removeClass('md-show');
  1542. };
  1543.  
  1544. h.resize = function() {
  1545. $("svg").css("margin-left", ($(window).width() / 2) - 450);
  1546. };
  1547. h.stop = function(e) {
  1548. e.stopPropagation();
  1549. e.preventDefault();
  1550. };
  1551. h.handleDrop = function(e) {
  1552. console.log('h.handleDrop fired');
  1553.  
  1554. h.stop(e);
  1555. h.removeSoundCloud();
  1556. //if (window.File && window.FileReader && window.FileList && window.Blob) {
  1557.  
  1558. URL.revokeObjectURL(objectUrl);
  1559. var file = e.originalEvent.dataTransfer.files[0];
  1560.  
  1561. if (!file.type.match(/audio.*/)) {
  1562. console.log("not audio file");
  1563. return;
  1564. }
  1565.  
  1566. h.readID3(file);
  1567.  
  1568. var objectUrl = URL.createObjectURL(file);
  1569. a.loadSoundHTML5(objectUrl);
  1570.  
  1571. // var files = e.originalEvent.dataTransfer.files;
  1572.  
  1573. // if (files[0].type.match(/audio.*/)) {
  1574. // console.log('true');
  1575.  
  1576. // var read = new FileReader();
  1577. // read.readAsDataURL(files[0]);
  1578. // read.onload = function(e) {
  1579. // console.log(' -- FileReader onload fired');
  1580.  
  1581. // // fuuzikplay[3] = soundManager.createSound({
  1582. // // id: "audio",
  1583. // // url: d.target.result
  1584. // // });
  1585. // //audio.pause();
  1586.  
  1587. // audio = new Audio();
  1588. // audio.src = e.target.result;
  1589. // audio.controls = true;
  1590. // audio.loop = true;
  1591. // audio.autoplay = true;
  1592.  
  1593. // $('#audio_box').empty();
  1594. // document.getElementById('audio_box').appendChild(audio);
  1595. // a.audioBullshit();
  1596.  
  1597. // };
  1598. // }
  1599.  
  1600. };
  1601. h.readID3 = function(file) {
  1602. console.log('h.readID3 fired');
  1603.  
  1604. $('.song-metadata').html("");
  1605.  
  1606. if (typeof file == 'string') {
  1607.  
  1608. ID3.loadTags(audio.src, function() {
  1609. var tags = ID3.getAllTags(audio.src);
  1610. h.renderSongTitle(tags);
  1611. });
  1612.  
  1613. }
  1614.  
  1615. else {
  1616.  
  1617. ID3.loadTags(file.urn || file.name, function() {
  1618. var tags = ID3.getAllTags(file.urn || file.name);
  1619. tags.dragged = true;
  1620. h.renderSongTitle(tags);
  1621.  
  1622. if( "picture" in tags ) {
  1623. var image = tags.picture;
  1624. var base64String = "";
  1625. for (var i = 0; i < image.data.length; i++) {
  1626. base64String += String.fromCharCode(image.data[i]);
  1627. }
  1628. //console.log("data:" + image.format + ";base64," + window.btoa(base64String));
  1629. //$("art").src = "data:" + image.format + ";base64," + window.btoa(base64String);
  1630. //$("art").style.display = "block";
  1631. }
  1632. else {
  1633. //console.log("nope.");
  1634. //$("art").style.display = "none";
  1635. }
  1636. }, {
  1637. dataReader: FileAPIReader(file)
  1638. });
  1639. }
  1640.  
  1641. };
  1642.  
  1643. h.removeSoundCloud = function() {
  1644. State.soundCloudURL = null;
  1645. State.soundCloudData = null;
  1646. State.soundCloudTracks = null;
  1647.  
  1648. $('.song-metadata').html("");
  1649. $('.song-metadata').attr('data-go', "");
  1650.  
  1651. $('#sc_input').val("");
  1652. $('#sc_url span').html('SOUNDCLOUD_URL');
  1653.  
  1654. // load local songs?
  1655.  
  1656. };
  1657.  
  1658. h.toggleShuffle = function() {
  1659. State.shuffle = !State.shuffle;
  1660. console.log('shuffe:'+State.shuffle);
  1661. }
  1662. h.togglePlay = function() {
  1663. (audio && audio.paused == false) ? audio.pause() : audio.play();
  1664. $('.icon-pause').toggleClass('icon-play');
  1665. };
  1666. h.songEnded = function() {
  1667. console.log('h.songEnded fired');
  1668.  
  1669. h.changeSong('n');
  1670.  
  1671. };
  1672. h.changeSong = function(direction) {
  1673. console.log('h.changeSong fired');
  1674.  
  1675. var totalTracks = State.soundCloudTracks || State.playlist.length;
  1676.  
  1677. if (State.soundCloudData && State.soundCloudTracks <= 1) {
  1678. audio.currentTime = 0;
  1679. $('.icon-pause').removeClass('icon-play');
  1680. return;
  1681. }
  1682.  
  1683. if (State.shuffle == true) {
  1684. console.log("shuffling song ("+totalTracks+" total)");
  1685. State.currentSong = Math.ceil(Math.random()*totalTracks);
  1686. console.log(State.currentSong);
  1687. }
  1688.  
  1689. if (direction == 'n')
  1690. State.currentSong = State.currentSong + 1;
  1691.  
  1692. else if (direction == 'p') {
  1693. if (audio.currentTime < 3) {
  1694. State.currentSong = (State.currentSong <= 0) ? State.currentSong+totalTracks-1 : State.currentSong - 1;
  1695. }
  1696. else {
  1697. audio.currentTime = 0;
  1698. $('.icon-pause').removeClass('icon-play');
  1699. return;
  1700. }
  1701. }
  1702. else {
  1703. State.currentSong = Math.floor(Math.random() * totalTracks);
  1704. }
  1705.  
  1706. if (State.soundCloudData) {
  1707. if (State.shuffle == true)
  1708. var trackNum = Math.ceil(Math.random()*State.soundCloudTracks);
  1709. else
  1710. var trackNum = Math.abs(State.currentSong)%State.soundCloudTracks;
  1711. h.renderSongTitle(State.soundCloudData[trackNum]);
  1712. a.loadSoundHTML5(State.soundCloudData[trackNum].uri+'/stream?client_id=67129366c767d009ecc75cec10fa3d0f');
  1713. }
  1714. else {
  1715. if (audio) {
  1716. audio.src = 'mp3/'+State.playlist[Math.abs(State.currentSong)%State.playlist.length];
  1717. h.readID3(audio.src);
  1718. }
  1719. }
  1720.  
  1721. $('.icon-pause').removeClass('icon-play');
  1722.  
  1723. };
  1724. h.renderSongTitle = function(obj) {
  1725. console.log('h.renderSongTitle fired');
  1726.  
  1727. if (State.soundCloudData) {
  1728. var trackNum = Math.abs(State.currentSong)%State.soundCloudTracks;
  1729. var regs = new RegExp(obj.user.username, 'gi');
  1730. var prettyTitle = obj.title;
  1731.  
  1732. if (prettyTitle.search(regs) == -1)
  1733. prettyTitle += ' <b>' + obj.user.username + '</b>';
  1734.  
  1735. //var prettyTitle = obj.title.replace(regs, "<b>"+obj.user.username+"</b>");
  1736.  
  1737. if (State.soundCloudTracks > 1)
  1738. prettyTitle += ' ['+(trackNum+1)+'/'+State.soundCloudTracks+']';
  1739.  
  1740. $('.song-metadata').html(prettyTitle);
  1741. $('.song-metadata').attr('data-go', obj.permalink_url);
  1742. }
  1743. else {
  1744. // id3?
  1745. var prettyTitle = '"'+obj.title+'" by <b>'+obj.artist+'</b>'; // on <i>'+tags.album+'</i>
  1746. var trackNum = Math.abs(State.currentSong)%State.playlist.length;
  1747.  
  1748. if (State.playlist.length > 1 && !obj.dragged)
  1749. prettyTitle += ' ['+(trackNum+1)+'/'+State.playlist.length+']';
  1750.  
  1751. $('.song-metadata').html(prettyTitle);
  1752. $('.song-metadata').attr('data-go', State.playListLinks[trackNum]);
  1753. }
  1754.  
  1755. $('.song-metadata').addClass("show-meta");
  1756.  
  1757. State.metaLock = true;
  1758. clearTimeout(metaHide);
  1759. // in 3 seconds, remove class unless lock
  1760. metaHide = setTimeout(function() {
  1761. State.metaLock = false;
  1762. if (State.hud == 0)
  1763. $('.song-metadata').removeClass("show-meta");
  1764. }, State.fastHide || 3000);
  1765.  
  1766. };
  1767. h.tooltipReplace = function() {
  1768. console.log('h.tooltipReplace fired');
  1769.  
  1770. var text = $(this).attr('data-hovertext');
  1771. console.log(text);
  1772. if (text != null) {
  1773. State.hoverTemp = $('.song-metadata').html();
  1774. $('.song-metadata').html(text);
  1775. }
  1776.  
  1777. };
  1778. h.tooltipUnReplace = function() {
  1779. console.log('h.tooltipUnReplace fired');
  1780.  
  1781. if (State.hoverTemp != null) {
  1782. $('.song-metadata').html(State.hoverTemp);
  1783. State.hoverTemp = null;
  1784. }
  1785.  
  1786. };
  1787. h.songGo = function() {
  1788. console.log('h.songGo fired.');
  1789.  
  1790. if (!$(this).attr('data-go'))
  1791. return false;
  1792. audio.pause();
  1793. $('.icon-pause').removeClass('icon-play');
  1794. window.open($(this).attr('data-go'),'_blank');
  1795.  
  1796. };
  1797.  
  1798. h.themeChange = function(n) {
  1799. n = +n;
  1800. n = (n<0) ? 5 : n;
  1801. n = (n>5) ? 0 : n;
  1802. State.theme = n;
  1803.  
  1804. console.log('h.themeChange:'+n);
  1805. var name = 'theme_'+n;
  1806. $('html').attr('class',name);
  1807.  
  1808. $('.dotstyle li.current').removeClass('current');
  1809. $('.dotstyle li:eq('+n+')').addClass('current');
  1810.  
  1811. };
  1812. h.vizChange = function(n) {
  1813. n = (n<0) ? 6 : n;
  1814. n = (n>6) ? 0 : n;
  1815.  
  1816. console.log('h.vizChange:'+n);
  1817. State.trigger = n;
  1818. $('.menu li.active').removeClass('active');
  1819. $('.menu li[viz-num="'+n+'"]').addClass('active');
  1820.  
  1821. };
  1822. h.infiniteChange = function(toggle) {
  1823. console.log('h.infiniteChange fired: '+toggle);
  1824.  
  1825. clearInterval(State.changeInterval);
  1826.  
  1827. State.changeInterval = setInterval(function(){
  1828. h.themeChange(Math.floor(Math.random() * 6));
  1829. h.vizChange(Math.floor(Math.random() * 8));
  1830. },toggle);
  1831.  
  1832. if (toggle == null)
  1833. clearInterval(State.changeInterval);
  1834.  
  1835. };
  1836.  
  1837. h.icosahedronFaces = function(slide) {
  1838. var slide = slide || 180;
  1839. var faces = [],
  1840. y = Math.atan2(1, 2) * slide / Math.PI;
  1841. for (var x = 0; x < 360; x += 72) {
  1842. faces.push(
  1843. [[x + 0, -90], [x + 0, -y], [x + 72, -y]],
  1844. [[x + 36, y], [x + 72, -y], [x + 0, -y]],
  1845. [[x + 36, y], [x + 0, -y], [x - 36, y]],
  1846. [[x + 36, y], [x - 36, y], [x - 36, 90]]
  1847. );
  1848. }
  1849. return faces;
  1850. };
  1851. h.degreesToRads = function(n) {
  1852. return d3.scale.linear().domain([0, 360]).range([0, 2 * Math.PI])(this);
  1853. };
  1854.  
  1855. h.microphoneError = function(e) {
  1856. // user clicked not to let microphone be used
  1857. console.log(e);
  1858. };
  1859. h.getURLParameter = function(sParam) {
  1860. //http://www.jquerybyexample.net/2012/06/get-url-parameters-using-jquery.html
  1861. var sPageURL = window.location.search.substring(1);
  1862. var sURLVariables = sPageURL.split('&');
  1863. for (var i = 0; i < sURLVariables.length; i++) {
  1864. var sParameterName = sURLVariables[i].split('=');
  1865. if (sParameterName[0] == sParam) {
  1866. return sParameterName[1];
  1867. }
  1868. }
  1869. };
  1870. h.isMobile = function() {
  1871. // returns true if user agent is a mobile device
  1872. return (/iPhone|iPod|iPad|Android|BlackBerry/).test(navigator.userAgent);
  1873. };
  1874. h.detectEnvironment = function() {
  1875. if (window.location.protocol.search('chrome-extension') >= 0)
  1876. return 'chrome-extension';
  1877.  
  1878. if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0)
  1879. return 'safari';
  1880.  
  1881. // https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
  1882.  
  1883. if (!!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0)
  1884. return 'opera';
  1885.  
  1886. if (typeof InstallTrigger !== 'undefined')
  1887. return 'firefox';
  1888.  
  1889. // var isChrome = !!window.chrome && !isOpera; // Chrome 1+
  1890. // var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
  1891.  
  1892. return 'unknown';
  1893.  
  1894. };
  1895. h.getCookie = function(c_name) {
  1896. //console.log("h.getCookie fired");
  1897. var i,x,y,ARRcookies=document.cookie.split(";");
  1898. for (i=0;i<ARRcookies.length;i++) {
  1899. x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
  1900. y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
  1901. x=x.replace(/^\s+|\s+$/g,"");
  1902. if (x==c_name) {
  1903. return unescape(y);
  1904. }
  1905. }
  1906. };
  1907. h.setCookie = function(c_name,value,exdays) {
  1908. //console.log("h.setCookie fired");
  1909. var exdate=new Date();
  1910. exdate.setDate(exdate.getDate() + exdays);
  1911. var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
  1912. document.cookie=c_name + "=" + c_value;
  1913. };
  1914. h.prettyLog = function(data) {
  1915. console.log("h.prettyLog fired");
  1916. return false;
  1917.  
  1918. var x = data || localStorage.account;
  1919. if (typeof x == 'object') x = JSON.stringify(x);
  1920. if (typeof data == "undefined") return;
  1921. if (typeof data == "string") {
  1922. console.log(data);
  1923. return;
  1924. }
  1925. console.log('\n'+JSON.stringify(JSON.parse(x),null, 4));
  1926. };
  1927. h.applyStyles = function(selector, styleToApply){
  1928. if(typeof selector == undefined) return;
  1929. if(typeof styleToApply == undefined) return;
  1930.  
  1931. var style = '';
  1932. for (var i = 0; i < State.vendors.length; i++) {
  1933. style += State.vendors[i]+ styleToApply;
  1934. }
  1935. $(selector).attr("style", style);
  1936. };
  1937. root.Helper = h;
  1938.  
  1939. }).call(this);
  1940.  
  1941. $(document).ready(App.init);
Add Comment
Please, Sign In to add comment