1'use strict'; 2 3class TxtType { 4 constructor(el, toRotate, period) { 5 this.toRotate = toRotate; 6 this.el = el; 7 this.loopNum = 0; 8 this.period = parseInt(period, 10) || 2000; 9 this.txt = ''; 10 this.isDeleting = false; 11 this.tick(); 12 } 13 14 tick() { 15 const i = this.loopNum % this.toRotate.length; 16 const fullTxt = this.toRotate[i]; 17 18 if (this.isDeleting) { 19 this.txt = fullTxt.substring(0, this.txt.length - 1); 20 } else { 21 this.txt = fullTxt.substring(0, this.txt.length + 1); 22 } 23 24 this.el.innerHTML = `<span class="wrap">${this.txt}</span>`; 25 26 let delta = 150 - Math.random() * 100; 27 28 if (this.isDeleting) { 29 delta /= 2; 30 } 31 32 if (!this.isDeleting && this.txt === fullTxt) { 33 delta = this.period; 34 this.isDeleting = true; 35 } else if (this.isDeleting && this.txt === '') { 36 this.isDeleting = false; 37 this.loopNum++; 38 delta = 500; 39 } 40 41 setTimeout(() => this.tick(), delta); 42 } 43} 44 45window.addEventListener('load', () => { 46 const elements = document.querySelectorAll('.typewriter'); 47 elements.forEach((element) => { 48 const toRotate = element.getAttribute('data-type'); 49 const period = element.getAttribute('data-period'); 50 if (toRotate) { 51 new TxtType(element, JSON.parse(toRotate), period); 52 } 53 }); 54 55 // INJECT CSS 56 const css = document.createElement('style'); 57 css.type = 'text/css'; 58 css.innerHTML = '.typewriter > .wrap { border-right: 0.1em solid #1688f0}'; 59 document.body.appendChild(css); 60}); 61 62(function ($) { 63 $('html').removeClass('no-js'); 64 65 // Animate to section when nav is clicked 66 $('header a').on('click', function (e) { 67 if ($(this).hasClass('no-scroll')) return; 68 69 e.preventDefault(); 70 const heading = $(this).attr('href'); 71 const scrollDistance = $(heading).offset().top; 72 73 window.scrollTo({top: scrollDistance, behavior: 'smooth'}); 74 75 // Hide the menu once clicked if mobile 76 if ($('header').hasClass('active')) { 77 $('header, body').removeClass('active'); 78 } 79 }); 80 81 // Scroll to top 82 $('#to-top').on('click', () => { 83 $('html, body').animate({scrollTop: 0}, 500); 84 }); 85 86 // Scroll to first element 87 $('#lead-down span').on('click', () => { 88 const scrollDistance = $('#lead').next().offset().top; 89 $('html, body').animate({scrollTop: `${scrollDistance}px`}, 500); 90 }); 91 92 // Create timeline 93 $('#experience-timeline').each(function () { 94 const $this = $(this); 95 const $userContent = $this.children('div'); 96 97 // Create each timeline block 98 $userContent.each(function () { 99 $(this) 100 .addClass('vtimeline-content') 101 .wrap( 102 '<div class="vtimeline-point"><div class="vtimeline-block"></div></div>' 103 ); 104 }); 105 106 // Add icons to each block 107 $this.find('.vtimeline-point').each(function () { 108 $(this).prepend( 109 '<div class="vtimeline-icon"><i class="fa fa-map-marker"></i></div>' 110 ); 111 }); 112 113 // Add dates to the timeline if exists 114 $this.find('.vtimeline-content').each(function () { 115 const date = $(this).data('date'); 116 if (date) { 117 $(this) 118 .parent() 119 .prepend(`<span class="vtimeline-date">${date}</span>`); 120 } 121 }); 122 }); 123 124 $('#mobile-menu-open').on('click', () => { 125 $('header, body').addClass('active'); 126 }); 127 128 $('#mobile-menu-close').on('click', () => { 129 $('header, body').removeClass('active'); 130 }); 131})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.