Misalkan ada persyaratan fungsi animasi seperti itu: Ubah lebar div dari 100px ke 200px. Kode yang ditulis mungkin terlihat seperti ini:
Salinan kode adalah sebagai berikut:
<Div id = "test1"> </div>
fungsi animate1 (elemen, endvalue, durasi) {
var startTime = new date (),
startValue = parseInt (element.style.width),
Langkah = 1;
var timerid = setInterval (function () {
var nextValue = parseInt (element.style.width) + langkah;
element.style.width = nextValue + 'px';
if (nextValue> = endValue) {
ClearInterval (TimerID);
// memakan waktu untuk menampilkan animasi
element.innerHtml = Tanggal baru - startTime;
}
}, durasi / (endvalue - startValue) * langkah);
}
animate1 (document.getElementById ('test1'), 200, 1000);
Prinsipnya adalah meningkatkan 1px setiap waktu tertentu hingga 200px. Namun, waktu tampilan setelah animasi selesai lebih dari 1s (biasanya sekitar 1,5s). Alasannya adalah bahwa SetInterval tidak dapat secara ketat menjamin interval eksekusi.
Apakah ada cara yang lebih baik untuk melakukannya? Pertama -tama mari kita lihat masalah matematika sekolah dasar:
Salinan kode adalah sebagai berikut:
Building A dan Building B terpisah 100 meter. Seorang pria berjalan dari membangun A ke Building B dengan kecepatan konstan. Setelah berjalan selama 5 menit, dia tiba di tujuannya. Seberapa jauh dia dari membangun A di menit ketiga?
Rumus perhitungan untuk menghitung jarak waktu tertentu selama kecepatan konstan adalah: jarak * waktu/waktu saat ini. Jadi jawabannya harus 100 * 3/5 = 60.
Inspirasi dari pertanyaan ini adalah bahwa perjalanan momen tertentu dapat dihitung melalui formula tertentu. Demikian pula, nilai momen tertentu selama proses animasi juga dapat dihitung melalui rumus alih -alih diakumulasikan:
Salinan kode adalah sebagai berikut:
<Div id = "test2"> </div>
fungsi animate2 (elemen, endvalue, durasi) {
var startTime = new date (),
startValue = parseInt (element.style.width);
var timerid = setInterval (function () {
persentase var = (tanggal baru - startTime) / durasi;
var stepValue = startValue + (endvalue - startValue) * persentase;
element.style.width = StepValue + 'px';
if (persentase> = 1) {
ClearInterval (TimerID);
element.innerHtml = Tanggal baru - startTime;
}
}, 13);
}
animate2 (document.geteLementById ('test2'), 200, 1000);
Setelah peningkatan ini, Anda dapat melihat bahwa waktu eksekusi animasi hanya akan memakan waktu hingga 10 ms. Namun, masalahnya belum sepenuhnya terpecahkan. Jika Anda memeriksa elemen test2 di alat pengembangan browser, Anda akan menemukan bahwa lebar akhir test2 mungkin lebih dari 200px. Jika Anda dengan hati -hati memeriksa kode fungsi Animate2, Anda akan menemukan:
1. Nilai persentase mungkin lebih besar dari 1, yang dapat diselesaikan dengan membatasi nilai maksimum dengan matematika.
2. Bahkan jika nilai persentase dijamin tidak lebih dari 1, selama nilai endvalue atau start -value adalah desimal, nilai (endValue - startValue) * persentase dapat menyebabkan kesalahan, karena operasi desimal JavaScript tidak cukup akurat. Faktanya, yang perlu kita pastikan adalah keakuratan nilai akhir, jadi ketika persentase adalah 1, cukup gunakan endValue secara langsung.
Jadi, kode fungsi Animate2 dimodifikasi menjadi:
Salinan kode adalah sebagai berikut:
fungsi animate2 (elemen, endvalue, durasi) {
var startTime = new date (),
startValue = parseInt (element.style.width);
var timerid = setInterval (function () {
// Pastikan persentasenya tidak lebih besar dari 1
persentase var = math.min (1, (tanggal baru - startTime) / durasi);
var stepvalue;
if (persentase> = 1) {
// Pastikan keakuratan nilai akhir
StepValue = EndValue;
} kalau tidak {
StepValue = StartValue + (EndValue - StartValue) * Persentase;
}
element.style.width = StepValue + 'px';
if (persentase> = 1) {
ClearInterval (TimerID);
element.innerHtml = Tanggal baru - startTime;
}
}, 13);
}
Ada pertanyaan terakhir lainnya: mengapa interval setinterval set ke 13ms? Alasannya adalah bahwa laju penyegaran monitor saat ini umumnya tidak melebihi 75Hz (yaitu, disegarkan 75 kali per detik, yang berarti disegarkan setiap 13 ms), dan menyinkronkan interval dengan laju refresh lebih baik.