Template:Toronto/js/script

// Autocomplete ================================================================

function start_autocomplete() {

 pages = [
   "Analysis",
   "Attributions",
   "Basic Part",
   "Collaborations",
   "Demonstrate",
   "Description",
   "Design",
   "Drylab",
   "Engagement",
   "Experiments",
   "Genetic Code Workshop",
   "Guide",
   "Gold Integrated",
   "HP Silver",
   "Hardware",
   "Home",
   "Human Practices",
   "Icon-a-thon",
   "Improve",
   "InterLab",
   "Interviews",
   "Model",
   "Notebook",
   "ODE",
   "Parts",
   "Podcast",
   "Protein Modelling",
   "Results",
   "Safety",
   "Team",
   "Wetlab"
 ]
 link = [
   "https://2017.igem.org/Team:Toronto/Analysis",
   "https://2017.igem.org/Team:Toronto/Attributions",
   "https://2017.igem.org/Team:Toronto/Basic_Part",
   "https://2017.igem.org/Team:Toronto/Collaborations",
   "https://2017.igem.org/Team:Toronto/Demonstrate",
   "https://2017.igem.org/Team:Toronto/Description",
   "https://2017.igem.org/Team:Toronto/Design",
   "https://2017.igem.org/Team:Toronto/Drylab",
   "https://2017.igem.org/Team:Toronto/Engagement",
   "https://2017.igem.org/Team:Toronto/Experiments",
   "https://2017.igem.org/Team:Toronto/Genetic_Code_Workshop",
   "https://2017.igem.org/Team:Toronto/Guide",
   "https://2017.igem.org/Team:Toronto/HP/Gold_Integrated",
   "https://2017.igem.org/Team:Toronto/HP/Silver",
   "https://2017.igem.org/Team:Toronto/Hardware",
   "https://2017.igem.org/Team:Toronto",
   "https://2017.igem.org/Team:Toronto/Human_Practices",
   "https://2017.igem.org/Team:Toronto/Icon-a-thon",
   "https://2017.igem.org/Team:Toronto/Improve",
   "https://2017.igem.org/Team:Toronto/InterLab",
   "https://2017.igem.org/Team:Toronto/Interviews",
   "https://2017.igem.org/Team:Toronto/Model",
   "https://2017.igem.org/Team:Toronto/Notebook",
   "https://2017.igem.org/Team:Toronto/ODE",
   "https://2017.igem.org/Team:Toronto/Parts",
   "https://2017.igem.org/Team:Toronto/Podcast",
   "https://2017.igem.org/Team:Toronto/Protein-Modelling",
   "https://2017.igem.org/Team:Toronto/Results",
   "https://2017.igem.org/Team:Toronto/Safety",
   "https://2017.igem.org/Team:Toronto/Team",
   "https://2017.igem.org/Team:Toronto/Wetlab"
 ]
   function autocomplete() {
     // console.log('Autocomplete has loaded');
     var input = document.getElementById('autocomplete');
     var suggest = document.getElementById("auto-suggest");
     var search = document.getElementById("search");
     var navbarSearch = document.getElementById("navbarSearch");
     // Opens up the input bar
     input.addEventListener('focus', function() {
       input.style.transition = '0.5s';
       input.style.width = '300px';
       input.style.paddingLeft = '30px';
     });
     // Closes input and auto-suggest at click event
     input.addEventListener('blur', function() {
       input.value = ;
       setTimeout(function() {
       suggest.innerHTML = ;
       input.style.width = '10px';
       input.style.padding = '5px 10px';
     }, 750);
     });
     // Add keyboard scrolling functionality
     input.addEventListener("keyup", function() {
       matches = [];
       pages.forEach(function(elem, i) {
         if (elem.toLowerCase().includes(input.value.toLowerCase()) && input.value != ) {
           var li = document.createElement('li');
           var a = document.createElement('a');
           var text = document.createTextNode(elem.toUpperCase())
           a.setAttribute('href', link[i])
           a.appendChild(text)
           li.appendChild(a)
           matches.push(li);
         }
       });
       suggest.innerHTML=;
       if (matches.length == 0) {
         search.style.display = 'none';
       } else {
         search.style.display = 'block';
         matches.forEach(function(elem) {
           suggest.appendChild(elem)
         });
       }
     });
   }
   autocomplete();

}

start_autocomplete();

// Set and unset the active class function setActive(elem) {

 var sideNav = document.getElementsByClassName('sidebar-minibox');
 // console.log(sideNav);
 var ul = sideNav[0].getElementsByTagName('ul');
 console.log(ul);
 var li = ul[0].getElementsByTagName('li');
 for (i=0; i<li.length; i++) {
   li[i].classList.remove('active');
 }
 elem.classList.add('active');

}

// Build the list items of the sideNav function build(item, id) {

 var li = document.createElement('li');
 var anchor = document.createElement('a');
 var text = document.createTextNode(item.innerText);
 anchor.appendChild(text)
 anchor.setAttribute('href', '#'+id);
 li.appendChild(anchor);
 li.setAttribute('onclick', 'setActive(this)');
 return li;

}

function scrollWatch(scrollHeights, sectionContent) {

 var header = document.getElementsByClassName('header')[0];
 var sideNav = document.getElementsByClassName('sidebar-minibox')[0];
 var content = document.getElementsByClassName('content-page')[0];
 var footer = document.getElementsByClassName('footer')[0];
 var sideNavItems = sideNav.getElementsByTagName('li');
 window.addEventListener('scroll', function() {
   var mainNavScrollHeight = header.scrollHeight;
   var windowPageYOffset = window.pageYOffset;
   var windowInnerHeight = window.innerHeight;
   var documentBodyHeight = document.body.offsetHeight;
   // var footerScrollHeight = footer.scrollHeight;
   var footerScrollHeight = 0;
   var contentScroll = windowPageYOffset + mainNavScrollHeight;
   var bottom = documentBodyHeight - windowInnerHeight;
   // console.log(contentScroll);
   var currentView = scrollHeights.filter(function(arr) {
     // return arr < contentScroll;
     return arr < windowPageYOffset;
   });
   var currentViewLength = currentView.length;
   // Make sure that the seek class is removed from the top element of the
   // sideNav when the top of the page is scrolled to
   if (contentScroll > windowPageYOffset) {
     sideNavItems[0].classList.remove('active');
   }
   // Add the active class to the list button in sideNav when the corresponding
   // section is in view. Remove this class when it is not.
   if (currentViewLength > 0) {
     var index = currentViewLength - 1;
     for (i=0; i<scrollHeights.length; i++) {
       sideNavItems[i].classList.remove('active');
     }
     sideNavItems[index].classList.add('active');
   } else {
   }
   // Fix the sideNav to the top of the page when the mainNav is scrolled past
   // Unfix otherwise
   if (windowPageYOffset > mainNavScrollHeight) {
     sideNav.classList.add('sideNavfixed');
     content.classList.add('contentScroll');
   } else {
     sideNav.classList.remove('sideNavfixed');
     content.classList.remove('contentScroll');
   }
 });

}

function buildNav() {

 var sections = document.getElementsByClassName('subsection');
 var numberOfSections = sections.length;
 var sideNav = document.getElementsByClassName('sidebar-minibox')[0];
 var titleList = [];
 var idList = [];
 var scrollHeights = [];
 // console.log(sideNav.getElementsByTagName('ul')[0]);
 // Make a list of titles and scroll heights
 for (i=0; i<numberOfSections; i++) {
   titleList.push(sections[i].getElementsByTagName('h2')[0]);
   idList.push(sections[i].id);
   scrollHeights.push(sections[i].offsetTop - 300);
 }
 console.log(scrollHeights);
 // Build the sideNav lists
 for (sec=0; sec<numberOfSections; sec++) {
   listItem = build(titleList[sec], idList[sec])
   sideNav.getElementsByTagName('ul')[0].appendChild(listItem);
 }
 scrollWatch(scrollHeights, sections);

}

function sidebarFixed() { var sidebarOffset = $("#sidebar-box").offset().top - 120; $(window).scroll(function() { var scroll = $(window).scrollTop(); //console.log(scroll); if (scroll >= sidebarOffset) { //console.log('a'); $("#sidebar-box").addClass("fixed"); } else { //console.log('a'); $("#sidebar-box").removeClass("fixed"); } }); }

sidebarFixed();

buildNav();


// 3dMOLjs initialization function

function insertStructure(container, structureUrl, settingsFunction){

 let element = $(container);
 let config = { backgroundColor: '#0d0d0d' };
 let viewer = $3Dmol.createViewer( element, config );
 let pdbUri = structureUrl;
 jQuery.ajax( pdbUri, {
   success: function(data) {
     let v = viewer;
     v.addModel( data, "pdb" );
     settingsFunction(v);
     v.zoomTo();
     v.zoom(1.2, 1000);
     v.render();
   },
   error: function(hdr, status, err) {
     console.log( "Failed to load PDB " + pdbUri + ": " + err );
   }
 });

}

var settingsList = {

 settings1: function(v){
   v.setStyle({}, {cartoon: {color: 'spectrum'}})
 },
 settings2: function(v){
   v.setStyle({}, {cartoon: {color: 'spectrum'}})
 },

}

insertStructure("#container-01", 'https://static.igem.org/mediawiki/2017/5/51/T--Toronto--2017_final_lacilov.txt', settingsList.settings1);

insertStructure("#container-02", 'https://static.igem.org/mediawiki/2017/9/99/T--Toronto--2017_2v1a.txt', settingsList.settings2);

'use strict';

var audioPlayer = document.querySelector('.audio-player'); var playPause = audioPlayer.querySelector('#playPause'); var playpauseBtn = audioPlayer.querySelector('.play-pause-btn'); var loading = audioPlayer.querySelector('.loading'); var progress = audioPlayer.querySelector('.progress'); var sliders = audioPlayer.querySelectorAll('.slider'); var volumeBtn = audioPlayer.querySelector('.volume-btn'); var volumeControls = audioPlayer.querySelector('.volume-controls'); var volumeProgress = volumeControls.querySelector('.slider .progress'); var player = audioPlayer.querySelector('audio'); var currentTime = audioPlayer.querySelector('.current-time'); var totalTime = audioPlayer.querySelector('.total-time'); var speaker = audioPlayer.querySelector('#speaker');

var draggableClasses = ['pin']; var currentlyDragged = null;

window.addEventListener('mousedown', function (event) {

 if (!isDraggable(event.target)) return false;
 currentlyDragged = event.target;
 var handleMethod = currentlyDragged.dataset.method;
 this.addEventListener('mousemove', window[handleMethod], false);
 window.addEventListener('mouseup', function () {
   currentlyDragged = false;
   window.removeEventListener('mousemove', window[handleMethod], false);
 }, false);

});

playpauseBtn.addEventListener('click', togglePlay); player.addEventListener('timeupdate', updateProgress); player.addEventListener('volumechange', updateVolume); player.addEventListener('loadedmetadata', function () {

 totalTime.textContent = formatTime(player.duration);

}); player.addEventListener('canplay', makePlay); player.addEventListener('ended', function () {

 playPause.attributes.d.value = "M18 12L0 24V0";
 player.currentTime = 0;

});

volumeBtn.addEventListener('click', function () {

 volumeBtn.classList.toggle('open');
 volumeControls.classList.toggle('hidden');

});

window.addEventListener('resize', directionAware);

sliders.forEach(function (slider) {

 var pin = slider.querySelector('.pin');
 slider.addEventListener('click', window[pin.dataset.method]);

});

directionAware();

function isDraggable(el) {

 var canDrag = false;
 var classes = Array.from(el.classList);
 draggableClasses.forEach(function (draggable) {
   if (classes.indexOf(draggable) !== -1) canDrag = true;
 });
 return canDrag;

}

function inRange(event) {

 var rangeBox = getRangeBox(event);
 var rect = rangeBox.getBoundingClientRect();
 var direction = rangeBox.dataset.direction;
 if (direction == 'horizontal') {
   var min = rangeBox.offsetLeft;
   var max = min + rangeBox.offsetWidth;
   if (event.clientX < min || event.clientX > max) return false;
 } else {
   var min = rect.top;
   var max = min + rangeBox.offsetHeight;
   if (event.clientY < min || event.clientY > max) return false;
 }
 return true;

}

function updateProgress() {

 var current = player.currentTime;
 var percent = current / player.duration * 100;
 progress.style.width = percent + '%';
 currentTime.textContent = formatTime(current);

}

function updateVolume() {

 volumeProgress.style.height = player.volume * 100 + '%';
 if (player.volume >= 0.5) {
   speaker.attributes.d.value = 'M14.667 0v2.747c3.853 1.146 6.666 4.72 6.666 8.946 0 4.227-2.813 7.787-6.666 8.934v2.76C20 22.173 24 17.4 24 11.693 24 5.987 20 1.213 14.667 0zM18 11.693c0-2.36-1.333-4.386-3.333-5.373v10.707c2-.947 3.333-2.987 3.333-5.334zm-18-4v8h5.333L12 22.36V1.027L5.333 7.693H0z';
 } else if (player.volume < 0.5 && player.volume > 0.05) {
   speaker.attributes.d.value = 'M0 7.667v8h5.333L12 22.333V1L5.333 7.667M17.333 11.373C17.333 9.013 16 6.987 14 6v10.707c2-.947 3.333-2.987 3.333-5.334z';
 } else if (player.volume <= 0.05) {
   speaker.attributes.d.value = 'M0 7.667v8h5.333L12 22.333V1L5.333 7.667';
 }

}

function getRangeBox(event) {

 var rangeBox = event.target;
 var el = currentlyDragged;
 if (event.type == 'click' && isDraggable(event.target)) {
   rangeBox = event.target.parentElement.parentElement;
 }
 if (event.type == 'mousemove') {
   rangeBox = el.parentElement.parentElement;
 }
 return rangeBox;

}

function getCoefficient(event) {

 var slider = getRangeBox(event);
 var rect = slider.getBoundingClientRect();
 var K = 0;
 if (slider.dataset.direction == 'horizontal') {
   var offsetX = event.clientX - slider.offsetLeft;
   var width = slider.clientWidth;
   K = offsetX / width;
 } else if (slider.dataset.direction == 'vertical') {
   var height = slider.clientHeight;
   var offsetY = event.clientY - rect.top;
   K = 1 - offsetY / height;
 }
 return K;

}

function rewind(event) {

 if (inRange(event)) {
   player.currentTime = player.duration * getCoefficient(event);
 }

}

function changeVolume(event) {

 if (inRange(event)) {
   player.volume = getCoefficient(event);
 }

}

function formatTime(time) {

 var min = Math.floor(time / 60);
 var sec = Math.floor(time % 60);
 return min + ':' + (sec < 10 ? '0' + sec : sec);

}

function togglePlay() {

 if (player.paused) {
   playPause.attributes.d.value = "M0 0h6v24H0zM12 0h6v24h-6z";
   player.play();
 } else {
   playPause.attributes.d.value = "M18 12L0 24V0";
   player.pause();
 }

}

function makePlay() {

 playpauseBtn.style.display = 'block';
 loading.style.display = 'none';

}

function directionAware() {

 if (window.innerHeight < 250) {
   volumeControls.style.bottom = '-54px';
   volumeControls.style.left = '54px';
 } else if (audioPlayer.offsetTop < 154) {
   volumeControls.style.bottom = '-164px';
   volumeControls.style.left = '-3px';
 } else {
   volumeControls.style.bottom = '52px';
   volumeControls.style.left = '-3px';
 }

}