|
| 1 | +/*==================== MENU SHOW Y HIDDEN ====================*/ |
| 2 | +const navMenu = document.getElementById("nav-menu"), |
| 3 | + navToggle = document.getElementById("nav-toggle"), |
| 4 | + navClose = document.getElementById("nav-close"); |
| 5 | + |
| 6 | +/*===== MENU SHOW =====*/ |
| 7 | +/* Validate if constant exists */ |
| 8 | +if (navToggle) { |
| 9 | + navToggle.addEventListener("click", () => { |
| 10 | + navMenu.classList.add("show-menu"); |
| 11 | + }); |
| 12 | +} |
| 13 | + |
| 14 | +/*===== MENU HIDDEN =====*/ |
| 15 | +/* Validate if constant exists */ |
| 16 | +if (navClose) { |
| 17 | + navClose.addEventListener("click", () => { |
| 18 | + navMenu.classList.remove("show-menu"); |
| 19 | + }); |
| 20 | +} |
| 21 | + |
| 22 | +/*==================== REMOVE MENU MOBILE ====================*/ |
| 23 | +const navLink = document.querySelectorAll(".nav__link"); |
| 24 | +navLink.forEach((a) => |
| 25 | + a.addEventListener("click", () => { |
| 26 | + const navMenu = document.getElementById("nav-menu"); |
| 27 | + // when user click on each nav__link , remove the show-menu class |
| 28 | + navMenu.classList.remove("show-menu"); |
| 29 | + }) |
| 30 | +); |
| 31 | +/*==================== ACCORDION SKILLS ====================*/ |
| 32 | +const skillsContent = document.getElementsByClassName("skills__content"), |
| 33 | + skillsHeader = document.querySelectorAll(".skills__header"); |
| 34 | + |
| 35 | +skillsHeader.forEach((element) => { |
| 36 | + element.addEventListener("click", function toggleSkills() { |
| 37 | + if (this.parentNode.className === "skills__content skills__open") { |
| 38 | + this.parentNode.className = "skills__content skills__close"; |
| 39 | + } else { |
| 40 | + this.parentNode.className = "skills__content skills__open"; |
| 41 | + } |
| 42 | + }); |
| 43 | +}); |
| 44 | +/*==================== QUALIFICATION TABS ====================*/ |
| 45 | +const educationBtn = document.getElementById("education-btn"), |
| 46 | + workBtn = document.getElementById("work-btn"), |
| 47 | + educationDiv = document.getElementById("education"), |
| 48 | + workDiv = document.getElementById("work"); |
| 49 | + |
| 50 | +educationBtn.addEventListener("click", function showEducations() { |
| 51 | + educationBtn.style.color = "#6e57e0"; |
| 52 | + workBtn.style.color = "#6d6a7c"; |
| 53 | + educationDiv.className = "ualification__content qualification__active"; |
| 54 | + workDiv.className = "qualification__content"; |
| 55 | +}); |
| 56 | + |
| 57 | +workBtn.addEventListener("click", function showWorks() { |
| 58 | + workBtn.style.color = "#6e57e0"; |
| 59 | + educationBtn.style.color = "#6d6a7c"; |
| 60 | + workDiv.className = "ualification__content qualification__active"; |
| 61 | + educationDiv.className = "qualification__content"; |
| 62 | +}); |
| 63 | + |
| 64 | +/*==================== SERVICES MODAL ====================*/ |
| 65 | +const modalViews = document.querySelectorAll(".services__modal"), |
| 66 | + modalBtns = document.querySelectorAll(".services__button"), |
| 67 | + modalCloses = document.querySelectorAll(".services__modal-close"); |
| 68 | + |
| 69 | +let modal = function (modalClick) { |
| 70 | + modalViews[modalClick].classList.add("active-modal"); |
| 71 | +}; |
| 72 | + |
| 73 | +modalBtns.forEach((modalBtn, i) => { |
| 74 | + modalBtn.addEventListener("click", () => { |
| 75 | + modal(i); |
| 76 | + }); |
| 77 | +}); |
| 78 | + |
| 79 | +modalCloses.forEach((modalClose) => { |
| 80 | + modalClose.addEventListener("click", () => { |
| 81 | + modalViews.forEach((modalView) => { |
| 82 | + modalView.classList.remove("active-modal"); |
| 83 | + }); |
| 84 | + }); |
| 85 | +}); |
| 86 | + |
| 87 | +/*==================== PORTFOLIO SWIPER ====================*/ |
| 88 | +var swiper = new Swiper(".portfolio__container", { |
| 89 | + cssMode: true, |
| 90 | + loop: true, |
| 91 | + navigation: { |
| 92 | + nextEl: ".swiper-button-next", |
| 93 | + prevEl: ".swiper-button-prev", |
| 94 | + }, |
| 95 | + pagination: { |
| 96 | + el: ".swiper-pagination", |
| 97 | + clickable: true, |
| 98 | + }, |
| 99 | + mousewheel: true, |
| 100 | + keyboard: true, |
| 101 | +}); |
| 102 | +/*==================== TESTIMONIAL ====================*/ |
| 103 | + |
| 104 | +/*==================== SCROLL SECTIONS ACTIVE LINK ====================*/ |
| 105 | +// const sections = document.querySelectorAll("section[id]"); |
| 106 | + |
| 107 | +// function scrollActive() { |
| 108 | +// const scrollY = window.pageYOffset; |
| 109 | + |
| 110 | +// sections.forEach((current) => { |
| 111 | +// const sectionHeight = current.offsetHeight; |
| 112 | +// const sectionTop = current.offsetTop - 50; |
| 113 | +// const sectionId = current.getAttribute("id"); |
| 114 | + |
| 115 | +// if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { |
| 116 | +// document.querySelector(".nav__menu a[href*=" + sectionId + "]").classList.add('.active-link'); |
| 117 | +// }else{ |
| 118 | +// document.querySelector(".nav__menu a[href*=" + sectionId + "]").classList.remove('.active-link') |
| 119 | +// } |
| 120 | +// }); |
| 121 | +// } |
| 122 | + |
| 123 | +// window.addEventListener('scroll', scrollActive) |
| 124 | +/*==================== CHANGE BACKGROUND HEADER ====================*/ |
| 125 | + |
| 126 | +/*==================== SHOW SCROLL UP ====================*/ |
| 127 | +function scrollUp() { |
| 128 | + const scrollUp = document.getElementById("scroll-up"); |
| 129 | + if (this.scrollY >= 560) scrollUp.classList.add("show-scroll"); |
| 130 | + else scrollUp.classList.remove("show-scroll"); |
| 131 | +} |
| 132 | +window.addEventListener("scroll", scrollUp); |
| 133 | + |
| 134 | +/*==================== DARK LIGHT THEME ====================*/ |
| 135 | +const themeButton = document.getElementById("theme-button"); |
| 136 | +const darkTheme = "dark-theme"; |
| 137 | +const iconTheme = "uil-sun"; |
| 138 | + |
| 139 | +// previously selected topic (if user selected) |
| 140 | +const selectedTheme = localStorage.getItem("selected-theme"); |
| 141 | +const selectedIcon = localStorage.getItem("selected-icon"); |
| 142 | + |
| 143 | +// we obtain the current theme that the interface has by validating the dark-them |
| 144 | +const getCurrentTheme = () => |
| 145 | + document.body.classList.contains(darkTheme) ? "dark" : "light"; |
| 146 | +const getCurrentIcon = () => |
| 147 | + themeButton.classList.contains(iconTheme) ? "uil-moon" : "uil-sun"; |
| 148 | + |
| 149 | +// we validate if the user previously chose a topic |
| 150 | +if (selectedTheme) { |
| 151 | + // if the validation is fulfilled, we ask what the issue was to know if we activated |
| 152 | + document.body.classList[selectedTheme === "dark" ? "add" : "remove"]( |
| 153 | + darkTheme |
| 154 | + ); |
| 155 | + themeButton.classList[selectedIcon === "uil-moon" ? "add" : "remove"]( |
| 156 | + iconTheme |
| 157 | + ); |
| 158 | +} |
| 159 | + |
| 160 | +// activate / deactivate the theme manually with the button |
| 161 | +themeButton.addEventListener("click", () => { |
| 162 | + // add or remove the dark / icon theme |
| 163 | + document.body.classList.toggle(darkTheme); |
| 164 | + themeButton.classList.toggle(iconTheme); |
| 165 | + // we save the theme and the current icon that the user chose |
| 166 | + localStorage.setItem("selected-themee", getCurrentTheme()); |
| 167 | + localStorage.setItem("selected-icon", getCurrentIcon()); |
| 168 | +}); |
| 169 | + |
| 170 | +// ------ TYPICAL ------ |
| 171 | +var TxtType = function (el, toRotate, period) { |
| 172 | + this.toRotate = toRotate; |
| 173 | + this.el = el; |
| 174 | + this.loopNum = 0; |
| 175 | + this.period = parseInt(period, 10) || 2000; |
| 176 | + this.txt = ""; |
| 177 | + this.tick(); |
| 178 | + this.isDeleting = false; |
| 179 | +}; |
| 180 | + |
| 181 | +TxtType.prototype.tick = function () { |
| 182 | + var i = this.loopNum % this.toRotate.length; |
| 183 | + var fullTxt = this.toRotate[i]; |
| 184 | + |
| 185 | + if (this.isDeleting) { |
| 186 | + this.txt = fullTxt.substring(0, this.txt.length - 1); |
| 187 | + } else { |
| 188 | + this.txt = fullTxt.substring(0, this.txt.length + 1); |
| 189 | + } |
| 190 | + |
| 191 | + this.el.innerHTML = '<span class="wrap">' + this.txt + "</span>"; |
| 192 | + |
| 193 | + var that = this; |
| 194 | + var delta = 200 - Math.random() * 100; |
| 195 | + |
| 196 | + if (this.isDeleting) { |
| 197 | + delta /= 2; |
| 198 | + } |
| 199 | + |
| 200 | + if (!this.isDeleting && this.txt === fullTxt) { |
| 201 | + delta = this.period; |
| 202 | + this.isDeleting = true; |
| 203 | + } else if (this.isDeleting && this.txt === "") { |
| 204 | + this.isDeleting = false; |
| 205 | + this.loopNum++; |
| 206 | + delta = 500; |
| 207 | + } |
| 208 | + |
| 209 | + setTimeout(function () { |
| 210 | + that.tick(); |
| 211 | + }, delta); |
| 212 | +}; |
| 213 | + |
| 214 | +window.onload = function () { |
| 215 | + var elements = document.getElementsByClassName("typewrite"); |
| 216 | + for (var i = 0; i < elements.length; i++) { |
| 217 | + var toRotate = elements[i].getAttribute("data-type"); |
| 218 | + var period = elements[i].getAttribute("data-period"); |
| 219 | + if (toRotate) { |
| 220 | + new TxtType(elements[i], JSON.parse(toRotate), period); |
| 221 | + } |
| 222 | + } |
| 223 | + // INJECT CSS |
| 224 | + var css = document.createElement("style"); |
| 225 | + css.type = "text/css"; |
| 226 | + css.innerHTML = ".typewrite > .wrap { border-right: 0.08em solid #fff}"; |
| 227 | + document.body.appendChild(css); |
| 228 | +}; |
0 commit comments