Mimari Özeti
Uygulama, tek bir preview.html içinde Three.js sahnesi kurar ve bildirim kartlarını
dikey eksende uzanan bir sinüs/spiral hattı boyunca konumlandırır. Bu sayfa
(preview.html) ise aynı sahneyi mobil bir cihaz çerçevesi içinde
<iframe> ile önizleme olarak sunar.
Demo; scrollOffset ve amplitude parametreleri üzerinden sırayla dikey kaydırma ve spiral genişliğini kontrol eder.
Spiral Konumlandırma Mantığı
Her kart için dikey eksen y indekse göre artar, yatay sapma ve derinlik ise sinüs
tabanlı bir spiral fonksiyonla hesaplanır:
// preview.html içindeki mantığın özeti
const y = index * VERTICAL_SPACING - scrollOffset;
const angle = y * FREQUENCY;
const radiusX = amplitude;
const radiusZ = amplitude * 0.5;
const x = Math.sin(angle) * radiusX;
const z = Math.cos(angle) * radiusZ;
mesh.position.set(x, y, z);
Böylece kartlar, alt tarafta birbirine yakın ve perspektiften dolayı daha dar, yukarı doğru çıktıkça ekranın üst kısmında daha geniş bir spiral izler.
Derinlik Hissi & Ölçek Animasyonu
Kartların boyutu, ekranın altından üstüne doğru hareket ederken konumlarına bağlı olarak dinamik değişir. Bu sayede kartlar “geriden gelip büyüyormuş” gibi bir derinlik hissi verir.
// Dikey konuma göre ölçekleme ve hafif wobble
const t = THREE.MathUtils.clamp((y + 4) / 16, 0, 1);
const depthScale = 0.1 + 0.8 * t;
const wobble = Math.sin(time * 0.002 + index * 0.35) * 0.04;
const baseScale = targetScale * depthScale;
currentScale += (baseScale + wobble - currentScale) * 0.15;
mesh.scale.set(currentScale, currentScale, 1.0);
depthScale altta ~0.1, üstte ise yaklaşık 0.9–1.0 arasında değişir.
wobble parametresi küçük bir salınım ekleyerek sahneyi canlı tutar.
Etkileşim: Dikey Sürükleme & Pinch Zoom
Fare ile sol tuş basılı iken yukarı–aşağı sürükleme veya tek parmakla dikey kaydırma,
spiral boyunca scrollOffset değerini değiştirir:
const SCROLL_SENSITIVITY = 0.02;
scrollOffset = THREE.MathUtils.clamp(
scrollOffset + deltaY * SCROLL_SENSITIVITY,
0,
MAX_SCROLL
);
İki parmak pinch hareketi veya mouse wheel, spiral genişliğini belirleyen
amplitude değerini kontrol eder. En dar durumda tüm kartlar ekranın alt
merkezinde üst üste biner gibi görünüp, zoom yaptıkça üst tarafta genişleyen bir sinüs
dalgasına dönüşür.
// Amplitude güncelleme (wheel / pinch)
amplitude = THREE.MathUtils.clamp(
amplitude * scaleOrDelta,
MIN_AMPLITUDE,
MAX_AMPLITUDE
);
Dummy Kart JSON Verisi
Kartlar, 50 öğelik basit bir JSON dizisinden üretilir ve her kartın rengi
hue alanı ile HSL tabanlı olarak atanır:
// preview.html içinde kullanılan dummy veri
const cardData = Array.from({ length: 50 }).map((_, i) => ({
id: i + 1,
title: `Bildirim #${i + 1}`,
subtitle: `Kategori ${(i % 5) + 1}`,
message: `Bu, ${i + 1}. deneme bildirimi. JSON dummy data ile oluşturuldu.`,
hue: (i / 50) * 0.9
}));
Bu yapı, ileride gerçek API verisine bağlanmak için kolayca genişletilebilir; sadece
cardData kaynağı değiştirilerek aynı geometri ve etkileşim korunur.
Three.js Kurulumu & Sahne
Demo, harici bir bundler ihtiyacı olmadan, doğrudan tarayıcıda ES module ile Three.js import eder:
<script type="module">
import * as THREE from
'https://unpkg.com/three@0.161.0/build/three.module.js';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
50,
window.innerWidth / window.innerHeight,
0.1,
100
);
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
</script>
Kamera hafifçe aşağıdan yukarı bakan bir açıya yerleştirilir; böylece spiral, ekranda “yukarı doğru çıkan” bir çizgi gibi algılanır.
Geliştirici Notları
Bu demo, konsept tasarım ve etkileşim prototipi olarak düşünülmüştür. Üretim ortamı için; performans optimizasyonu, kart içeriklerinin dinamik olarak doldurulması (örneğin bildirim API'lerinden) ve erişilebilirlik (odak yönetimi, ekran okuyucu metinleri vb.) gibi ek katmanlar rahatlıkla üzerine inşa edilebilir.
Geliştirici notları · Halit YEŞİL · halityesil.com