1/** 2 * feature-showcase.js 3 * 4 * Desktop (â¥1360px): scroll pozisyonuna göre slayt deÄiÅir 5 * Mobil (<1360px): touch swipe ile slayt deÄiÅir 6 * 7 * GeçiÅ: crossfade â out ve in aynı anda, translateY Åiddetli 8 * 9 * Slayt sayısı DOM'dan okunur. Slayt eklerken/çıkarırken burada 10 * deÄiÅtirilecek bir Åey yok, sadece .feature-showcase yüksekliÄi 11 * slayt sayısıyla uyumlu olmalı. 12 */ 13(function () { 14 function init() { 15 const showcase = document.querySelector(".feature-showcase"); 16 if (!showcase) return; 17 18 const slides = showcase.querySelectorAll(".feature-slide"); 19 const dots = showcase.querySelectorAll(".feature-dot"); 20 const scrollEl = document.querySelector(".fullcontent"); 21 if (!scrollEl || !slides.length) return; 22 23 const TOTAL = slides.length; 24 25 // Nokta sayısı slayt sayısını tutmuyorsa fazlalıkları gizle 26 dots.forEach((dot, i) => { 27 dot.style.display = i < TOTAL ? "" : "none"; 28 }); 29 30 // Kaydırma alanı slayt sayısına göre ayarlanır, CSS'te sabit 31 // yükseklik tutmaya gerek kalmaz 32 showcase.style.height = TOTAL * 100 + "vh"; 33 34 const isMobile = () => window.innerWidth < 1360; 35 36 let current = 0; 37 let animating = false; 38 let pending = null; 39 40 function goTo(next, dir) { 41 if (next < 0 || next >= TOTAL || next === current) return; 42 43 // Animasyon sürerken gelen istek kaybolmasın, sonunda uygulanır 44 if (animating) { 45 pending = next; 46 return; 47 } 48 animating = true; 49 50 const outSlide = slides[current]; 51 const inSlide = slides[next]; 52 const outY = dir > 0 ? "-64px" : "64px"; 53 const inY = dir > 0 ? "64px" : "-64px"; 54 55 // In slide hazırla â görünmez, offset pozisyonda 56 inSlide.style.cssText = 57 "opacity: 0; display: flex;" + 58 " transform: translateY(" + 59 inY + 60 ") scale(0.9);" + 61 " filter: blur(var(--wtk-translucent-blur));"; 62 inSlide.classList.add("active"); 63 64 // Her ikisi de transition baÅlat (crossfade) 65 requestAnimationFrame(() => { 66 requestAnimationFrame(() => { 67 const transition = 68 "opacity 350ms ease, transform 350ms ease, filter 350ms ease"; 69 70 outSlide.style.transition = transition; 71 outSlide.style.opacity = "0"; 72 outSlide.style.transform = `translateY(${outY}) scale(0.9)`; 73 outSlide.style.filter = "blur(var(--wtk-translucent-blur))"; 74 75 inSlide.style.transition = transition; 76 inSlide.style.opacity = "1"; 77 inSlide.style.transform = "translateY(0) scale(1)"; 78 inSlide.style.filter = "blur(0px)"; 79 80 setTimeout(() => { 81 outSlide.classList.remove("active"); 82 outSlide.style.cssText = ""; 83 inSlide.style.cssText = ""; 84 animating = false; 85 86 if (pending !== null) { 87 const target = pending; 88 pending = null; 89 goTo(target, target > current ? 1 : -1); 90 } 91 }, 360); 92 }); 93 }); 94 95 if (dots.length) { 96 if (dots[current]) dots[current].classList.remove("active"); 97 if (dots[next]) dots[next].classList.add("active"); 98 } 99 100 current = next; 101 } 102 103 // âââ Desktop: scroll pozisyonuna göre slayt âââ 104 function onScroll() { 105 const showcaseTop = showcase.offsetTop; 106 const scrollY = scrollEl.scrollTop; 107 const relativeScroll = scrollY - showcaseTop; 108 const slideHeight = window.innerHeight; 109 110 if (relativeScroll < 0 || relativeScroll > slideHeight * TOTAL) return; 111 112 const newIndex = Math.min( 113 TOTAL - 1, 114 Math.max( 115 0, 116 Math.floor((relativeScroll + slideHeight * 0.5) / slideHeight), 117 ), 118 ); 119 if (newIndex !== current) { 120 goTo(newIndex, newIndex > current ? 1 : -1); 121 } 122 } 123 124 scrollEl.addEventListener("scroll", onScroll, { passive: true }); 125 126 // Dot tıklaması â scroll pozisyonunu ayarla 127 dots.forEach((dot, i) => { 128 if (i >= TOTAL) return; 129 dot.addEventListener("click", () => { 130 const showcaseTop = showcase.offsetTop; 131 scrollEl.scrollTo({ 132 top: showcaseTop + i * window.innerHeight, 133 }); 134 }); 135 }); 136 137 // âââ Mobil: touch swipe âââ 138 let touchStartY = 0; 139 let touchStartX = 0; 140 let swiping = false;
141 142 showcase.addEventListener( 143 "touchstart", 144 (e) => { 145 touchStartY = e.touches[0].clientY; 146 touchStartX = e.touches[0].clientX; 147 swiping = true; 148 }, 149 { passive: true }, 150 ); 151 152 showcase.addEventListener( 153 "touchend", 154 (e) => { 155 if (!swiping || !isMobile()) return; 156 swiping = false; 157 158 const deltaY = touchStartY - e.changedTouches[0].clientY; 159 const deltaX = touchStartX - e.changedTouches[0].clientX; 160 161 if (Math.abs(deltaX) > Math.abs(deltaY)) return; 162 if (Math.abs(deltaY) < 60) return; 163 164 const dir = deltaY > 0 ? 1 : -1; 165 const next = current + dir; 166 167 if (next < 0 || next >= TOTAL) return; 168 169 const showcaseTop = showcase.offsetTop; 170 scrollEl.scrollTo({ 171 top: showcaseTop + next * window.innerHeight, 172 }); 173 174 goTo(next, dir); 175 }, 176 { passive: true }, 177 ); 178 } 179 180 if (document.readyState === "loading") { 181 document.addEventListener("DOMContentLoaded", init); 182 } else { 183 init(); 184 } 185})();
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.