-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
1,744 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
function initAnimations() { | ||
// Skill bar animasyonları | ||
const observer = new IntersectionObserver((entries) => { | ||
entries.forEach(entry => { | ||
if (entry.isIntersecting) { | ||
entry.target.classList.add('animate'); | ||
} | ||
}); | ||
}, { threshold: 0.1 }); | ||
|
||
document.querySelectorAll('.progress').forEach(progress => { | ||
observer.observe(progress); | ||
}); | ||
|
||
// Fade-in animasyonları | ||
const sectionObserver = new IntersectionObserver( | ||
(entries) => { | ||
entries.forEach(entry => { | ||
if (entry.isIntersecting) { | ||
entry.target.classList.add('fade-in'); | ||
} | ||
}); | ||
}, | ||
{ threshold: 0.1 } | ||
); | ||
|
||
document.querySelectorAll('.section').forEach(section => { | ||
sectionObserver.observe(section); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
function toggleEducation(element) { | ||
const timelineItem = element.closest('.timeline-item'); | ||
const wasActive = timelineItem.classList.contains('active'); | ||
|
||
document.querySelectorAll('.timeline-item').forEach(item => { | ||
item.classList.remove('active'); | ||
}); | ||
|
||
if (!wasActive) { | ||
timelineItem.classList.add('active'); | ||
scrollToElement(element); | ||
} | ||
} | ||
|
||
function initFirstEducationItem() { | ||
const firstItem = document.querySelector('.timeline-item'); | ||
if (firstItem) { | ||
firstItem.classList.add('active'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
document.addEventListener('DOMContentLoaded', function() { | ||
// Modal HTML'ini oluştur | ||
const modal = document.createElement('div'); | ||
modal.className = 'modal'; | ||
modal.innerHTML = ` | ||
<span class="modal-close">×</span> | ||
<span class="modal-nav modal-prev">❮</span> | ||
<span class="modal-nav modal-next">❯</span> | ||
<img class="modal-content" id="modalImage"> | ||
`; | ||
document.body.appendChild(modal); | ||
|
||
const images = document.querySelectorAll('.diploma-image-container img'); | ||
const modalImg = document.getElementById('modalImage'); | ||
let currentIndex = 0; | ||
|
||
// Modal'ı aç | ||
function openModal(index) { | ||
modal.style.display = 'block'; | ||
currentIndex = index; | ||
updateModalImage(); | ||
document.body.style.overflow = 'hidden'; | ||
} | ||
|
||
// Modal'ı kapat | ||
function closeModal() { | ||
modal.style.display = 'none'; | ||
document.body.style.overflow = 'auto'; | ||
} | ||
|
||
// Modal içindeki resmi güncelle | ||
function updateModalImage() { | ||
modalImg.src = images[currentIndex].src; | ||
} | ||
|
||
// Önceki resme git | ||
function prevImage() { | ||
currentIndex = (currentIndex - 1 + images.length) % images.length; | ||
updateModalImage(); | ||
} | ||
|
||
// Sonraki resme git | ||
function nextImage() { | ||
currentIndex = (currentIndex + 1) % images.length; | ||
updateModalImage(); | ||
} | ||
|
||
// Resimlere tıklama olayı | ||
images.forEach((img, index) => { | ||
img.addEventListener('click', () => openModal(index)); | ||
}); | ||
|
||
// Kapatma butonuna tıklama | ||
modal.querySelector('.modal-close').addEventListener('click', closeModal); | ||
|
||
// Modal dışına tıklama | ||
modal.addEventListener('click', (e) => { | ||
if (e.target === modal) closeModal(); | ||
}); | ||
|
||
// Gezinme butonlarına tıklama | ||
modal.querySelector('.modal-prev').addEventListener('click', (e) => { | ||
e.stopPropagation(); | ||
prevImage(); | ||
}); | ||
|
||
modal.querySelector('.modal-next').addEventListener('click', (e) => { | ||
e.stopPropagation(); | ||
nextImage(); | ||
}); | ||
|
||
// Klavye kontrolleri | ||
document.addEventListener('keydown', (e) => { | ||
if (modal.style.display === 'block') { | ||
if (e.key === 'Escape') closeModal(); | ||
if (e.key === 'ArrowLeft') prevImage(); | ||
if (e.key === 'ArrowRight') nextImage(); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
document.addEventListener('DOMContentLoaded', function() { | ||
const images = document.querySelectorAll('.zoomable-image'); | ||
|
||
images.forEach(img => { | ||
const MIN_SCALE = 1; | ||
const MAX_SCALE = 4; | ||
const SCALE_STEP = 0.1; | ||
|
||
let currentScale = 1; | ||
let isZoomed = false; | ||
let currentPos = { x: 0, y: 0 }; | ||
|
||
// Mouse wheel ile zoom | ||
img.addEventListener('wheel', function(e) { | ||
e.preventDefault(); | ||
|
||
const delta = e.deltaY > 0 ? -1 : 1; | ||
let newScale = currentScale + (delta * SCALE_STEP); | ||
newScale = Math.min(Math.max(newScale, MIN_SCALE), MAX_SCALE); | ||
|
||
if (newScale !== currentScale) { | ||
currentScale = newScale; | ||
isZoomed = currentScale > 1; | ||
|
||
if (!isZoomed) { | ||
resetZoom(); | ||
} else { | ||
// Zoom yaparken mouse pozisyonunu merkez al | ||
const rect = img.getBoundingClientRect(); | ||
const mouseX = (e.clientX - rect.left) / rect.width; | ||
const mouseY = (e.clientY - rect.top) / rect.height; | ||
|
||
const moveX = (mouseX - 0.5) * 2; | ||
const moveY = (mouseY - 0.5) * 2; | ||
|
||
currentPos = { | ||
x: -moveX * (rect.width * (currentScale - 1)) / 2, | ||
y: -moveY * (rect.height * (currentScale - 1)) / 2 | ||
}; | ||
} | ||
|
||
updateTransform(); | ||
} | ||
}); | ||
|
||
// Mouse hareketi ile pan | ||
img.addEventListener('mousemove', function(e) { | ||
if (!isZoomed) return; | ||
|
||
const rect = img.getBoundingClientRect(); | ||
const mouseX = (e.clientX - rect.left) / rect.width; | ||
const mouseY = (e.clientY - rect.top) / rect.height; | ||
|
||
const moveX = (mouseX - 0.5) * 2; | ||
const moveY = (mouseY - 0.5) * 2; | ||
|
||
const maxMoveX = (rect.width * currentScale - rect.width) / 2; | ||
const maxMoveY = (rect.height * currentScale - rect.height) / 2; | ||
|
||
currentPos = { | ||
x: -moveX * maxMoveX, | ||
y: -moveY * maxMoveY | ||
}; | ||
|
||
updateTransform(); | ||
}); | ||
|
||
// Mouse leave olayı | ||
img.addEventListener('mouseleave', function() { | ||
resetZoom(); | ||
}); | ||
|
||
// Transform güncelleme fonksiyonu | ||
function updateTransform() { | ||
img.style.transform = `translate(${currentPos.x}px, ${currentPos.y}px) scale(${currentScale})`; | ||
img.classList.toggle('zoomed', isZoomed); | ||
} | ||
|
||
// Zoom'u resetleme fonksiyonu | ||
function resetZoom() { | ||
currentScale = 1; | ||
currentPos = { x: 0, y: 0 }; | ||
isZoomed = false; | ||
updateTransform(); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
// Performans ve kullanıcı deneyimi iyileştirmeleri | ||
document.addEventListener('DOMContentLoaded', function() { | ||
// Tema değiştirici | ||
const themeToggle = document.querySelector('.theme-toggle'); | ||
if (themeToggle) { | ||
themeToggle.addEventListener('click', () => { | ||
const root = document.documentElement; | ||
const currentTheme = root.getAttribute('data-theme'); | ||
const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; | ||
root.setAttribute('data-theme', newTheme); | ||
localStorage.setItem('theme', newTheme); // Tema tercihini kaydet | ||
}); | ||
} | ||
|
||
// Tercih edilen temayı yükle | ||
const savedTheme = localStorage.getItem('theme'); | ||
if (savedTheme) { | ||
document.documentElement.setAttribute('data-theme', savedTheme); | ||
} | ||
|
||
// Mobil menü kontrolü | ||
const menuToggle = document.querySelector('.menu-toggle'); | ||
const sidenav = document.querySelector('.ok-sidenav'); | ||
if (menuToggle && sidenav) { | ||
menuToggle.addEventListener('click', () => { | ||
sidenav.classList.toggle('active'); | ||
menuToggle.classList.toggle('active'); | ||
}); | ||
|
||
// Menü dışına tıklandığında kapat | ||
document.addEventListener('click', (e) => { | ||
if (!sidenav.contains(e.target) && !menuToggle.contains(e.target)) { | ||
sidenav.classList.remove('active'); | ||
menuToggle.classList.remove('active'); | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
// İyileştirilmiş Modal Yönetimi | ||
class ImageModal { | ||
constructor() { | ||
this.createModal(); | ||
this.initializeEvents(); | ||
this.preloadImages(); | ||
} | ||
|
||
createModal() { | ||
this.modal = document.createElement('div'); | ||
this.modal.className = 'modal'; | ||
this.modal.innerHTML = ` | ||
<div class="modal-content-wrapper"> | ||
<span class="modal-close">×</span> | ||
<span class="modal-nav modal-prev" data-tooltip="Önceki">❮</span> | ||
<span class="modal-nav modal-next" data-tooltip="Sonraki">❯</span> | ||
<img class="modal-content" id="modalImage"> | ||
<div class="modal-counter"></div> | ||
</div> | ||
`; | ||
document.body.appendChild(this.modal); | ||
|
||
this.modalImg = this.modal.querySelector('#modalImage'); | ||
this.counter = this.modal.querySelector('.modal-counter'); | ||
this.images = Array.from(document.querySelectorAll('.diploma-image-container img')); | ||
this.currentIndex = 0; | ||
} | ||
|
||
initializeEvents() { | ||
// Resim tıklama olayları | ||
this.images.forEach((img, index) => { | ||
img.addEventListener('click', () => this.openModal(index)); | ||
}); | ||
|
||
// Modal kontrolleri | ||
this.modal.querySelector('.modal-close').addEventListener('click', () => this.closeModal()); | ||
this.modal.querySelector('.modal-prev').addEventListener('click', (e) => { | ||
e.stopPropagation(); | ||
this.navigate(-1); | ||
}); | ||
this.modal.querySelector('.modal-next').addEventListener('click', (e) => { | ||
e.stopPropagation(); | ||
this.navigate(1); | ||
}); | ||
|
||
// Modal dışına tıklama | ||
this.modal.addEventListener('click', (e) => { | ||
if (e.target === this.modal) this.closeModal(); | ||
}); | ||
|
||
// Klavye kontrolleri | ||
document.addEventListener('keydown', (e) => { | ||
if (!this.modal.style.display === 'block') return; | ||
|
||
switch(e.key) { | ||
case 'Escape': this.closeModal(); break; | ||
case 'ArrowLeft': this.navigate(-1); break; | ||
case 'ArrowRight': this.navigate(1); break; | ||
} | ||
}); | ||
|
||
// Touch olayları | ||
let touchStartX = 0; | ||
let touchEndX = 0; | ||
|
||
this.modal.addEventListener('touchstart', (e) => { | ||
touchStartX = e.changedTouches[0].screenX; | ||
}); | ||
|
||
this.modal.addEventListener('touchend', (e) => { | ||
touchEndX = e.changedTouches[0].screenX; | ||
this.handleSwipe(touchStartX, touchEndX); | ||
}); | ||
} | ||
|
||
handleSwipe(startX, endX) { | ||
const swipeThreshold = 50; | ||
const diff = startX - endX; | ||
|
||
if (Math.abs(diff) > swipeThreshold) { | ||
if (diff > 0) { | ||
this.navigate(1); // Sola kaydırma | ||
} else { | ||
this.navigate(-1); // Sağa kaydırma | ||
} | ||
} | ||
} | ||
|
||
preloadImages() { | ||
// Sonraki ve önceki resimleri önceden yükle | ||
this.images.forEach(img => { | ||
const preloadLink = document.createElement('link'); | ||
preloadLink.rel = 'preload'; | ||
preloadLink.as = 'image'; | ||
preloadLink.href = img.src; | ||
document.head.appendChild(preloadLink); | ||
}); | ||
} | ||
|
||
openModal(index) { | ||
this.modal.style.display = 'block'; | ||
this.currentIndex = index; | ||
this.updateModalImage(); | ||
document.body.style.overflow = 'hidden'; | ||
this.modalImg.classList.add('fade-in'); | ||
} | ||
|
||
closeModal() { | ||
this.modal.style.display = 'none'; | ||
document.body.style.overflow = 'auto'; | ||
this.modalImg.classList.remove('fade-in'); | ||
} | ||
|
||
navigate(direction) { | ||
this.currentIndex = (this.currentIndex + direction + this.images.length) % this.images.length; | ||
this.modalImg.classList.remove('fade-in'); | ||
setTimeout(() => { | ||
this.updateModalImage(); | ||
this.modalImg.classList.add('fade-in'); | ||
}, 300); | ||
} | ||
|
||
updateModalImage() { | ||
this.modalImg.src = this.images[this.currentIndex].src; | ||
this.counter.textContent = `${this.currentIndex + 1} / ${this.images.length}`; | ||
} | ||
} | ||
|
||
// Modal'ı başlat | ||
new ImageModal(); |
Oops, something went wrong.