-
Ta lại quay lại về cái đếm ngược Oh Noes.
-
Giờ nếu ta muốn ảnh của Oh Noes to dần ra
-
khi đếm ngược dần về 0,
-
thì phải làm thế nào?
-
Một cách làm là tạo ảnh động
-
với CSS của ảnh này với window.setInterval.
-
Bước đầu tiên, tôi sẽ tìm ảnh này
-
và gán nó vào một biến.
-
ohnoes = document.getElemenyById("ohnoes");
-
Ta đặt style khởi điểm,
-
tức là sẽ bắt đầu từ chiều rộng này.
-
Rồi ảnh sẽ lớn dần ra từ đó.
-
Giờ ta viết một hàm makeItBigger
-
để làm ảnh to ra từng chút một.
-
Ở đây ta lấy giá trị style.width,
-
lấy giá trị style.width từ trước và cộng thêm 1 vào.
-
Cuối cùng tôi sẽ gọi hàm setInterval với hàm này.
-
window.setInterval(makeItBigger),
-
Ta muốn nó to lên từng nào nào?
-
Hỏi cách khác là cứ bao lâu thì sẽ to lên 1 lần?
-
Nếu ta ma muốn tạo một hình ảnh động thật mượt,
-
thì tức là sẽ cần thay đổi trong khoảng tần suất
-
24 khung hình mỗi giây tới 60 khung hình mỗi giây.
-
Tôi sẽ thử với 30 khung hình mỗi giây, tức là 1000/3.
-
Không được rồi.
-
Bạn biết tại sao không? Hơi rắc rối đấy.
-
Ta sẽ xem lại xem nào.
-
Giá trị của ohnoes.style.width
-
sau khi chạy dòng lệnh này là bao nhiêu nào?
-
Chắc là 50px rồi sẽ đến 51px rồi,
-
nhưng ta cứ log ra xem ohnoes.style.width là bao nhiêu.
-
Ta đặt cái này vào trong infoDiv.
-
Nó sẽ bằng...
-
50px, okay.
-
Rồi khi ta cộng thêm 1 vào 50px,
-
50px thêm 1 là gì?
-
Bạn đoán là 51px, nhưng JS
-
coi 50px là 1 string,
-
nên thêm 1 sẽ thành 50px1,
-
tức là chả có ý nghĩa gì.
-
Như vậy là trình duyệt sẽ không
-
thay đổi thuộc tính width theo giá trị dở hơi này được rồi.
-
Vậy là ta sẽ cần chuyển đổi string với đơn vị pixel này
-
về kiểu số,
-
rồi cộng 1 vào số đó,
-
rồi lại thêm "px" vào sau.
-
Ta có thể đặt cái này vào trong parseFloat,
-
thế là đổi được về dạng số.
-
Rồi ta đóng ngoặc cụm này lại,
-
và thêm "px" vào sau.
-
Được rồi. Ảnh đang to dần lên rồi.
-
Bạn thấy cái lằng nhằng
-
trong việc tạo hình động với CSS
-
là thường nó sẽ có cả chữ đơn vị ở sau giá trị số nữa, bạn sẽ phải
-
chuyển bỏ đơn vị đó đi... trời ơi ảnh to quá...
-
bạn phải bỏ chữ đơn vị đó ra rồi lại đưa nó lại vào sau.
-
Ảnh này to ra quá rồi.
-
Còn một vài vấn đề thường gặp
-
khi sử dụng setInterval để thay đổi thuộc tính CSS.
-
Đầu tiên là trình duyệt sẽ không phải lúc nào cũng
-
đợi đúng theo số interval này.
-
Nếu có event gì khác xảy ra, như là khi người dùng sử dụng trình duyệt,
-
gõ gì đó chẳng hạn, thì có thể trình duyệt sẽ đợi xong event đó mới gọi hàm callback này,
-
thì hoạt hình động trông sẽ không được mượt.
-
Thứ 2 nữa là trình duyệt sẽ gọi hàm này
-
kể cả khi tab này ẩn đi,
-
tức là sẽ tiêu tốn tài nguyên của máy tính.
-
Vì vậy nên là các trình duyệt hiện đại
-
có một hàm mới,
-
chuyên dùng để tạo hoạt hình với DOM,
-
gọi là window.requestAnimationFrame.
-
Làm việc với hàm đó, đầu tiên ta sẽ bỏ dòng setInterval này đi
-
và gọi hàm requestAnimationFrame()
-
ở trong hàm này.
-
Và ta sẽ chỉ nó đến
-
hàm makeItBigger.
-
Rồi sẽ sẽ gọi hàm makeItBigger() ngay khi tải trang web.
-
Oh! Ảnh này đang to lên nahnh quá.
-
Trình duyệt đang gọi hàm makeItBigger liên tục
-
mỗi khi cập nhật ảnh, tức là vào khoảng 60 khung hình một giây,
-
tức là gấp đôi tần số vừa rồi.
-
Hàm này cứ mỗi lần lại cộng thêm 1px vào chiều rộng,
-
tính toán ra thì
-
là cộng thêm 60px mỗi giây.
-
Chỉ vài giây là ảnh đã to hơn cả trang rồi.
-
Giờ to quá đi mất rồi.
-
Vậy làm sao để làm chậm hoạt hình này lại?
-
Có một vài cách, nhưng một cách tôi thích dùng
-
là kiểm tra xem đã chạy bao nhiêu giây rồi,
-
rồi tính giá trị của chiều rộng
-
dựa theo giá trị đó.
-
Ta bắt đầu chép lại thời gian khởi điểm, tính theo ms,
-
trước khi hàm này được gọi.
-
var startTime... ảnh lại to ra nữa rồi.
-
new Date().getTime();
-
Trong makeItBigger9) thì ta lưu giá trị của thời gian hiện tại.
-
var currTime = new Date().getTime();
-
Giờ ta phải tính,
-
ví dụ nếu muốn ảnh to ra 30px/s,
-
và bắt đầu từ 50px,
-
ta tính toán ở đây.
-
newWidth bằng 50 + ..., 50 là giá trị khởi điểm...
-
cộng thêm currentTime trừ đi startTime.
-
Giá trị này là millisecond, nên ta sẽ
-
chia cho 1000,
-
rồi nhân với 30,
-
bỏi vì ta muốn tăng lên 30px mỗi giây.
-
Đây là newWidth rồi.
-
Giờ ta sẽ đặt style.width cho bằng newWidth.
-
newWidth... đây được rồi,
-
thế này là được 30px/s thật mượt rồi.
-
Ta có thể thay đổi số này nếu muốn nó chạy
-
nhanh hơn chậm hơn.
-
Còn nếu muốn dừng hoạt hình lại khi to đủ rồi thì sao?
-
Ta có thể cho dòng này vào trong điều kiện 'if'.
-
Dòng này đây, và chỉ chạy dòng này
-
nếu currentWidth nhỏ hơn 1 giá trị nào đó,
if the currentWidth is
-
như là 300, thử xem nào.
-
Thực ra không phải là currentWidth mà là newWidth mới được.
-
Thử xem có dừng ở 300 không.
-
Oh Noes ơi, to ra xem nào.
-
Đẹp rồi.
-
Kĩ thuật sử dụng requestAnimationFrame này
-
hoàn toàn dùng được với Chrome,
-
Firefox và IE10 trở lên.
-
Còn có những thư viện JS
-
để dùng requestAnimationFrame nếu được,
-
và quay lai jdungf setInterval nếu là trình duyệt cũ.
-
Đấy là một vấn đề của việc lập trình web:
-
Mạng web thay đổi liên tục,
-
các trình duyệt liên tục cung cấp các chức năng mới,
-
lập trình viên cũng phát triển các kĩ thuật mới.
-
Bạn cần liên tục học về những cái mới này
-
thì sử dụng mới hiệu quả tối đa được.