İsimsiz Uygulama
Açıklama yok
DNA Origami Tasarım Stüdyosu
1 Veri Yapıları ve Algoritma
Bu teknik neden seçildi?
DNA çift sarmalını temsil etmek için iki ayrı nokta dizisi (strand1, strand2) kullandım. Her dizi, { x, y, t, angle } nesneleri içeriyor. Bu yaklaşım, sarmalın her iki ipliğini bağımsız olarak hesaplamayı ve baz çiftlerini (A-T, G-C) renklendirmeyi kolaylaştırıyor. Ayrıca time değişkeni ile sinüs/kosinüs dalgalarını faz kaydırarak sürekli bir animasyon elde ettim.
Algoritma özeti: 160 nokta üzerinden t = i / points parametresi ile sarmal açısı hesaplanır. İki iplik π radyan faz farkıyla konumlandırılır. Bağlantı çizgileri her 2 adımda bir çizilir; nükleotidler her 3 adımda bir renklendirilir.
Hangi alternatifler mümkündü?
- 3D vektör matematiği:
THREE.jsolmadan manuel 3D projeksiyon ile daha derinlikli görünüm sağlanabilirdi — ancak performans maliyeti artardı. - Parçacık sistemi: Her nükleotidi ayrı bir parçacık olarak yönetmek, daha organik bir görünüm verir; fakat baz çifti bağlarını takip etmek zorlaşır.
- Bezier eğrileri: Sarmal yerine yumuşak spline'lar kullanılabilirdi; ama DNA'nın karakteristik burgu şekli kaybolurdu.
Gelecekte nasıl geliştirilebilir?
Nokta dizileri yerine typed array (Float32Array) kullanılarak bellek ve CPU tasarrufu sağlanabilir. Ayrıca her nükleotit için bir Uint8Array renk indeksi tutulabilir. WebGL'e geçiş yapılırsa, vertex shader içinde sarmal denklemi hesaplanarak CPU yükü sıfıra indirilebilir.
// Mevcut nokta üretimi
for (let i = 0; i <= points; i++) {
const t = i / points;
const angle = t * Math.PI * 2 * turns + offset;
strand1.push({
x: centerX + Math.cos(angle) * amp + pointerOffsetX,
y: centerY + (t - 0.5) * h * 0.6 + Math.sin(angle) * amp * 0.45
});
}
// Alternatif: Float32Array ile
const positions = new Float32Array(points * 2);
for (let i = 0; i < points; i++) {
positions[i*2] = ...; // x
positions[i*2+1] = ...; // y
}
2 Performans Kararları
Bu teknik neden seçildi?
Her karede tüm sarmal noktalarını yeniden hesaplamak yerine, delta-time tabanlı bir animasyon döngüsü kullandım. requestAnimationFrame ile 60 FPS hedeflenir; visibilitychange olayı ile sekme arka plana atıldığında döngü durdurulur. Canvas boyutlandırması ResizeObserver ile yapılır ve devicePixelRatio hesaba katılarak retina ekranlarda keskin görüntü sağlanır.
Kritik optimizasyon: ctx.shadowBlur yalnızca nokta çizimlerinde aktif edilir ve sonra sıfırlanır. Gölge efektleri GPU'yu yorduğu için çizgi çizimlerinde kullanılmaz.
Hangi alternatifler mümkündü?
- OffscreenCanvas: Arka planda çizim yapıp ana thread'i serbest bırakmak mümkündü; ancak tarayıcı desteği hâlâ sınırlı.
- Web Workers: Nokta hesaplamaları worker'a taşınabilirdi; fakat canvas çizimi ana thread'de kalmak zorunda.
- Statik önbellek: Değişmeyen arka plan yıldızları bir kez çizilip
drawImageile kopyalanabilirdi; bu, her karede 70 yıldız çiziminden tasarruf sağlardı.
Gelecekte nasıl geliştirilebilir?
Çizim katmanları ayrılabilir: arka plan, sarmal gövdesi ve nükleotidler ayrı OffscreenCanvas nesnelerinde tutulabilir. Ayrıca willReadFrequently bayrağı ile canvas context'i optimize edilebilir. WebGL'e geçiş, özellikle mobil cihazlarda büyük kazanç sağlar.
// Delta-time animasyon
let lastTimestamp = 0;
function draw(timestamp) {
const delta = Math.min(0.05, (timestamp - lastTimestamp) / 1000);
lastTimestamp = timestamp;
time += delta * speed * 2.2;
animationFrame = requestAnimationFrame(draw);
}
// OffscreenCanvas alternatifi
const offscreen = new OffscreenCanvas(w, h);
const octx = offscreen.getContext('2d');
// arka planı bir kez çiz, sonra kopyala
ctx.drawImage(offscreen, 0, 0);
3 Tasarım ve Renk Mimarisi
Bu teknik neden seçildi?
Uzay teması için koyu mor-lacivert arka plan (#0b0715) seçildi. DNA iplikleri için #b78aff (mor) ve #5fd9ff (cyan) kullanıldı — bunlar hem birbirinden ayrışır hem de koyu zeminde parlak görünür. Nükleotid renkleri (A, T, G, C) biyolojik çağrışımlardan bağımsız olarak yüksek kontrastlı tonlardan seçildi: pembe, yeşil, turuncu, mavi.
Erişilebilirlik notu: Renk körlüğü için her nükleotid farklı parlaklık seviyesine sahiptir. Ayrıca nokta boyutları hafifçe farklılaştırılarak şekil ayrımı güçlendirilmiştir.
Hangi alternatifler mümkündü?
- Monokrom şema: Tüm sarmal tek renk olabilirdi; ama nükleotid çeşitliliği kaybolurdu.
- Neon palet: Daha canlı renkler (saf #FF00FF gibi) kullanılabilirdi; ancak göz yorgunluğu yaratır.
- HSL döngüsü: Renkler zamanla değişebilirdi; fakat biyolojik kimlik hissi zayıflar.
Gelecekte nasıl geliştirilebilir?
CSS color-mix() fonksiyonu ile dinamik renk geçişleri yapılabilir. Kullanıcı tercihine göre yüksek kontrast modu eklenebilir. Ayrıca prefers-reduced-motion sorgusu ile animasyon hızı sıfıra indirilebilir.
/* CSS renk değişkenleri */
:root {
--nucleotide-a: #ff5e8a;
--nucleotide-t: #3cd6a0;
--nucleotide-g: #ffb347;
--nucleotide-c: #5fa8ff;
}
/* Yüksek kontrast modu */
@media (prefers-contrast: more) {
:root {
--bg-deep: #000000;
--helix-a: #ffffff;
--helix-b: #ffff00;
}
}
4 Anti-Pattern Uyarıları
Bu teknik neden seçildi?
Uygulamada bilinçli olarak kaçınılan bazı anti-pattern'ler var. Örneğin: global değişken kirliliği yok (IIFE içinde), setInterval kullanılmadı (requestAnimationFrame tercih edildi), DOM sürekli güncellenmiyor (sadece slider değerleri). Ayrıca eval, innerHTML ile kullanıcı verisi yazma gibi tehlikeli pratiklerden kaçınıldı.
Dikkat: Canvas boyutlandırmada canvas.width = rect.width * dpr yapılırken ctx.scale(dpr, dpr) çağrısı unutulursa bulanık görüntü oluşur. Bu, yaygın bir hatadır.
Hangi alternatifler mümkündü?
- React/Vue kullanımı: Sanal DOM ile state yönetimi kolaylaşırdı; ancak tek dosya kısıtı ve harici bağımlılık yasağı nedeniyle tercih edilmedi.
- Global değişkenler: Daha kısa kod yazılabilirdi; fakat çakışma riski ve test edilebilirlik azalırdı.
- CSS animasyonları: Sarmal tamamen CSS ile çizilemezdi; Canvas zorunluydu.
Gelecekte nasıl geliştirilebilir?
ES modülleri kullanılarak kod parçalara ayrılabilir. TypeScript ile tip güvenliği sağlanabilir. Ayrıca birim testler için Jest + jsdom eklenebilir; fakat bu, tek dosya felsefesini bozar.
// Anti-pattern: setInterval ile animasyon
setInterval(() => { draw(); }, 16); // KÖTÜ
// Doğru: requestAnimationFrame
function loop(ts) {
draw(ts);
requestAnimationFrame(loop); // İYİ
}
// Anti-pattern: ctx.scale'i her karede çağırmak
// Doğru: bir kez resize'da çağır
function resize() {
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.scale(dpr, dpr);
}
5 Alternatif Yaklaşımlar ve Geliştirme Önerileri
Bu teknik neden seçildi?
Canvas 2D, Web Audio API ile doğrudan entegre edilebilir ve tek dosya içinde tüm işlevselliği sunar. Ses sentezleme için OscillatorNode + BiquadFilterNode kombinasyonu kullanıldı; bu, düşük gecikmeli ve esnek bir yapı sağlar. Kullanıcı etkileşimi (pointer konumu) hem görsel hem işitsel parametreleri modüle eder.
Gelecek fikir: MIDI desteği eklenerek harici klavye ile notalar tetiklenebilir. Ayrıca AudioWorklet ile özel DSP algoritmaları yazılabilir.
Hangi alternatifler mümkündü?
- WebGL + Three.js: 3D DNA modeli ve post-processing efektleri; ancak harici kütüphane yasağı.
- WebGPU: Gelecekte canvas 2D'nin yerini alabilir; şu an deneysel.
- SVG animasyonu: Vektörel çizim avantajı; fakat performans sınırlı.
- Web Audio API yerine
<audio>elementi: Hazır ses dosyaları gerekir; sentezleme yapılamaz.
Gelecekte nasıl geliştirilebilir?
Uygulama PWA'ya dönüştürülerek çevrimdışı çalışabilir. Ses kaydı özelliği (MediaRecorder) eklenebilir. Kullanıcıların kendi DNA dizilimlerini girmesi için bir arayüz tasarlanabilir. Ayrıca Web MIDI API ve Gamepad API ile alternatif kontrol yöntemleri sunulabilir.
// Web Audio API zinciri
oscillator = audioCtx.createOscillator();
filter = audioCtx.createBiquadFilter();
gainNode = audioCtx.createGain();
oscillator.type = 'sawtooth';
filter.type = 'lowpass';
filter.Q.value = resonance;
oscillator.connect(filter);
filter.connect(gainNode);
gainNode.connect(audioCtx.destination);
oscillator.start();
// AudioWorklet alternatifi
await audioCtx.audioWorklet.addModule('processor.js');
const workletNode = new AudioWorkletNode(audioCtx, 'dna-processor');