Di bab ini Kamu akan memulai dengan JavaScript untuk animasi! Kita akan lihat bagaimana cara membuat animasi yang berjalan secara berulang atau harus berhenti saat poin tertentu.
-
Fungsi
setInterval()
memulai aksi berulang dan dipanggil pada rentang tertentu. FungsiclearInterval()
memberhentikan aksi berulang yang diluncurkan olehsetInterval()
. -
Fungsi
setTimeout()
mengeksekusi aksi sekali setelah jeda tertentu. -
Fungsi
requestAnimationFrame()
meminta browser untuk mengeksekusi satu fungsi yang mengupdate animasi secepat mungkin. Hal ini cocok diterapkan untuk animasi real-time. FungsicancelAnimationFrame()
memberhentikan animasi yang sedang berlangsung yang diluncurkan olehrequestAnimationFrame()
. -
Kamu juga bisa membuat animasi web dengan CSS.
Mari kita mulai dengan animasi dengan belajar bagaimana cara memodifikasi konten elemen secara berulang. Berikut kode HTML-nya.
<h1 id="title">This page will self-destruct in <span id="counter">10</span> second(s)...</h1>
Berikut kode JavaScript-nya.
// Hitung mundur
const decreaseCounter = () => {
// Mengkonversi teks counter ke angka
const counter = Number(counterElement.textContent);
// Mengurangi penghitung 1 angka
counterElement.textContent = counter - 1;
};
const counterElement = document.getElementById("counter");
// Call the decreaseCounter function every second (1000 milliseconds)
setInterval(decreaseCounter, 1000);
Klik di sini untuk bisa melihatnya secara langsung. Program ini bekerja dengan semestinya.. Counter-nya tidak pernah berhenti. Kita akan memperbaikinya nanti.
Bagaimana contoh sebelumnya bisa bekerja? Kode JavaScript mendefinisikan fungsi bernama decreaseCounter()
yang mengakses dan mengurangi nilai satu per satu nilai elemen HTML bernama counter
.
Memanggil
Number()
di dalam kode fungi adalah wajib: fungsi ini mengkonversi string counter menjadi angka, yang berfungsi untuk mengurangi nilai.
Pemanggilan setInterval()
memicu perulangan aksi. Fungsi ini memungkinkan Kamu untuk memanggil fungsi pada regular interval. Parameternya adalah fungsi untuk memanggil dan waktu pemanggilan dalam millisecond diantara setiap panggilan. Nilai yang dikembalikan adalah ID untuk perulangan aksi, yang bisa digunakan untuk dimodifikasi nantinya.
// Mengatur aksi berulang
const intervalId = setInterval(callbackFunction, timeBetweenEachCall);
Mari kita coba untuk menghentikan counter saat perhitungan mundur selesai. Kita juga akan memodifikasi teks di halaman. Berikut ini kode JavaScript di contoh kita, di update untuk memproduksi hasil yang diinginkan:
// Hitung mundur counter sampai 0
const decreaseCounter = () => {
// Mengubah teks counter ke angka
const counter = Number(counterElement.textContent);
if (counter > 1) {
// Mengurangi counter dengan 1
counterElement.textContent = counter - 1;
}
else {
// Membatalkan eksekusi berulang
clearInterval(intervalId);
// Modifikasi judul halaman
const title = document.getElementById("title");
title.textContent = "BOOM!!";
}
};
const counterElement = document.getElementById("counter");
// Memanggil fungsi decreaseCounter setiap detik (1000 millisecond)
const intervalId = setInterval(decreaseCounter, 1000);
Klik di sini untuk melihat lebih lanjut.
Pada fungsi decreaseCounter()
, kita hanya mengurangi counter jika nilai saat ini lebih tinggi dari 1. Jika tidak, kita memanggil fungsi clearInterval()
, lalu memodifikasi judul halaman.
Fungsi clearInterval()
memungkinkan Kamu memotong eksekusi kode berulang. Fungsi ini mengambil ID aksi sebagai parameter yang di set oleh panggilan ke setInterval()
.
// Membatalkan aksi berulang yang di set dengan setInterval()
clearInterval(intervalId);
Bayangkan ketika Kamu ingin memodifikasi teks halaman setelah "ledakan" di contoh sebelumnya. Kamu akan memodifikasi contoh tersebut sebagai berikut:
// Menghitung mundur sampai dengan 0
const decreaseCounter = () => {
// Mengkonversi teks counter ke angka
const counter = Number(counterElement.textContent);
if (counter > 1) {
// Mengurangi counter dengan 1
counterElement.textContent = counter - 1;
}
else {
// Membatalkan eksekusi yang berulang
clearInterval(intervalId);
// Modifikasi judul halaman
const titleElement = document.getElementById("title");
titleElement.textContent = "BOOM!!";
// Modifikasi judul setelah 2 detik
setTimeout(() => {
titleElement.textContent = "Everything's broken now :(";
}, 2000);
}
};
const counterElement = document.getElementById("counter");
// Memanggil fungsi decreaseCounter setiap detik (1000 milliseconds)
const intervalId = setInterval(decreaseCounter, 1000);
Klik di sini untuk lihat contohnya secara langsung.
Ketika perhitungan mundur selesai, kita panggil fungsi setTimeout()
untuk mengatur judul halaman baru setelah delay 2 detik (2000 millisecond).
Fungsi setTimeout()
memungkinkan Kamu mengeksekusi fungsi setelah delay tertentu, diekspresikan dalam millisecond.
// Eksekusi aksi sekali, setelah delay
setTimeout(callbackFunction, timeBeforeCall);
Solusi sebelumnya sangatlah memudahkan dalam membuat halaman kita menjadi lebih sedikit lebih dinamis, tetapi tidak cukup untuk menambah animasi real-time. Mari kita lihat solusi yang lebih baik dari sisi performansinya.
Ambil contoh, pergerakan tiep elemen <div>
dari kiri ke kanan pada halaman. Kita mulai dengan kode HTML dan CSS berikut yang menampilkan blok merah di halaman.
<div id="frame">
<div id="block"></div>
</div>
#frame {
border: 1px solid red;
}
#block {
width: 20px;
height: 40px;
background: red;
position: relative;
}
Dan berikut ini kode JavaScript yang memungkinkan Kamu untuk memindahkan blok merah tersebut.
// Memindahkan blok ke kiri
const moveBlock = () => {
// Mengkonversi posisi kiri blok (nilai dari bentuk "XXpx") ke angka
const xBlock = parseFloat(getComputedStyle(blockElement).left);
// Memindahkan blok ke kanan
blockElement.style.left = (xBlock + movement) + "px";
// Membuat browser memanggil moveBlock sesegera mungkin
requestAnimationFrame(moveBlock);
};
const blockElement = document.getElementById("block");
// Nilai pergerakan dalam pixel
const movement = 7;
// Memulai animasi
requestAnimationFrame(moveBlock);
Klik di sini untuk lihat secara langsung.
Saat halaman terbuka, blok merah bergerak (terus menerus) dari kiri ke kanan.
Contoh kode mendefinisikan sebuah fungsi moveBlock()
yang memindahkan blok secara horizontal ke kanan. Fungsi ini mengambil posisi blok sisi kiri saat ini lalu menambahkan nilai yang ada di dalam variabel movement
. Selanjutnya, kode memanggil method requestAnimationFrame()
untuk menjaga agar animasi tetap bergerak.
Nilai posisi ditulis dalam pixel. Nilai ini adalah string yang Kamu lihat yang menyerupai format "XXpx", yang memerlukan penggunaan fungsi parseFloat()
untuk mengkonversi nilai numerik sebelum melakukan perhitungan.
Jangan gunakan konversi
Number()
untuk mengkonversi satu string dengan"px"
ke nilai numerik. Tidak bisa dan Kamu akan mendapat nilaiNaN
(Not a Number) sebagai hasilnya!
Fungsi requestAnimationFrame()
memungkinkan Kamu untuk meminta browser untuk mengeksekusi fungsi sesegera mungkin, fungsi yang mengupdate animasi. Merupakan tugas browser untuk memastikan animasi berjalan selancar mungkin. Nilai yang dikembalikan dari requestAnimationFrame()
adalah sebuah ID untuk animsi, yang bisa digunakan untuk dimodifikasi lebih lanjut.
Berikut ini adalah cara requestAnimationFrame()
digunakan dan dikombinasikan dengan fungsi animasi.
const animate = () => {
// Kode animasi
// ...
// Di akhir animasi, meminta yang lainnya
animationId = requestAnimationFrame(animate);
};
// Animasi dimulai
let animationId = requestAnimationFrame(animate);
Sekarang mari kita lihat bagaimana menghentikan blok sebelum mencapai batas frame yang ada di dalamnya. Kita haru menverifikasi bahwa posisi perbatasan kiri lebih kecil dari lebar frame, perhatikan ketebalan blok tersebut.
Berikut kode JavaScript terbarunya.
// Memindahkan blok ke kanan, sampai dengan akhir frame
const moveBlock = () => {
// Konversi posisi kiri dari blok (nilai dari bentuk "XXpx") ke angka
const xBlock = parseFloat(getComputedStyle(blockElement).left);
// Konversi lebar frame (nilai dari bentuk "XXpx") ke angka
const xMax = parseFloat(getComputedStyle(frame).width);
// Jika blok belum sampai dengan akhir frame
if (xBlock + blockWidth <= xMax) {
// Pergerakan blok
blockElement.style.left = (xBlock + movement) + "px";
animationId = requestAnimationFrame(moveBlock);
}
else {
// Membatalkan animasi
cancelAnimationFrame(animationId);
}
};
const blockElement = document.getElementById("block");
// Konversi lebar blok (nilai dari bentuk "XXpx") ke angka
const blockWidth = parseFloat(getComputedStyle(block).width);
// Nilai pergerakan dalam pixel
const movement = 7;
// Memulai animasi
let animationId = requestAnimationFrame(moveBlock);
Klik di sini untuk lihat secara langsung.
Fungsi baru moveBlock()
mengecek blok telah sampai di akhir frame sebelum bergerak. Jika ini kasusnya, animasi berhenti melalui panggilan ke cancelAnimationFrame()
.
Fungsi cancelAnimationFrame()
menghentikan animasi dan mengambil animasi ID yang diset oleh pemanggilan sebelumnya ke requestAnimationFrame()
.
// Hentikan animasi
cancelAnimationFrame(animationID);
Kamu baru saja belajar tentang perbedaan kemungkinan yang JavaScript tawarkan untuk menganimasikan halaman web. Ada juga alternatif lainnya: CSS.
Paragraf ini hanyalah kulit dari animasi CSS.
Mari kita cek bagaimana mendapatkan efek yang sama dengan contoh sebelumnya dengan menggunakan CSS dibandingkan JavaScript. Hapus semua kode JavaScript code dari contoh Kamu dan modifikasi kode CSS sebagai berikut.
#frame {
border: 1px solid red;
}
#block {
width: 20px;
height: 40px;
background: red;
position: relative;
margin-left: -20px; /* Margin negatif untuk menyederhanakan kalkulasi posisi */
animation-name: moveBlock; /* Nama animasi */
animation-duration: 6s; /* Panjang animasi */
animation-fill-mode: forwards; /* Membiarkan blok di posisi akhir */
}
@keyframes moveBlock {
from {
/* Posisi awal: ke kiri frame (mempertimbangkan margin negatif) */
left: 20px;
}
to {
/* Posisi akhir: di sebelah kanan frame (mempertimbangkan margin negatif) */
left: 100%;
}
}
Klik di sini untuk lihat secara langsung.
Kode ini mendefinisikan animasi CSS dinamakan moveBlock()
, yang memindahkan blok dari kiri ke kanan frame. Hasilnya hampir sama dengan versi JavaScript.
Sekarang, waktu memutuskan. Bagaimana Kamu memilih antara setInterval()
, requestAnimationFrame()
, atau CSS untuk menganimasikan halaman Kamu? Jawabannya tergantung seberapa kompleks animasi Kamu. Teorinya, animasi CSS lebih efisien secara performansi, tetapi Kamu tidak bisa melakukan semuanya dengan ini.
Berikut bagaimana Kamu melakukan pendekatan untuk pengambilan keputusan:
- Gunakan
setInterval()
jika animasi tidak real-time dan bergerak secara regular. - Pilih CSS jika animasi terjadi secara real-time dan bisa dikelola dengan cara ini.
- Gunakan
requestAnimationFrame()
untuk kasus lainnya.
Tulis halaman web interaktif dengan tombol untuk memulai dan memberhentikan chronometer dalam menghitung detik yang berlalu.
Tujuan dari latihan ini adalah membuat bola basket memantul di layar. Kamu bisa download gambar di sini.
Mulai dengan konten HTML dan CSS berikut.
<p>
<button id="start">Start</button>
<button id="stop" disabled>Stop</button>
</p>
<div id="frame">
<!-- Update the "src" attribute if you downloaded the image locally -->
<img id="ball" src="https://raw.githubusercontent.com/bpesquet/thejsway/master/resources/basketball.jpg">
</div>
#ball {
position: relative;
left: 0px;
}
Tulis kode JavaScript yang bisa membuat bola tersebut memantul secara horizotal.
Dengan solusi Kamu, buat satu variabel dengan nilai 1 atau -1 yang mengarahkan ke mana bola harus bergerak.