Difference between revisions of "Team:UCSC/new-testing"

Line 1: Line 1:
 
{{:Team:UCSC/Reset-Styles}}
 
{{:Team:UCSC/Reset-Styles}}
 
{{:Team:UCSC/new-testing.css}}
 
{{:Team:UCSC/new-testing.css}}
 +
  
 
<html lang="en">
 
<html lang="en">
Line 157: Line 158:
 
   </section>
 
   </section>
 
</body>
 
</body>
 +
<script>
 +
// Utility function
 +
function Util () {};
 +
 +
/*
 +
class manipulation functions
 +
*/
 +
Util.hasClass = function(el, className) {
 +
if (el.classList) return el.classList.contains(className);
 +
else return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
 +
};
 +
 +
Util.addClass = function(el, className) {
 +
var classList = className.split(' ');
 +
if (el.classList) el.classList.add(classList[0]);
 +
else if (!Util.hasClass(el, classList[0])) el.className += " " + classList[0];
 +
if (classList.length > 1) Util.addClass(el, classList.slice(1).join(' '));
 +
};
 +
 +
Util.removeClass = function(el, className) {
 +
var classList = className.split(' ');
 +
if (el.classList) el.classList.remove(classList[0]);
 +
else if(Util.hasClass(el, classList[0])) {
 +
var reg = new RegExp('(\\s|^)' + classList[0] + '(\\s|$)');
 +
el.className=el.className.replace(reg, ' ');
 +
}
 +
if (classList.length > 1) Util.removeClass(el, classList.slice(1).join(' '));
 +
};
 +
 +
Util.toggleClass = function(el, className, bool) {
 +
if(bool) Util.addClass(el, className);
 +
else Util.removeClass(el, className);
 +
};
 +
 +
Util.setAttributes = function(el, attrs) {
 +
  for(var key in attrs) {
 +
    el.setAttribute(key, attrs[key]);
 +
  }
 +
};
 +
 +
/*
 +
  DOM manipulation
 +
*/
 +
Util.getChildrenByClassName = function(el, className) {
 +
  var children = el.children,
 +
    childrenByClass = [];
 +
  for (var i = 0; i < el.children.length; i++) {
 +
    if (Util.hasClass(el.children[i], className)) childrenByClass.push(el.children[i]);
 +
  }
 +
  return childrenByClass;
 +
};
 +
 +
/*
 +
Animate height of an element
 +
*/
 +
Util.setHeight = function(start, to, element, duration, cb) {
 +
var change = to - start,
 +
    currentTime = null;
 +
 +
  var animateHeight = function(timestamp){
 +
    if (!currentTime) currentTime = timestamp;
 +
    var progress = timestamp - currentTime;
 +
    var val = parseInt((progress/duration)*change + start);
 +
    element.setAttribute("style", "height:"+val+"px;");
 +
    if(progress < duration) {
 +
        window.requestAnimationFrame(animateHeight);
 +
    } else {
 +
    cb();
 +
    }
 +
  };
 +
 +
  //set the height of the element before starting animation -> fix bug on Safari
 +
  element.setAttribute("style", "height:"+start+"px;");
 +
  window.requestAnimationFrame(animateHeight);
 +
};
 +
 +
/*
 +
Smooth Scroll
 +
*/
 +
 +
Util.scrollTo = function(final, duration, cb) {
 +
  var start = window.scrollY || document.documentElement.scrollTop,
 +
      currentTime = null;
 +
 +
  var animateScroll = function(timestamp){
 +
  if (!currentTime) currentTime = timestamp;
 +
    var progress = timestamp - currentTime;
 +
    if(progress > duration) progress = duration;
 +
    var val = Math.easeInOutQuad(progress, start, final-start, duration);
 +
    window.scrollTo(0, val);
 +
    if(progress < duration) {
 +
        window.requestAnimationFrame(animateScroll);
 +
    } else {
 +
      cb && cb();
 +
    }
 +
  };
 +
 +
  window.requestAnimationFrame(animateScroll);
 +
};
 +
 +
/*
 +
  Focus utility classes
 +
*/
 +
 +
//Move focus to an element
 +
Util.moveFocus = function (element) {
 +
  if( !element ) element = document.getElementsByTagName("body")[0];
 +
  element.focus();
 +
  if (document.activeElement !== element) {
 +
    element.setAttribute('tabindex','-1');
 +
    element.focus();
 +
  }
 +
};
 +
 +
/*
 +
  Misc
 +
*/
 +
 +
Util.getIndexInArray = function(array, el) {
 +
  return Array.prototype.indexOf.call(array, el);
 +
};
 +
 +
Util.cssSupports = function(property, value) {
 +
  if('CSS' in window) {
 +
    return CSS.supports(property, value);
 +
  } else {
 +
    var jsProperty = property.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase();});
 +
    return jsProperty in document.body.style;
 +
  }
 +
};
 +
 +
/*
 +
Polyfills
 +
*/
 +
//Closest() method
 +
if (!Element.prototype.matches) {
 +
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
 +
}
 +
 +
if (!Element.prototype.closest) {
 +
Element.prototype.closest = function(s) {
 +
var el = this;
 +
if (!document.documentElement.contains(el)) return null;
 +
do {
 +
if (el.matches(s)) return el;
 +
el = el.parentElement || el.parentNode;
 +
} while (el !== null && el.nodeType === 1);
 +
return null;
 +
};
 +
}
 +
 +
//Custom Event() constructor
 +
if ( typeof window.CustomEvent !== "function" ) {
 +
 +
  function CustomEvent ( event, params ) {
 +
    params = params || { bubbles: false, cancelable: false, detail: undefined };
 +
    var evt = document.createEvent( 'CustomEvent' );
 +
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
 +
    return evt;
 +
  }
 +
 +
  CustomEvent.prototype = window.Event.prototype;
 +
 +
  window.CustomEvent = CustomEvent;
 +
}
 +
 +
/*
 +
Animation curves
 +
*/
 +
Math.easeInOutQuad = function (t, b, c, d) {
 +
t /= d/2;
 +
if (t < 1) return c/2*t*t + b;
 +
t--;
 +
return -c/2 * (t*(t-2) - 1) + b;
 +
};
 +
 +
 
 +
</script>
 +
 +
<script>
 +
  (function() {
 +
// Swipe Content Plugin - by CodyHouse.co
 +
// https://codyhouse.co/ds/components/info/swipe-content
 +
var SwipeContent = function(element) {
 +
this.element = element;
 +
this.delta = [false, false];
 +
this.dragging = false;
 +
this.intervalId = false;
 +
initSwipeContent(this);
 +
};
 +
 +
function initSwipeContent(content) {
 +
content.element.addEventListener('mousedown', handleEvent.bind(content));
 +
content.element.addEventListener('touchstart', handleEvent.bind(content));
 +
};
 +
 +
function initDragging(content) {
 +
//add event listeners
 +
content.element.addEventListener('mousemove', handleEvent.bind(content));
 +
content.element.addEventListener('touchmove', handleEvent.bind(content));
 +
content.element.addEventListener('mouseup', handleEvent.bind(content));
 +
content.element.addEventListener('mouseleave', handleEvent.bind(content));
 +
content.element.addEventListener('touchend', handleEvent.bind(content));
 +
};
 +
 +
function cancelDragging(content) {
 +
//remove event listeners
 +
if(content.intervalId) {
 +
(!window.requestAnimationFrame) ? clearInterval(content.intervalId) : window.cancelAnimationFrame(content.intervalId);
 +
content.intervalId = false;
 +
}
 +
content.element.removeEventListener('mousemove', handleEvent.bind(content));
 +
content.element.removeEventListener('touchmove', handleEvent.bind(content));
 +
content.element.removeEventListener('mouseup', handleEvent.bind(content));
 +
content.element.removeEventListener('mouseleave', handleEvent.bind(content));
 +
content.element.removeEventListener('touchend', handleEvent.bind(content));
 +
};
 +
 +
function handleEvent(event) {
 +
switch(event.type) {
 +
case 'mousedown':
 +
case 'touchstart':
 +
startDrag(this, event);
 +
break;
 +
case 'mousemove':
 +
case 'touchmove':
 +
drag(this, event);
 +
break;
 +
case 'mouseup':
 +
case 'mouseleave':
 +
case 'touchend':
 +
endDrag(this, event);
 +
break;
 +
}
 +
};
 +
 +
function startDrag(content, event) {
 +
content.dragging = true;
 +
// listen to drag movements
 +
initDragging(content);
 +
content.delta = [parseInt(unify(event).clientX), parseInt(unify(event).clientY)];
 +
// emit drag start event
 +
emitSwipeEvents(content, 'dragStart', content.delta);
 +
};
 +
 +
function endDrag(content, event) {
 +
cancelDragging(content);
 +
// credits: https://css-tricks.com/simple-swipe-with-vanilla-javascript/
 +
var dx = parseInt(unify(event).clientX),
 +
    dy = parseInt(unify(event).clientY);
 +
 
 +
  // check if there was a left/right swipe
 +
if(content.delta && (content.delta[0] || content.delta[0] === 0)) {
 +
    var s = Math.sign(dx - content.delta[0]);
 +
 +
if(Math.abs(dx - content.delta[0]) > 30) {
 +
(s < 0) ? emitSwipeEvents(content, 'swipeLeft', [dx, dy]) : emitSwipeEvents(content, 'swipeRight', [dx, dy]);
 +
}
 +
   
 +
    content.delta[0] = false;
 +
  }
 +
// check if there was a top/bottom swipe
 +
  if(content.delta && (content.delta[1] || content.delta[1] === 0)) {
 +
  var y = Math.sign(dy - content.delta[1]);
 +
 +
  if(Math.abs(dy - content.delta[1]) > 30) {
 +
    (y < 0) ? emitSwipeEvents(content, 'swipeUp', [dx, dy]) : emitSwipeEvents(content, 'swipeDown', [dx, dy]);
 +
    }
 +
 +
    content.delta[1] = false;
 +
  }
 +
// emit drag end event
 +
  emitSwipeEvents(content, 'dragEnd', [dx, dy]);
 +
  content.dragging = false;
 +
};
 +
 +
function drag(content, event) {
 +
if(!content.dragging) return;
 +
// emit dragging event with coordinates
 +
(!window.requestAnimationFrame)
 +
? content.intervalId = setTimeout(function(){emitDrag.bind(content, event);}, 250)
 +
: content.intervalId = window.requestAnimationFrame(emitDrag.bind(content, event));
 +
};
 +
 +
function emitDrag(event) {
 +
emitSwipeEvents(this, 'dragging', [parseInt(unify(event).clientX), parseInt(unify(event).clientY)]);
 +
};
 +
 +
function unify(event) {
 +
// unify mouse and touch events
 +
return event.changedTouches ? event.changedTouches[0] : event;
 +
};
 +
 +
function emitSwipeEvents(content, eventName, detail) {
 +
// emit event with coordinates
 +
var event = new CustomEvent(eventName, {detail: {x: detail[0], y: detail[1]}});
 +
content.element.dispatchEvent(event);
 +
};
 +
 +
window.SwipeContent = SwipeContent;
 +
 +
//initialize the SwipeContent objects
 +
var swipe = document.getElementsByClassName('js-swipe-content');
 +
if( swipe.length > 0 ) {
 +
for( var i = 0; i < swipe.length; i++) {
 +
(function(i){new SwipeContent(swipe[i]);})(i);
 +
}
 +
}
 +
}());
 +
</script>
 +
 
<script>
 
<script>
 
   (function() {
 
   (function() {
Line 164: Line 476:
 
this.datesContainer = this.element.getElementsByClassName('cd-h-timeline__dates')[0];
 
this.datesContainer = this.element.getElementsByClassName('cd-h-timeline__dates')[0];
 
this.line = this.datesContainer.getElementsByClassName('cd-h-timeline__line')[0]; // grey line in the top timeline section
 
this.line = this.datesContainer.getElementsByClassName('cd-h-timeline__line')[0]; // grey line in the top timeline section
this.fillingLine = this.datesContainer.getElementsByClassName('cd-h-timeline__filling-line')[0]; // green filling line in the top timeline section
+
this.fillingLine = this.datesContainer.getElementsByClassName('cd-h-timeline__filling-line')[0]; // green filling line in the top timeline section
 
this.date = this.line.getElementsByClassName('cd-h-timeline__date');
 
this.date = this.line.getElementsByClassName('cd-h-timeline__date');
 
this.selectedDate = this.line.getElementsByClassName('cd-h-timeline__date--selected')[0];
 
this.selectedDate = this.line.getElementsByClassName('cd-h-timeline__date--selected')[0];
Line 172: Line 484:
 
this.contentWrapper = this.element.getElementsByClassName('cd-h-timeline__events')[0];
 
this.contentWrapper = this.element.getElementsByClassName('cd-h-timeline__events')[0];
 
this.content = this.contentWrapper.getElementsByClassName('cd-h-timeline__event');
 
this.content = this.contentWrapper.getElementsByClassName('cd-h-timeline__event');
 
+
 
this.eventsMinDistance = 60; // min distance between two consecutive events (in px)
 
this.eventsMinDistance = 60; // min distance between two consecutive events (in px)
 
this.eventsMaxDistance = 200; // max distance between two consecutive events (in px)
 
this.eventsMaxDistance = 200; // max distance between two consecutive events (in px)
 
this.translate = 0; // this will be used to store the translate value of this.line
 
this.translate = 0; // this will be used to store the translate value of this.line
 
this.lineLength = 0; //total length of this.line
 
this.lineLength = 0; //total length of this.line
 
+
 
// store index of selected and previous selected dates
 
// store index of selected and previous selected dates
 
this.oldDateIndex = Util.getIndexInArray(this.date, this.selectedDate);
 
this.oldDateIndex = Util.getIndexInArray(this.date, this.selectedDate);
Line 189: Line 501:
 
   // set dates left position
 
   // set dates left position
 
   var left = 0;
 
   var left = 0;
for (var i = 0; i < timeline.dateValues.length; i++) {
+
for (var i = 0; i < timeline.dateValues.length; i++) {  
 
var j = (i == 0) ? 0 : i - 1;
 
var j = (i == 0) ? 0 : i - 1;
 
    var distance = daydiff(timeline.dateValues[j], timeline.dateValues[i]),
 
    var distance = daydiff(timeline.dateValues[j], timeline.dateValues[i]),
 
    distanceNorm = (Math.round(distance/timeline.minLapse) + 2)*timeline.eventsMinDistance;
 
    distanceNorm = (Math.round(distance/timeline.minLapse) + 2)*timeline.eventsMinDistance;
 
+
 
    if(distanceNorm < timeline.eventsMinDistance) {
 
    if(distanceNorm < timeline.eventsMinDistance) {
 
    distanceNorm = timeline.eventsMinDistance;
 
    distanceNorm = timeline.eventsMinDistance;
Line 202: Line 514:
 
    timeline.date[i].setAttribute('style', 'left:' + left+'px');
 
    timeline.date[i].setAttribute('style', 'left:' + left+'px');
 
}
 
}
 
+
 
// set line/filling line dimensions
 
// set line/filling line dimensions
 
     timeline.line.style.width = (left + timeline.eventsMinDistance)+'px';
 
     timeline.line.style.width = (left + timeline.eventsMinDistance)+'px';
Line 252: Line 564:
 
left = dateStyle.getPropertyValue("left"),
 
left = dateStyle.getPropertyValue("left"),
 
width = dateStyle.getPropertyValue("width");
 
width = dateStyle.getPropertyValue("width");
 
+
 
left = Number(left.replace('px', '')) + Number(width.replace('px', ''))/2;
 
left = Number(left.replace('px', '')) + Number(width.replace('px', ''))/2;
 
timeline.fillingLine.style.transform = 'scaleX('+(left/timeline.lineLength)+')';
 
timeline.fillingLine.style.transform = 'scaleX('+(left/timeline.lineLength)+')';
Line 320: Line 632:
 
resetTimelinePosition(timeline, direction);
 
resetTimelinePosition(timeline, direction);
 
};
 
};
 
+
 
function resetTimelinePosition(timeline, direction) { //translate timeline according to new selected event position
 
function resetTimelinePosition(timeline, direction) { //translate timeline according to new selected event position
 
var eventStyle = window.getComputedStyle(timeline.selectedDate, null),
 
var eventStyle = window.getComputedStyle(timeline.selectedDate, null),
Line 337: Line 649:
 
var singleDate = timeline.date[i].getAttribute('data-date'),
 
var singleDate = timeline.date[i].getAttribute('data-date'),
 
dateComp = singleDate.split('T');
 
dateComp = singleDate.split('T');
 
+
 
if( dateComp.length > 1 ) { //both DD/MM/YEAR and time are provided
 
if( dateComp.length > 1 ) { //both DD/MM/YEAR and time are provided
 
var dayComp = dateComp[0].split('/'),
 
var dayComp = dateComp[0].split('/'),
Line 356: Line 668:
 
   function calcMinLapse(timeline) { // determine the minimum distance among events
 
   function calcMinLapse(timeline) { // determine the minimum distance among events
 
var dateDistances = [];
 
var dateDistances = [];
for(var i = 1; i < timeline.dateValues.length; i++) {
+
for(var i = 1; i < timeline.dateValues.length; i++) {  
 
    var distance = daydiff(timeline.dateValues[i-1], timeline.dateValues[i]);
 
    var distance = daydiff(timeline.dateValues[i-1], timeline.dateValues[i]);
 
    if(distance > 0) dateDistances.push(distance);
 
    if(distance > 0) dateDistances.push(distance);
Line 374: Line 686:
 
   if(horizontalTimeline.length > 0) {
 
   if(horizontalTimeline.length > 0) {
 
for(var i = 0; i < horizontalTimeline.length; i++) {
 
for(var i = 0; i < horizontalTimeline.length; i++) {
horizontalTimelineTimelineArray.push(new HorizontalTimeline(horizontalTimeline[i]));
+
horizontalTimelineTimelineArray.push(new HorizontalTimeline(horizontalTimeline[i]));  
 
}
 
}
 
// navigate the timeline when inside the viewport using the keyboard
 
// navigate the timeline when inside the viewport using the keyboard
Line 417: Line 729:
 
}());
 
}());
 
</script>
 
</script>
(function() {
 
// Swipe Content Plugin - by CodyHouse.co
 
// https://codyhouse.co/ds/components/info/swipe-content
 
var SwipeContent = function(element) {
 
this.element = element;
 
this.delta = [false, false];
 
this.dragging = false;
 
this.intervalId = false;
 
initSwipeContent(this);
 
};
 
  
function initSwipeContent(content) {
+
  <!--script src="assets/js/util.js"></script>
content.element.addEventListener('mousedown', handleEvent.bind(content));
+
  <script src="assets/js/swipe-content.js"></script>
content.element.addEventListener('touchstart', handleEvent.bind(content));
+
  <script src="assets/js/main.js"></script-->
};
+
  
function initDragging(content) {
 
//add event listeners
 
content.element.addEventListener('mousemove', handleEvent.bind(content));
 
content.element.addEventListener('touchmove', handleEvent.bind(content));
 
content.element.addEventListener('mouseup', handleEvent.bind(content));
 
content.element.addEventListener('mouseleave', handleEvent.bind(content));
 
content.element.addEventListener('touchend', handleEvent.bind(content));
 
};
 
  
function cancelDragging(content) {
 
//remove event listeners
 
if(content.intervalId) {
 
(!window.requestAnimationFrame) ? clearInterval(content.intervalId) : window.cancelAnimationFrame(content.intervalId);
 
content.intervalId = false;
 
}
 
content.element.removeEventListener('mousemove', handleEvent.bind(content));
 
content.element.removeEventListener('touchmove', handleEvent.bind(content));
 
content.element.removeEventListener('mouseup', handleEvent.bind(content));
 
content.element.removeEventListener('mouseleave', handleEvent.bind(content));
 
content.element.removeEventListener('touchend', handleEvent.bind(content));
 
};
 
 
function handleEvent(event) {
 
switch(event.type) {
 
case 'mousedown':
 
case 'touchstart':
 
startDrag(this, event);
 
break;
 
case 'mousemove':
 
case 'touchmove':
 
drag(this, event);
 
break;
 
case 'mouseup':
 
case 'mouseleave':
 
case 'touchend':
 
endDrag(this, event);
 
break;
 
}
 
};
 
 
function startDrag(content, event) {
 
content.dragging = true;
 
// listen to drag movements
 
initDragging(content);
 
content.delta = [parseInt(unify(event).clientX), parseInt(unify(event).clientY)];
 
// emit drag start event
 
emitSwipeEvents(content, 'dragStart', content.delta);
 
};
 
 
function endDrag(content, event) {
 
cancelDragging(content);
 
// credits: https://css-tricks.com/simple-swipe-with-vanilla-javascript/
 
var dx = parseInt(unify(event).clientX),
 
    dy = parseInt(unify(event).clientY);
 
 
  // check if there was a left/right swipe
 
if(content.delta && (content.delta[0] || content.delta[0] === 0)) {
 
    var s = Math.sign(dx - content.delta[0]);
 
 
if(Math.abs(dx - content.delta[0]) > 30) {
 
(s < 0) ? emitSwipeEvents(content, 'swipeLeft', [dx, dy]) : emitSwipeEvents(content, 'swipeRight', [dx, dy]);
 
}
 
 
    content.delta[0] = false;
 
  }
 
// check if there was a top/bottom swipe
 
  if(content.delta && (content.delta[1] || content.delta[1] === 0)) {
 
  var y = Math.sign(dy - content.delta[1]);
 
 
  if(Math.abs(dy - content.delta[1]) > 30) {
 
    (y < 0) ? emitSwipeEvents(content, 'swipeUp', [dx, dy]) : emitSwipeEvents(content, 'swipeDown', [dx, dy]);
 
    }
 
 
    content.delta[1] = false;
 
  }
 
// emit drag end event
 
  emitSwipeEvents(content, 'dragEnd', [dx, dy]);
 
  content.dragging = false;
 
};
 
 
function drag(content, event) {
 
if(!content.dragging) return;
 
// emit dragging event with coordinates
 
(!window.requestAnimationFrame)
 
? content.intervalId = setTimeout(function(){emitDrag.bind(content, event);}, 250)
 
: content.intervalId = window.requestAnimationFrame(emitDrag.bind(content, event));
 
};
 
 
function emitDrag(event) {
 
emitSwipeEvents(this, 'dragging', [parseInt(unify(event).clientX), parseInt(unify(event).clientY)]);
 
};
 
 
function unify(event) {
 
// unify mouse and touch events
 
return event.changedTouches ? event.changedTouches[0] : event;
 
};
 
 
function emitSwipeEvents(content, eventName, detail) {
 
// emit event with coordinates
 
var event = new CustomEvent(eventName, {detail: {x: detail[0], y: detail[1]}});
 
content.element.dispatchEvent(event);
 
};
 
 
window.SwipeContent = SwipeContent;
 
 
//initialize the SwipeContent objects
 
var swipe = document.getElementsByClassName('js-swipe-content');
 
if( swipe.length > 0 ) {
 
for( var i = 0; i < swipe.length; i++) {
 
(function(i){new SwipeContent(swipe[i]);})(i);
 
}
 
}
 
}());
 
<script>
 
</script>
 
 
<script>
 
  // Utility function
 
function Util () {};
 
 
/*
 
class manipulation functions
 
*/
 
Util.hasClass = function(el, className) {
 
if (el.classList) return el.classList.contains(className);
 
else return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
 
};
 
 
Util.addClass = function(el, className) {
 
var classList = className.split(' ');
 
if (el.classList) el.classList.add(classList[0]);
 
else if (!Util.hasClass(el, classList[0])) el.className += " " + classList[0];
 
if (classList.length > 1) Util.addClass(el, classList.slice(1).join(' '));
 
};
 
 
Util.removeClass = function(el, className) {
 
var classList = className.split(' ');
 
if (el.classList) el.classList.remove(classList[0]);
 
else if(Util.hasClass(el, classList[0])) {
 
var reg = new RegExp('(\\s|^)' + classList[0] + '(\\s|$)');
 
el.className=el.className.replace(reg, ' ');
 
}
 
if (classList.length > 1) Util.removeClass(el, classList.slice(1).join(' '));
 
};
 
 
Util.toggleClass = function(el, className, bool) {
 
if(bool) Util.addClass(el, className);
 
else Util.removeClass(el, className);
 
};
 
 
Util.setAttributes = function(el, attrs) {
 
  for(var key in attrs) {
 
    el.setAttribute(key, attrs[key]);
 
  }
 
};
 
 
/*
 
  DOM manipulation
 
*/
 
Util.getChildrenByClassName = function(el, className) {
 
  var children = el.children,
 
    childrenByClass = [];
 
  for (var i = 0; i < el.children.length; i++) {
 
    if (Util.hasClass(el.children[i], className)) childrenByClass.push(el.children[i]);
 
  }
 
  return childrenByClass;
 
};
 
 
/*
 
Animate height of an element
 
*/
 
Util.setHeight = function(start, to, element, duration, cb) {
 
var change = to - start,
 
    currentTime = null;
 
 
  var animateHeight = function(timestamp){
 
    if (!currentTime) currentTime = timestamp;
 
    var progress = timestamp - currentTime;
 
    var val = parseInt((progress/duration)*change + start);
 
    element.setAttribute("style", "height:"+val+"px;");
 
    if(progress < duration) {
 
        window.requestAnimationFrame(animateHeight);
 
    } else {
 
    cb();
 
    }
 
  };
 
 
  //set the height of the element before starting animation -> fix bug on Safari
 
  element.setAttribute("style", "height:"+start+"px;");
 
  window.requestAnimationFrame(animateHeight);
 
};
 
 
/*
 
Smooth Scroll
 
*/
 
 
Util.scrollTo = function(final, duration, cb) {
 
  var start = window.scrollY || document.documentElement.scrollTop,
 
      currentTime = null;
 
 
  var animateScroll = function(timestamp){
 
  if (!currentTime) currentTime = timestamp;
 
    var progress = timestamp - currentTime;
 
    if(progress > duration) progress = duration;
 
    var val = Math.easeInOutQuad(progress, start, final-start, duration);
 
    window.scrollTo(0, val);
 
    if(progress < duration) {
 
        window.requestAnimationFrame(animateScroll);
 
    } else {
 
      cb && cb();
 
    }
 
  };
 
 
  window.requestAnimationFrame(animateScroll);
 
};
 
 
/*
 
  Focus utility classes
 
*/
 
 
//Move focus to an element
 
Util.moveFocus = function (element) {
 
  if( !element ) element = document.getElementsByTagName("body")[0];
 
  element.focus();
 
  if (document.activeElement !== element) {
 
    element.setAttribute('tabindex','-1');
 
    element.focus();
 
  }
 
};
 
 
/*
 
  Misc
 
*/
 
 
Util.getIndexInArray = function(array, el) {
 
  return Array.prototype.indexOf.call(array, el);
 
};
 
 
Util.cssSupports = function(property, value) {
 
  if('CSS' in window) {
 
    return CSS.supports(property, value);
 
  } else {
 
    var jsProperty = property.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase();});
 
    return jsProperty in document.body.style;
 
  }
 
};
 
 
/*
 
Polyfills
 
*/
 
//Closest() method
 
if (!Element.prototype.matches) {
 
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
 
}
 
 
if (!Element.prototype.closest) {
 
Element.prototype.closest = function(s) {
 
var el = this;
 
if (!document.documentElement.contains(el)) return null;
 
do {
 
if (el.matches(s)) return el;
 
el = el.parentElement || el.parentNode;
 
} while (el !== null && el.nodeType === 1);
 
return null;
 
};
 
}
 
 
//Custom Event() constructor
 
if ( typeof window.CustomEvent !== "function" ) {
 
 
  function CustomEvent ( event, params ) {
 
    params = params || { bubbles: false, cancelable: false, detail: undefined };
 
    var evt = document.createEvent( 'CustomEvent' );
 
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
 
    return evt;
 
  }
 
 
  CustomEvent.prototype = window.Event.prototype;
 
 
  window.CustomEvent = CustomEvent;
 
}
 
 
/*
 
Animation curves
 
*/
 
Math.easeInOutQuad = function (t, b, c, d) {
 
t /= d/2;
 
if (t < 1) return c/2*t*t + b;
 
t--;
 
return -c/2 * (t*(t-2) - 1) + b;
 
};
 
</script>
 
 
</html>
 
</html>

Revision as of 04:17, 14 October 2019


👈 Article & Download

  1. Horizontal Timeline

    January 16th, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  2. Event title here

    February 28th, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  3. Event title here

    March 20th, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  4. Event title here

    May 20th, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  5. Event title here

    July 9th, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  6. Event title here

    August 30th, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  7. Event title here

    September 15th, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  8. Event title here

    November 1st, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  9. Event title here

    December 10th, 2014

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  10. Event title here

    January 29th, 2015

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.

  11. Event title here

    March 3rd, 2015

    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Illum praesentium officia, fugit recusandae ipsa, quia velit nulla adipisci? Consequuntur aspernatur at, eaque hic repellendus sit dicta consequatur quae, ut harum ipsam molestias maxime non nisi reiciendis eligendi! Doloremque quia pariatur harum ea amet quibusdam quisquam, quae, temporibus dolores porro doloribus.