HTML5+JS
Efektler, bir HTML5 canvas öğesi üzerinde saf JavaScript kullanılarak oluşturulur. Bu bölümde temel konuları ele alacağız: şekil çizimi, yinelemeyle çizim ve hareket ekleme.
Şekil Çizimi
Section titled “Şekil Çizimi”Bu eğitim için genel bir lightscript şablonu kullanacağım:
<head> <meta description="Template"/> <meta publisher="WhirlwindFX" /></head>
<body style="margin: 0; padding: 0;"> <canvas id="exCanvas" width="320" height="200"></canvas></body>
<script> // Get the canvas element from the DOM var c = document.getElementById("exCanvas"); var ctx = c.getContext("2d");
var width = 320; var height = 200; var hue = 0;
function update() { // Code goes here window.requestAnimationFrame(update); }
window.requestAnimationFrame(update);</script>Çizgiler
Section titled “Çizgiler”Tek bir çizgi veya birçok çizgi kullanırken süreç aynı kalır.
- ctx.beginPath() şeklinizi başlatır
- ctx.moveTo(x, y) ilk noktayı ayarlar
- ctx.lineTo(x, y) bir sonraki noktayı ve ilk noktaya geri dönüş çizgisini ayarlar. Daha büyük şekiller çizmek için birden fazla lineTo kullanın.
- ctx.strokeStyle ve/veya ctx.fillStyle ayarlayın (şekil kapalıysa)
- Çizgileri çizmek için ctx.stroke() ve kapalı şekilleri doldurmak için ctx.fill() kullanın. Bu noktaya kadar her şeyin varsayımsal olduğunu belirtmek önemlidir — bu komutlar yürütülene kadar hiçbir şey çizilmez.
Çizgiler kullanan üç örnek:
function update() { // Tek Çizgi ctx.beginPath(); ctx.moveTo(30, 30); ctx.lineTo(30, 170); ctx.strokeStyle = "blue"; ctx.stroke();
// L ctx.beginPath(); ctx.moveTo(80, 30); ctx.lineTo(80, 100); ctx.lineTo(120, 100); ctx.strokeStyle = "blue"; ctx.stroke();
// Dolu Üçgen ctx.beginPath(); ctx.moveTo(130, 30); ctx.lineTo(130, 100); ctx.lineTo(170, 100); ctx.lineTo(130, 30); ctx.fillStyle = "red"; ctx.strokeStyle = "blue"; ctx.fill(); ctx.stroke();
window.requestAnimationFrame(update);}
Burada çizim sırasına dikkat etmek önemlidir: dolu üçgen en son çizilir, dolayısıyla aynı konumda olsaydı diğer iki şekli kaplardı. Ayrıca üçgendeki kontur, dolgudan sonra çizilir. Bu adımları ters çevirseydik, kontürun iç yarısı kırmızı dolgu tarafından kaplanırdı.
Dikdörtgenler
Section titled “Dikdörtgenler”Dikdörtgenler basit ve kullanışlıdır; özellikle RGB klavyenin ortalama çözünürlüğü için idealdir. Süreç çizgi çizmeye benzerdir — yalnızca moveTo ve lineTo komutlarını rect(x, y, genişlik, yükseklik) ile değiştirin.
function update() { // Temel Kare ctx.beginPath(); ctx.rect(30, 30, 75, 75); ctx.strokeStyle = "blue"; ctx.stroke();
// Dolu Dikdörtgen ctx.beginPath(); ctx.rect(125, 30, 125, 100); ctx.fillStyle = "red"; ctx.strokeStyle = "blue"; ctx.fill(); ctx.stroke();
window.requestAnimationFrame(update); }
Yaylar
Section titled “Yaylar”Yaylar, bir dış noktanın merkez nokta etrafında döndürülmesiyle çizilir ve tam daireler oluşturmak için kullanılabilir. Yay komutu ctx.arc(x, y, yarıçap, başlangıç açısı, bitiş açısı)‘dır; her iki açı ölçümü radyan cinsinden verilir. Dikdörtgenlerin aksine, bir yay kaynağı (x, y) yayın merkezinde olacak şekilde çizilir.
function update() { // Yarım daire ctx.beginPath(); ctx.arc(70, 100, 30, 0, Math.PI); ctx.strokeStyle = "blue"; ctx.stroke();
// 3/4 daire ctx.beginPath(); ctx.arc(140, 100, 30, 0, Math.PI * (3/2)); ctx.strokeStyle = "blue"; ctx.stroke();
// Tam daire ctx.beginPath(); ctx.arc(210, 100, 30, 0, Math.PI * 2); ctx.strokeStyle = "blue"; ctx.stroke(); ctx.fillStyle = "red"; ctx.fill();
window.requestAnimationFrame(update); }
Gördüğünüz gibi yaylar varsayılan olarak saat yönünde çizilir. Bu, başlangıç açısından küçük bir bitiş açısıyla veya ctx.arc() yöntemine son bağımsız değişken olarak “true” eklenerek tersine çevrilebilir.
Yinelemeyle Çizim
Section titled “Yinelemeyle Çizim”Üç şekli elle çizmek kolayca yirmi satır kod alabilir; dolayısıyla yüz şekil çizmeniz gerekiyorsa daha verimli bir yaklaşıma ihtiyaç vardır. JavaScript’teki döngüler görevleri tekrarlamanın basit bir yoludur ve çizime de uygulanabilir.
Bir satır kareli kare çizmek için for döngüsü kullanan bir örnek:
function update() {
for(let i = 0; i < 8; i++){
// 1. Her biri için dikdörtgen yolu oluştur ve konturunu çiz. ctx.beginPath(); ctx.rect(i * 20, 20, 20, 20); ctx.strokeStyle = "black"; ctx.stroke();
// 2. 'i' çiftse, fillStyle siyah. Aksi takdirde beyaz. if(i % 2 == 0){ ctx.fillStyle = "black"; } else { ctx.fillStyle = "white"; } // 3. fillStyle ayarlandıktan sonra şekli doldur. ctx.fill(); }
window.requestAnimationFrame(update); }
Kareli bir ızgara çizmek için while döngüsü örneği. Şablon değişmezlerini kullanarak her yinelemede siyah karelerin açıklığını ve beyaz karelerin renk tonunu biraz değiştireceğim.
function update() {
var i = 0;
while(i < 16){
// 1. 'satır' ve 'sütun' ile X ve Y hesaplamaları // Bu işlem sonucu aşağıya en yakın tam sayıya yuvarlar. i = (0-3) için satır 0, i = (4-7) için satır 1 olacak vb. var iRow = Math.floor(i / 4); // Bu işlem bölme sonrasındaki kalanı bulur, sütunu (0-3) aralığıyla sınırlar. var iCol = i % 4; // Bu karenin x-kaynağını bulmak için kare genişliğiyle çarp var ix = iCol * 20; // Bu karenin y-kaynağını bulmak için kare yüksekliğiyle çarp var iy = iRow * 20;
// 2. Yol ve kontur ctx.beginPath(); ctx.rect(ix, iy, 20, 20); ctx.strokeStyle = "black"; ctx.stroke();
// 3. Satır çiftse her ikinci kare siyah doldurulur. Tekse siyah kareler değiştirilir. // Her yinelemede siyaha küçük miktarda açıklık bileşeni ve beyaza renk tonu eklenir. if(iRow % 2 == 0){ if(i % 2 == 0){ // 'Siyah' ctx.fillStyle = `hsl(1, 0%, ${5 * i}%)` } else { // 'Beyaz' ctx.fillStyle = `hsl(${10 * i}, 100%, 50%)`; } } else { if(i % 2 == 0){ // 'Beyaz' ctx.fillStyle = `hsl(${10 * i}, 100%, 50%)`; } else { // 'Siyah' ctx.fillStyle = `hsl(1, 0%, ${5 * i}%)` } }
ctx.fill(); i++; }
window.requestAnimationFrame(update); }
Hareket Ekleme
Section titled “Hareket Ekleme”Canvas’taki animasyonlar yalnızca hayal gücünüz ve matematiksel bilginizle sınırlıdır. Trigonometri veya geometri konusunda kendinizi güvensiz hissediyorsanız becerilerinizi bir üst seviyeye taşımak için biraz araştırma yapmanızı öneririm. Sonraki birkaç örnekte sabit bir daire alacak ve her olası değişkeni basit bir salınan harekete bağlayacağım.
Salınım (düzenli ileri-geri hareket) için altın standart, bir zamanlayıcının sin() veya kosinüs()‘ünü almaktır. Her iki işlem de, yalnızca yukarı sayıyor olsa bile, aktarılan HERHANGİ bir değer için -1 ile 1 arasında bir değer döndürür. İkisi arasındaki tek fark hafifçe senkronize olmamalarıdır — cos 0 olduğunda sin -1 veya 1’dir ve tam tersi. Bunu bu animasyonda avantajımıza kullanabiliriz —
function update() {
// Milisaniye cinsinden geçerli zamanı bul, ardından animasyon hızını yavaşlatmak için böl let time = Date.now() / 100;
// Eski şekiller kalmasın diye arka plan çiz ctx.fillStyle = "white"; ctx.fillRect(0, 0, 320,200);
ctx.beginPath();
// BİR ÖRNEK KULLANIN // 1. örnek - sağa sola, y sabit ctx.arc(15 * Math.cos(time) + 160, 100, 30, 0, Math.PI * 2); // 2. örnek - yukarı aşağı, x sabit ctx.arc(160, 15 * Math.sin(time) + 100, 30, 0, Math.PI * 2); // 3. örnek - daire, x ve y değişken ctx.arc(15 * Math.cos(time) + 160, 15 * Math.sin(time) + 100, 30, 0, Math.PI * 2);
ctx.fillStyle = "black"; ctx.fill();
window.requestAnimationFrame(update); }Sağa-Sola
Section titled “Sağa-Sola”
Yukarı-Aşağı
Section titled “Yukarı-Aşağı”
Tam Daire
Section titled “Tam Daire”
Zaman içinde değiştirilecek yalnızca birkaç özellik kaldı — daire yarıçapı, dolgu ve kontur. Şekli basit tutmak için yay açılarını şimdilik olduğu gibi bırakacağım çünkü gerisi oldukça gösterişli olacak.
function update() {
let time = Date.now() / 100;
ctx.fillStyle = "white"; ctx.fillRect(0, 0, 320,200);
ctx.beginPath(); ctx.arc(15 * Math.cos(time) + 160, 15 * Math.sin(time) + 100, 30 + 15 * Math.sin(time), 0, Math.PI * 2);
ctx.fillStyle = `hsl(${180 + 180 * Math.cos(time)}, 100%, 50%)`; ctx.fill();
ctx.strokeStyle = `hsl(${180 + 180 * Math.sin(time)}, 100%, 50%)`; ctx.stroke();
window.requestAnimationFrame(update); }
Şimdiye kadar oluşturduğumuz her şeklin her özelliği zaman içinde değiştirilebilir ve yaptığım her animasyon yukarıdaki becerilerin bir kombinasyonudur. Yeniden kullanılabilir, verimli animasyonlar oluşturma hakkında daha fazla ayrıntı için Callbacks sayfamıza göz atın!