Proje Detayları

Adım Adım Geliştirme

Bu bölümde, animasyon efektlerini adım adım nasıl geliştirebileceğinizi öğreneceksiniz. Her adımda, ilgili kod parçalarını ve açıklamalarını bulacaksınız.

Adım 1: Proje Yapısını Oluşturma

İlk olarak, projemiz için gerekli dosyaları oluşturalım:

  • index.html - Ana HTML dosyası
  • style.css - CSS stil dosyası
  • script.js - JavaScript kod dosyası
index.html
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Animasyon Efektleri</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="animation-container">
            <div class="animation-header">
                <h1>Animasyon Efektleri</h1>
                <p>Farklı animasyon türlerini görmek için butonlara tıklayın</p>
            </div>
            
            <div class="animation-controls">
                <button class="animation-btn" data-animation="fade-in">Fade In</button>
                <button class="animation-btn" data-animation="slide-in">Slide In</button>
                <button class="animation-btn" data-animation="scale-up">Scale Up</button>
                <button class="animation-btn" data-animation="rotate">Rotate</button>
                <button class="animation-btn" data-animation="pulse">Pulse</button>
                <button class="animation-btn" data-animation="bounce">Bounce</button>
            </div>
            
            <div class="animation-showcase">
                <div class="animation-box" id="animationBox">
                    Efekt
                </div>
            </div>
            
            <div class="animation-header">
                <h2>Gelişmiş Animasyonlar</h2>
                <p>Karmaşık hareket yolları ve paralaks efektler</p>
            </div>
            
            <div class="animation-scene">
                <div class="animation-element animation-path"></div>
            </div>
            
            <div class="animation-parallax" id="parallaxScene">
                <div class="parallax-layer parallax-bg"></div>
                <div class="parallax-layer parallax-mid">
                    <div class="parallax-cloud cloud-1"></div>
                    <div class="parallax-cloud cloud-2"></div>
                    <div class="parallax-cloud cloud-3"></div>
                </div>
                <div class="parallax-layer parallax-front">
                    <div class="parallax-mountain"></div>
                    <div class="parallax-tree"></div>
                </div>
            </div>
            
            <div class="animation-header">
                <h2>Kaydırma Animasyonları</h2>
                <p>Sayfayı aşağı kaydırdıkça görünür olan öğeler</p>
            </div>
            
            <div class="scroll-animations">
                <div class="scroll-item" data-animation="fade-in">Fade In</div>
                <div class="scroll-item" data-animation="slide-in">Slide In</div>
                <div class="scroll-item" data-animation="scale-up">Scale Up</div>
                <div class="scroll-item" data-animation="rotate">Rotate</div>
            </div>
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

Adım 2: CSS Animasyonları Oluşturma

Şimdi, farklı animasyon efektleri için CSS kodunu yazalım:

style.css
/* Genel Stiller */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #f5f5f5;
    color: #333;
    line-height: 1.6;
}

.container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}

/* Animasyon Konteyner Stilleri */
.animation-container {
    width: 100%;
    max-width: 800px;
    margin: 0 auto;
}

.animation-header {
    text-align: center;
    margin-bottom: 30px;
}

.animation-header h1 {
    font-size: 2.5rem;
    color: #333;
    margin-bottom: 10px;
}

.animation-header h2 {
    font-size: 2rem;
    color: #333;
    margin-bottom: 10px;
}

.animation-header p {
    color: #666;
    font-size: 1.1rem;
}

/* Animasyon Kontrol Butonları */
.animation-controls {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    margin-bottom: 20px;
    gap: 10px;
}

.animation-btn {
    background-color: #4caf50;
    color: white;
    border: none;
    padding: 10px 15px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
    transition: background-color 0.3s;
}

.animation-btn:hover {
    background-color: #388e3c;
}

.animation-btn.active {
    background-color: #2196f3;
}

/* Animasyon Gösterim Alanı */
.animation-showcase {
    display: flex;
    justify-content: center;
    margin-bottom: 50px;
}

.animation-box {
    width: 200px;
    height: 200px;
    background-color: #2196f3;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-weight: bold;
    font-size: 1.5rem;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

/* Temel Animasyon Sınıfları */
.fade-in {
    animation: fadeIn 2s ease;
}

.fade-out {
    animation: fadeOut 2s ease;
}

.slide-in {
    animation: slideIn 1s ease;
}

.slide-out {
    animation: slideOut 1s ease;
}

.scale-up {
    animation: scaleUp 1s ease;
}

.scale-down {
    animation: scaleDown 1s ease;
}

.rotate {
    animation: rotate 2s linear infinite;
}

.pulse {
    animation: pulse 1.5s ease infinite;
}

.bounce {
    animation: bounce 1s ease infinite;
}

/* Animasyon Keyframes */
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes fadeOut {
    from { opacity: 1; }
    to { opacity: 0; }
}

@keyframes slideIn {
    from { transform: translateX(-100%); }
    to { transform: translateX(0); }
}

@keyframes slideOut {
    from { transform: translateX(0); }
    to { transform: translateX(100%); }
}

@keyframes scaleUp {
    from { transform: scale(0); }
    to { transform: scale(1); }
}

@keyframes scaleDown {
    from { transform: scale(1); }
    to { transform: scale(0); }
}

@keyframes rotate {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

@keyframes pulse {
    0% { transform: scale(1); }
    50% { transform: scale(1.1); }
    100% { transform: scale(1); }
}

@keyframes bounce {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-30px); }
}

/* Gelişmiş Animasyon Stilleri */
.animation-scene {
    width: 100%;
    height: 300px;
    background-color: #f0f0f0;
    border-radius: 8px;
    position: relative;
    overflow: hidden;
    margin-bottom: 50px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

.animation-element {
    position: absolute;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background-color: #2196f3;
}

.animation-path {
    animation: movePath 5s linear infinite;
}

@keyframes movePath {
    0% { left: 0; top: 50%; transform: translateY(-50%); }
    25% { left: 50%; top: 0; transform: translate(-50%, 0); }
    50% { left: 100%; top: 50%; transform: translate(-100%, -50%); }
    75% { left: 50%; top: 100%; transform: translate(-50%, -100%); }
    100% { left: 0; top: 50%; transform: translateY(-50%); }
}

/* Paralaks Efekt Stilleri */
.animation-parallax {
    width: 100%;
    height: 300px;
    background-color: #87ceeb; /* Gökyüzü rengi */
    border-radius: 8px;
    position: relative;
    overflow: hidden;
    margin-bottom: 50px;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

.parallax-layer {
    position: absolute;
    width: 100%;
    height: 100%;
}

.parallax-bg {
    background-color: transparent;
}

.parallax-mid {
    display: flex;
    justify-content: space-around;
    align-items: center;
}

.parallax-front {
    display: flex;
    justify-content: space-around;
    align-items: flex-end;
    padding-bottom: 20px;
}

.parallax-cloud {
    width: 80px;
    height: 40px;
    background-color: white;
    border-radius: 20px;
    position: relative;
}

.parallax-cloud:before, .parallax-cloud:after {
    content: '';
    position: absolute;
    background-color: white;
    border-radius: 50%;
}

.parallax-cloud:before {
    width: 40px;
    height: 40px;
    top: -20px;
    left: 10px;
}

.parallax-cloud:after {
    width: 30px;
    height: 30px;
    top: -15px;
    right: 10px;
}

.parallax-mountain {
    width: 0;
    height: 0;
    border-left: 60px solid transparent;
    border-right: 60px solid transparent;
    border-bottom: 100px solid #4caf50;
}

.parallax-tree {
    width: 20px;
    height: 60px;
    background-color: #795548;
    position: relative;
}

.parallax-tree:before {
    content: '';
    position: absolute;
    top: -50px;
    left: -40px;
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 60px solid #388e3c;
}

.cloud-1 {
    animation: cloudMove 20s linear infinite;
}

.cloud-2 {
    animation: cloudMove 15s linear infinite;
    animation-delay: 5s;
}

.cloud-3 {
    animation: cloudMove 25s linear infinite;
    animation-delay: 10s;
}

@keyframes cloudMove {
    from { transform: translateX(-100%); }
    to { transform: translateX(100vw); }
}

/* Kaydırma Animasyonları */
.scroll-animations {
    display: flex;
    flex-direction: column;
    gap: 100px;
    margin-bottom: 50px;
}

.scroll-item {
    width: 100%;
    height: 150px;
    background-color: #2196f3;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-weight: bold;
    font-size: 1.5rem;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    opacity: 0; /* Başlangıçta görünmez */
}

/* Responsive Tasarım */
@media (max-width: 768px) {
    .animation-box {
        width: 150px;
        height: 150px;
        font-size: 1.2rem;
    }
    
    .animation-scene, .animation-parallax {
        height: 200px;
    }
    
    .scroll-item {
        height: 100px;
    }
}

Adım 3: JavaScript ile Animasyonları Kontrol Etme

Şimdi, animasyonları JavaScript ile kontrol etmek için kod yazalım:

script.js
// DOM elementlerini seçme
const animationBox = document.getElementById('animationBox');
const animationButtons = document.querySelectorAll('.animation-btn');
const parallaxScene = document.getElementById('parallaxScene');
const scrollItems = document.querySelectorAll('.scroll-item');

// Sayfa yüklendiğinde
document.addEventListener('DOMContentLoaded', () => {
    // Animasyon butonları için olay dinleyicileri
    animationButtons.forEach(button => {
        button.addEventListener('click', () => {
            // Aktif butonu güncelle
            animationButtons.forEach(btn => btn.classList.remove('active'));
            button.classList.add('active');
            
            // Animasyon kutusundan tüm animasyon sınıflarını kaldır
            animationBox.className = 'animation-box';
            
            // Animasyonu yeniden başlatmak için bir mikrosaniye bekle
            setTimeout(() => {
                // Seçilen animasyonu uygula
                const animation = button.getAttribute('data-animation');
                animationBox.classList.add(animation);
            }, 1);
        });
    });
    
    // Paralaks efekti için kaydırma olayı
    window.addEventListener('scroll', () => {
        if (parallaxScene) {
            const scrollPosition = window.scrollY;
            
            // Paralaks katmanlarını farklı hızlarda hareket ettir
            const parallaxBg = parallaxScene.querySelector('.parallax-bg');
            const parallaxMid = parallaxScene.querySelector('.parallax-mid');
            const parallaxFront = parallaxScene.querySelector('.parallax-front');
            
            if (parallaxBg && parallaxMid && parallaxFront) {
                parallaxBg.style.transform = `translateY(${scrollPosition * 0.1}px)`;
                parallaxMid.style.transform = `translateY(${scrollPosition * 0.3}px)`;
                parallaxFront.style.transform = `translateY(${scrollPosition * 0.5}px)`;
            }
        }
    });
    
    // Kaydırma animasyonları için Intersection Observer
    const observerOptions = {
        root: null, // viewport kullan
        rootMargin: '0px',
        threshold: 0.3 // öğenin %30'u görünür olduğunda tetikle
    };
    
    const observer = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                const animation = entry.target.getAttribute('data-animation');
                entry.target.style.opacity = 1;
                entry.target.classList.add(animation);
                
                // Öğe görüntülendikten sonra gözlemlemeyi durdur
                observer.unobserve(entry.target);
            }
        });
    }, observerOptions);
    
    // Tüm kaydırma öğelerini gözlemle
    scrollItems.forEach(item => {
        observer.observe(item);
    });
});

// Animasyon performansını optimize etmek için requestAnimationFrame kullanımı
function animateElement(element, startPos, endPos, duration) {
    const startTime = performance.now();
    
    function update(currentTime) {
        const elapsedTime = currentTime - startTime;
        const progress = Math.min(elapsedTime / duration, 1);
        
        // Easing fonksiyonu (ease-out)
        const easeProgress = 1 - Math.pow(1 - progress, 3);
        
        // Pozisyonu güncelle
        const currentPos = startPos + (endPos - startPos) * easeProgress;
        element.style.transform = `translateX(${currentPos}px)`;
        
        // Animasyon tamamlanmadıysa devam et
        if (progress < 1) {
            requestAnimationFrame(update);
        }
    }
    
    requestAnimationFrame(update);
}

// Özel animasyon fonksiyonu örneği
function customAnimation() {
    const element = document.createElement('div');
    element.className = 'custom-element';
    document.body.appendChild(element);
    
    // -100px'den 100px'e 1 saniyede hareket et
    animateElement(element, -100, 100, 1000);
    
    // Animasyon tamamlandıktan sonra elementi kaldır
    setTimeout(() => {
        document.body.removeChild(element);
    }, 1000);
}

Adım 4: Gelişmiş Animasyon Teknikleri

Şimdi, daha gelişmiş animasyon teknikleri için ek kodlar ekleyelim:

advanced-animations.js
// Gelişmiş animasyon teknikleri
// Bu kodu script.js dosyasına ekleyebilirsiniz

// GSAP benzeri bir zamanlama fonksiyonu
class Timeline {
    constructor() {
        this.animations = [];
        this.currentTime = 0;
    }
    
    add(element, properties, duration, delay = 0) {
        const startTime = this.currentTime + delay;
        
        this.animations.push({
            element,
            properties,
            duration,
            startTime,
            endTime: startTime + duration
        });
        
        // Toplam süreyi güncelle
        this.currentTime = Math.max(this.currentTime, startTime + duration);
        
        return this;
    }
    
    play() {
        const startTime = performance.now();
        
        const animate = (currentTime) => {
            const elapsedTime = currentTime - startTime;
            
            // Tüm animasyonları güncelle
            this.animations.forEach(anim => {
                // Animasyon zamanı geldi mi?
                if (elapsedTime >= anim.startTime && elapsedTime <= anim.endTime) {
                    const progress = (elapsedTime - anim.startTime) / anim.duration;
                    const easeProgress = 1 - Math.pow(1 - progress, 3); // ease-out
                    
                    // Özellikleri güncelle
                    Object.keys(anim.properties).forEach(prop => {
                        const { from, to } = anim.properties[prop];
                        const value = from + (to - from) * easeProgress;
                        
                        if (prop === 'x') {
                            anim.element.style.transform = `translateX(${value}px)`;
                        } else if (prop === 'y') {
                            anim.element.style.transform = `translateY(${value}px)`;
                        } else if (prop === 'scale') {
                            anim.element.style.transform = `scale(${value})`;
                        } else if (prop === 'rotate') {
                            anim.element.style.transform = `rotate(${value}deg)`;
                        } else if (prop === 'opacity') {
                            anim.element.style.opacity = value;
                        }
                    });
                }
            });
            
            // Tüm animasyonlar tamamlanana kadar devam et
            if (elapsedTime < this.currentTime) {
                requestAnimationFrame(animate);
            }
        };
        
        requestAnimationFrame(animate);
        return this;
    }
}

// Kullanım örneği
function createSequenceAnimation() {
    const box = document.createElement('div');
    box.className = 'animation-box';
    box.textContent = 'Sequence';
    document.body.appendChild(box);
    
    const timeline = new Timeline();
    
    timeline
        .add(box, { x: { from: -100, to: 0 }, opacity: { from: 0, to: 1 } }, 500)
        .add(box, { y: { from: 0, to: -50 } }, 500, 500)
        .add(box, { scale: { from: 1, to: 1.5 } }, 500, 1000)
        .add(box, { rotate: { from: 0, to: 360 } }, 1000, 1500)
        .add(box, { scale: { from: 1.5, to: 1 } }, 500, 2500)
        .add(box, { y: { from: -50, to: 0 } }, 500, 3000)
        .add(box, { opacity: { from: 1, to: 0 } }, 500, 3500)
        .play();
    
    // Animasyon tamamlandıktan sonra elementi kaldır
    setTimeout(() => {
        document.body.removeChild(box);
    }, 4500);
}

// Kaydırma bazlı animasyon kontrolü
function setupScrollAnimations() {
    const animatedElements = document.querySelectorAll('[data-scroll-animation]');
    
    // Kaydırma pozisyonunu takip et
    let lastScrollPosition = window.scrollY;
    let ticking = false;
    
    window.addEventListener('scroll', () => {
        lastScrollPosition = window.scrollY;
        
        if (!ticking) {
            window.requestAnimationFrame(() => {
                updateElementsOnScroll(lastScrollPosition);
                ticking = false;
            });
            
            ticking = true;
        }
    });
    
    function updateElementsOnScroll(scrollPosition) {
        animatedElements.forEach(element => {
            const elementTop = element.getBoundingClientRect().top + scrollPosition;
            const elementHeight = element.offsetHeight;
            const windowHeight = window.innerHeight;
            
            // Görünürlük yüzdesi hesapla (0-1 arası)
            const visibilityPercentage = Math.max(0, Math.min(1, 
                (scrollPosition + windowHeight - elementTop) / (windowHeight + elementHeight)
            ));
            
            // Animasyon türünü al
            const animationType = element.getAttribute('data-scroll-animation');
            
            // Animasyon türüne göre uygula
            if (animationType === 'fade') {
                element.style.opacity = visibilityPercentage;
            } else if (animationType === 'slide') {
                const slideDistance = 100 * (1 - visibilityPercentage);
                element.style.transform = `translateX(${slideDistance}px)`;
            } else if (animationType === 'scale') {
                const scale = 0.5 + (0.5 * visibilityPercentage);
                element.style.transform = `scale(${scale})`;
            } else if (animationType === 'rotate') {
                const rotation = 360 * visibilityPercentage;
                element.style.transform = `rotate(${rotation}deg)`;
            }
        });
    }
    
    // Sayfa yüklendiğinde ilk güncellemeyi yap
    updateElementsOnScroll(lastScrollPosition);
}

// Sayfa yüklendiğinde gelişmiş animasyonları ayarla
document.addEventListener('DOMContentLoaded', () => {
    // Kaydırma animasyonlarını ayarla
    setupScrollAnimations();
    
    // Animasyon demo butonları
    const demoButton = document.createElement('button');
    demoButton.className = 'animation-btn';
    demoButton.textContent = 'Sequence Demo';
    demoButton.addEventListener('click', createSequenceAnimation);
    
    // Butonları kontrol paneline ekle
    const controlsContainer = document.querySelector('.animation-controls');
    if (controlsContainer) {
        controlsContainer.appendChild(demoButton);
    }
});

Adım 5: Performans Optimizasyonu

Animasyon performansını optimize etmek için aşağıdaki teknikleri kullanabilirsiniz:

performance.js
// Animasyon performans optimizasyonu
// Bu kodu script.js dosyasına ekleyebilirsiniz

// GPU hızlandırmalı özellikleri kullan
function optimizeAnimations() {
    const animatedElements = document.querySelectorAll('.animation-box, .animation-element, .scroll-item');
    
    animatedElements.forEach(element => {
        // transform ve opacity özellikleri GPU tarafından hızlandırılır
        element.style.willChange = 'transform, opacity';
        
        // Animasyon tamamlandığında willChange'i kaldır
        element.addEventListener('animationend', () => {
            element.style.willChange = 'auto';
        });
    });
}

// Animasyonları throttle et (sınırla)
function throttleAnimation(callback, delay) {
    let lastCall = 0;
    
    return function(...args) {
        const now = Date.now();
        
        if (now - lastCall >= delay) {
            lastCall = now;
            callback(...args);
        }
    };
}

// Kaydırma olayını throttle et
const throttledScrollHandler = throttleAnimation(() => {
    // Kaydırma bazlı animasyonları güncelle
    const scrollPosition = window.scrollY;
    updateParallaxEffect(scrollPosition);
}, 16); // 60fps için yaklaşık 16ms

function updateParallaxEffect(scrollPosition) {
    if (parallaxScene) {
        const parallaxBg = parallaxScene.querySelector('.parallax-bg');
        const parallaxMid = parallaxScene.querySelector('.parallax-mid');
        const parallaxFront = parallaxScene.querySelector('.parallax-front');
        
        if (parallaxBg && parallaxMid && parallaxFront) {
            // transform: translate3d() GPU hızlandırması için
            parallaxBg.style.transform = `translate3d(0, ${scrollPosition * 0.1}px, 0)`;
            parallaxMid.style.transform = `translate3d(0, ${scrollPosition * 0.3}px, 0)`;
            parallaxFront.style.transform = `translate3d(0, ${scrollPosition * 0.5}px, 0)`;
        }
    }
}

// Animasyonları sadece görünür olduklarında çalıştır
function setupLazyAnimations() {
    const animatedElements = document.querySelectorAll('.animation-box, .animation-element, .scroll-item');
    
    // IntersectionObserver kullanarak sadece görünür öğeleri animasyonla
    const observer = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                // Öğe görünür olduğunda animasyonu başlat
                entry.target.classList.add('animate');
                
                // Animasyon tamamlandığında gözlemlemeyi durdur
                entry.target.addEventListener('animationend', () => {
                    observer.unobserve(entry.target);
                }, { once: true });
            }
        });
    }, {
        root: null,
        rootMargin: '0px',
        threshold: 0.1
    });
    
    // Tüm animasyonlu öğeleri gözlemle
    animatedElements.forEach(element => {
        observer.observe(element);
    });
}

// Sayfa yüklendiğinde optimizasyonları uygula
document.addEventListener('DOMContentLoaded', () => {
    // Animasyonları optimize et
    optimizeAnimations();
    
    // Lazy animasyonları ayarla
    setupLazyAnimations();
    
    // Throttled kaydırma olayı
    window.addEventListener('scroll', throttledScrollHandler);
});

Adım 6: Uygulamayı Test Etme

Şimdi uygulamanızı test etme zamanı! Aşağıdaki adımları izleyin:

  1. Tüm dosyaları (index.htmlstyle.cssscript.js) aynı klasöre kaydedin.
  2. HTML dosyasını bir web tarayıcısında açın.
  3. Farklı animasyon butonlarına tıklayarak temel animasyonları test edin.
  4. Sayfayı aşağı kaydırarak paralaks efektini gözlemleyin.
  5. Kaydırma animasyonlarının görünürlük alanına girdiğinde tetiklendiğini doğrulayın.
  6. Farklı ekran boyutlarında responsive tasarımı test edin.
  7. Animasyon performansını kontrol edin ve gerekirse optimize edin.

İpucu: Tarayıcınızın geliştirici araçlarını (genellikle F12 tuşu ile açılır) kullanarak animasyon performansını izleyebilirsiniz. Chrome'da "Performance" sekmesi, animasyonların kare hızını ve CPU kullanımını gösterir.

Projeyi Geliştirme

Temel animasyon efektleri uygulamasını başarıyla oluşturduktan sonra, aşağıdaki özelliklerle projenizi geliştirebilirsiniz:

1. SVG Animasyonları

SVG elementlerini animasyonlu hale getirerek daha karmaşık ve ilgi çekici görsel efektler oluşturun:

svg-animations.js
// SVG Animasyonları
// HTML'e SVG elementi ekleyin:
// <svg id="svgAnimation" width="300" height="200" viewBox="0 0 300 200">
//   <path id="path" d="M10,100 C50,50 250,150 290,100" fill="none" stroke="#2196f3" stroke-width="5"/>
//   <circle id="circle" cx="10" cy="100" r="10" fill="#f44336"/>
// </svg>

// SVG yolu boyunca hareket animasyonu
function animateAlongPath() {
    const path = document.getElementById('path');
    const circle = document.getElementById('circle');
    
    if (!path || !circle) return;
    
    // Yolun toplam uzunluğunu al
    const pathLength = path.getTotalLength();
    
    // Animasyon zamanlaması
    let start = null;
    const duration = 3000; // 3 saniye
    
    function animate(timestamp) {
        if (!start) start = timestamp;
        const progress = (timestamp - start) / duration;
        
        if (progress <= 1) {
            // Yol üzerindeki noktayı hesapla
            const point = path.getPointAtLength(pathLength * progress);
            
            // Daireyi bu noktaya taşı
            circle.setAttribute('cx', point.x);
            circle.setAttribute('cy', point.y);
            
            requestAnimationFrame(animate);
        } else {
            // Animasyonu tekrarla
            start = null;
            requestAnimationFrame(animate);
        }
    }
    
    requestAnimationFrame(animate);
}

// SVG çizim animasyonu
function animateDrawing() {
    const path = document.getElementById('path');
    
    if (!path) return;
    
    // Yolun toplam uzunluğunu al
    const pathLength = path.getTotalLength();
    
    // Başlangıçta yolu görünmez yap
    path.style.strokeDasharray = pathLength;
    path.style.strokeDashoffset = pathLength;
    
    // Çizim animasyonu
    path.style.animation = 'drawPath 2s linear forwards';
    
    // CSS keyframes ekleyin:
    // @keyframes drawPath {
    //   to {
    //     stroke-dashoffset: 0;
    //   }
    // }
}

// Morph animasyonu (şekil değiştirme)
function animateMorph() {
    const path = document.getElementById('path');
    
    if (!path) return;
    
    // Başlangıç ve bitiş yolları
    const paths = [
        "M10,100 C50,50 250,150 290,100",
        "M10,100 C50,150 250,50 290,100",
        "M10,50 C100,150 200,150 290,50",
        "M10,150 C100,50 200,50 290,150"
    ];
    
    let currentPath = 0;
    
    // Her 2 saniyede bir şekli değiştir
    setInterval(() => {
        currentPath = (currentPath + 1) % paths.length;
        
        // Yeni yolu ayarla
        path.setAttribute('d', paths[currentPath]);
    }, 2000);
}

// Sayfa yüklendiğinde SVG animasyonlarını başlat
document.addEventListener('DOMContentLoaded', () => {
    // SVG animasyon butonları
    const svgAnimationContainer = document.createElement('div');
    svgAnimationContainer.className = 'animation-header';
    svgAnimationContainer.innerHTML = `
        SVG Animasyonları
        Vektör tabanlı animasyonlar
    `;
    
    const svgElement = document.createElement('div');
    svgElement.innerHTML = `
        
            
            
        
    `;
    
    const svgControls = document.createElement('div');
    svgControls.className = 'animation-controls';
    
    const pathButton = document.createElement('button');
    pathButton.className = 'animation-btn';
    pathButton.textContent = 'Yol Animasyonu';
    pathButton.addEventListener('click', animateAlongPath);
    
    const drawButton = document.createElement('button');
    drawButton.className = 'animation-btn';
    drawButton.textContent = 'Çizim Animasyonu';
    drawButton.addEventListener('click', animateDrawing);
    
    const morphButton = document.createElement('button');
    morphButton.className = 'animation-btn';
    morphButton.textContent = 'Morph Animasyonu';
    morphButton.addEventListener('click', animateMorph);
    
    svgControls.appendChild(pathButton);
    svgControls.appendChild(drawButton);
    svgControls.appendChild(morphButton);
    
    // Animasyon konteynerine ekle
    const animationContainer = document.querySelector('.animation-container');
    if (animationContainer) {
        animationContainer.appendChild(svgAnimationContainer);
        animationContainer.appendChild(svgElement);
        animationContainer.appendChild(svgControls);
    }
    
    // CSS keyframes ekle
    const style = document.createElement('style');
    style.textContent = `
        @keyframes drawPath {
            to {
                stroke-dashoffset: 0;
            }
        }
    `;
    document.head.appendChild(style);
});

2. 3D Animasyonlar

CSS 3D dönüşümlerini kullanarak derinlik hissi veren animasyonlar ekleyin:

3d-animations.js
// 3D Animasyonlar
// HTML'e 3D konteyner ekleyin:
// <div class="animation-3d-container">
//   <div class="cube">
//     <div class="cube-face front">Ön</div>
//     <div class="cube-face back">Arka</div>
//     <div class="cube-face right">Sağ</div>
//     <div class="cube-face left">Sol</div>
//     <div class="cube-face top">Üst</div>
//     <div class="cube-face bottom">Alt</div>
//   </div>
// </div>

// CSS'e 3D stilleri ekleyin:
/*
.animation-3d-container {
    perspective: 1000px;
    width: 200px;
    height: 200px;
    margin: 0 auto;
}

.cube {
    width: 100%;
    height: 100%;
    position: relative;
    transform-style: preserve-3d;
    transform: translateZ(-100px);
    transition: transform 1s;
}

.cube-face {
    position: absolute;
    width: 200px;
    height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    font-weight: bold;
    color: white;
    border: 2px solid rgba(255, 255, 255, 0.5);
}

.front  { background: rgba(33, 150, 243, 0.8); transform: rotateY(0deg) translateZ(100px); }
.back   { background: rgba(33, 150, 243, 0.8); transform: rotateY(180deg) translateZ(100px); }
.right  { background: rgba(76, 175, 80, 0.8); transform: rotateY(90deg) translateZ(100px); }
.left   { background: rgba(76, 175, 80, 0.8); transform: rotateY(-90deg) translateZ(100px); }
.top    { background: rgba(244, 67, 54, 0.8); transform: rotateX(90deg) translateZ(100px); }
.bottom { background: rgba(244, 67, 54, 0.8); transform: rotateX(-90deg) translateZ(100px); }
*/

// 3D küp animasyonu
function animateCube() {
    const cube = document.querySelector('.cube');
    
    if (!cube) return;
    
    // Küpü farklı yönlere döndür
    const rotations = [
        'rotateY(0deg)',
        'rotateY(90deg)',
        'rotateY(180deg)',
        'rotateY(270deg)',
        'rotateX(90deg)',
        'rotateX(-90deg)'
    ];
    
    let currentRotation = 0;
    
    // Her 2 saniyede bir küpü döndür
    setInterval(() => {
        currentRotation = (currentRotation + 1) % rotations.length;
        cube.style.transform = `translateZ(-100px) ${rotations[currentRotation]}`;
    }, 2000);
}

// 3D küpü fare ile döndürme
function setupCubeInteraction() {
    const cube = document.querySelector('.cube');
    const container = document.querySelector('.animation-3d-container');
    
    if (!cube || !container) return;
    
    let isDragging = false;
    let previousX = 0;
    let previousY = 0;
    let rotationX = 0;
    let rotationY = 0;
    
    // Fare olayları
    container.addEventListener('mousedown', (e) => {
        isDragging = true;
        previousX = e.clientX;
        previousY = e.clientY;
        e.preventDefault();
    });
    
    window.addEventListener('mouseup', () => {
        isDragging = false;
    });
    
    window.addEventListener('mousemove', (e) => {
        if (isDragging) {
            const deltaX = e.clientX - previousX;
            const deltaY = e.clientY - previousY;
            
            rotationY += deltaX * 0.5;
            rotationX -= deltaY * 0.5;
            
            cube.style.transform = `translateZ(-100px) rotateX(${rotationX}deg) rotateY(${rotationY}deg)`;
            
            previousX = e.clientX;
            previousY = e.clientY;
        }
    });
    
    // Dokunmatik olaylar
    container.addEventListener('touchstart', (e) => {
        isDragging = true;
        previousX = e.touches[0].clientX;
        previousY = e.touches[0].clientY;
        e.preventDefault();
    });
    
    window.addEventListener('touchend', () => {
        isDragging = false;
    });
    
    window.addEventListener('touchmove', (e) => {
        if (isDragging) {
            const deltaX = e.touches[0].clientX - previousX;
            const deltaY = e.touches[0].clientY - previousY;
            
            rotationY += deltaX * 0.5;
            rotationX -= deltaY * 0.5;
            
            cube.style.transform = `translateZ(-100px) rotateX(${rotationX}deg) rotateY(${rotationY}deg)`;
            
            previousX = e.touches[0].clientX;
            previousY = e.touches[0].clientY;
        }
    });
}

// Sayfa yüklendiğinde 3D animasyonları ayarla
document.addEventListener('DOMContentLoaded', () => {
    // 3D animasyon başlığı
    const animation3dHeader = document.createElement('div');
    animation3dHeader.className = 'animation-header';
    animation3dHeader.innerHTML = `
        3D Animasyonlar
        CSS 3D dönüşümleri ile derinlik efektleri
    `;
    
    // 3D küp konteyner
    const animation3dContainer = document.createElement('div');
    animation3dContainer.className = 'animation-3d-container';
    animation3dContainer.innerHTML = `
        
            Ön
            Arka
            Sağ
            Sol
            Üst
            Alt
        
    `;
    
    // 3D kontrol butonları
    const animation3dControls = document.createElement('div');
    animation3dControls.className = 'animation-controls';
    
    const autoRotateButton = document.createElement('button');
    autoRotateButton.className = 'animation-btn';
    autoRotateButton.textContent = 'Otomatik Döndür';
    autoRotateButton.addEventListener('click', animateCube);
    
    const interactiveButton = document.createElement('button');
    interactiveButton.className = 'animation-btn';
    interactiveButton.textContent = 'Etkileşimli Mod';
    interactiveButton.addEventListener('click', setupCubeInteraction);
    
    animation3dControls.appendChild(autoRotateButton);
    animation3dControls.appendChild(interactiveButton);
    
    // Animasyon konteynerine ekle
    const animationContainer = document.querySelector('.animation-container');
    if (animationContainer) {
        animationContainer.appendChild(animation3dHeader);
        animationContainer.appendChild(animation3dContainer);
        animationContainer.appendChild(animation3dControls);
    }
    
    // CSS stilleri ekle
    const style = document.createElement('style');
    style.textContent = `
        .animation-3d-container {
            perspective: 1000px;
            width: 200px;
            height: 200px;
            margin: 0 auto 50px;
        }
        
        .cube {
            width: 100%;
            height: 100%;
            position: relative;
            transform-style: preserve-3d;
            transform: translateZ(-100px);
            transition: transform 1s;
        }
        
        .cube-face {
            position: absolute;
            width: 200px;
            height: 200px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 2rem;
            font-weight: bold;
            color: white;
            border: 2px solid rgba(255, 255, 255, 0.5);
        }
        
        .front  { background: rgba(33, 150, 243, 0.8); transform: rotateY(0deg) translateZ(100px); }
        .back   { background: rgba(33, 150, 243, 0.8); transform: rotateY(180deg) translateZ(100px); }
        .right  { background: rgba(76, 175, 80, 0.8); transform: rotateY(90deg) translateZ(100px); }
        .left   { background: rgba(76, 175, 80, 0.8); transform: rotateY(-90deg) translateZ(100px); }
        .top    { background: rgba(244, 67, 54, 0.8); transform: rotateX(90deg) translateZ(100px); }
        .bottom { background: rgba(244, 67, 54, 0.8); transform: rotateX(-90deg) translateZ(100px); }
    `;
    document.head.appendChild(style);
});

Geliştirme Zorlukları

Animasyon efektleri uygulamanızı daha da geliştirmek için aşağıdaki zorlukları deneyebilirsiniz:

  1. Animasyon Editörü: Kullanıcıların kendi animasyonlarını oluşturabileceği basit bir editör ekleyin.
  2. Fizik Tabanlı Animasyonlar: Yerçekimi, çarpışma ve yaylanma gibi fizik kurallarını simüle eden animasyonlar ekleyin.
  3. Animasyon Sekansları: Birden fazla animasyonu sırayla veya paralel olarak çalıştırabilen bir sekans sistemi oluşturun.
  4. Ses Efektleri: Animasyonlara uygun ses efektleri ekleyin.
  5. Animasyon Kütüphanesi: Kullanıcıların seçebileceği hazır animasyon koleksiyonu oluşturun.

Sonuç ve Öğrenilen Dersler

Bu projede, CSS ve JavaScript kullanarak çeşitli animasyon efektleri oluşturduk. Bu süreçte şunları öğrendik:

  • CSS animasyonlarının temellerini ve keyframes kullanımını
  • JavaScript ile animasyonları kontrol etmeyi
  • Zamanlama fonksiyonlarını ve animasyon özelliklerini
  • Paralaks kaydırma efektleri oluşturmayı
  • Animasyon performansını optimize etmeyi
  • Kullanıcı etkileşimine dayalı animasyonlar eklemeyi
  • Responsive tasarımda animasyonları uyarlamayı
  • SVG ve 3D animasyonlar gibi gelişmiş teknikleri

Bu proje, web sayfalarınıza canlılık katmak ve kullanıcı deneyimini geliştirmek için animasyonları nasıl etkili bir şekilde kullanabileceğinizi göstermiştir. Öğrendiğiniz teknikleri ve kavramları kullanarak, daha karmaşık ve etkileyici animasyonlar oluşturabilir, kullanıcı deneyimini zenginleştirebilirsiniz.