Phần tử canvas trong HTML5, giúp bạn dễ dàng tạo và thay đổi đồ họa trên website. Chúng ta có thể sử dụng canvas như mọi phần tử HTML khác, tức là có thể áp dụng các hiệu ứng của jQuery, kiểm tra các sự kiện, áp dụng vào trong layout...
Các bài hướng dẫn canvas trước đây thường về game hoặc hiệu ứng ảnh. Hôm nay bạn sẽ được học cách sử dụng canvas để tạo hiệu ứng cho jquery slideshow.
Ý tưởng
Sử dụng JavaScript, chúng ta sẽ áp dụng bộ lọc đặc biệt vào các ảnh trong slideshow. Chúng ta sẽ tạo một phiên bản mới của ảnh trong slideshow và lưu vào trong phần tử canvas. Khi người xem click để chuyển ảnh, canvas sẽ xuất hiện với hiệu ứng fadeIn.
Mã HTML
Trước tiên, bạn cần có file HTML, tạm đặt tên là html5-slideshow.html như sau:
05 |
< meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" /> |
06 |
< title >An HTML5 Slideshow w/ Canvas & jQuery | Tutorialzine Demo</ title > |
07 |
< link rel = "stylesheet" type = "text/css" href = "styles.css" /> |
12 |
< li >< img src = "img/photos/1.jpg" width = "620" height = "320" alt = "Marsa Alam" /></ li > |
13 |
< li >< img src = "img/photos/2.jpg" width = "620" height = "320" alt = "Turrimetta Beach" /></ li > |
14 |
< li >< img src = "img/photos/3.jpg" width = "620" height = "320" alt = "Power Station" /></ li > |
15 |
< li >< img src = "img/photos/4.jpg" width = "620" height = "320" alt = "Colors of Nature" /></ li > |
18 |
< span class = "arrow previous" ></ span > |
19 |
< span class = "arrow next" ></ span > |
23 |
< script src = "script.js" ></ script > |
Đây là kiểu khai báo doctype của HTML5, bạn có thể thấy nó hơi khác so với HTML4.1 hiện tại. Mã HTML cho slideshow rất đơn giản, tất cả nằm trong thẻ div#slideshow và mỗi ảnh nằm trong một phần tử li của unordered list.
Ở dưới chúng ta thêm jquery và script.js (phần cuối bài viết) để xử lý các hiệu ứng (bạn hoàn toàn có thể chuyển thẻ script này vào trong thẻ <head>).
Mã CSS
Tất cả các mã CSS được lưu vào style.css, ở đây tác giả sử dụng #slideshow trước các thuộc tính CSS khác. Việc này giúp bạn có thể gắn vào website của mình mà không lo bị xung đột.
02 |
background-color : #F5F5F5 ; |
03 |
border : 1px solid #FFFFFF ; |
09 |
-moz-box-shadow: 0 0 22px #111 ; |
10 |
-webkit-box-shadow: 0 0 22px #111 ; |
11 |
box-shadow: 0 0 22px #111 ; |
17 |
list-style : none outside none ; |
30 |
#slideshow li:first-child{ |
35 |
#slideshow .slideActive{ |
49 |
background : url ( 'img/arrows.png' ) no-repeat ; |
56 |
#slideshow .previous{ background-position : left top ; left : 0 ;} |
57 |
#slideshow .previous:hover{ background-position : left bottom ;} |
59 |
#slideshow .next{ background-position : right top ; right : 0 ;} |
60 |
#slideshow .next:hover{ background-position : right bottom ;} |
Chúng ta có thể chia thành 3 nhóm người xem slideshow như sau:
-
Người xem tắt JavaScript trên trình duyệt: chỉ nhìn thấy ảnh đầu tiên và không thể click sang ảnh tiếp theo.
-
Người xem bật JavaScript (mặc định), nhưng trình duyệt không hỗ trợ canvas: vẫn thấy slide chuyển động nhưng không đi kèm hiệu ứng.
-
Người xem bật JavaScript và sử dụng trình duyệt hỗ trợ canvas: thấy đầy đủ nhất hiệu ứng của slideshow (Các phiên bản mới nhất của Firefox, Safari, Chrome, Opera và IE9).
Với 2 nhóm đầu tiên, sử dụng cách chọn first-child để hiển thị slide đầu tiên và áp dụng thuộc tínhoverflow:hidden để che đi các phần khác.
Mã JavaScript
Cuối cùng là phần quan trọng nhất của bài hướng dẫn: mã Javascript và jQuery.
script.js – Phần 11
01 |
$(window).load( function (){ |
06 |
var supportCanvas = 'getContext' in document.createElement( 'canvas' ); |
11 |
setTimeout( function (){ |
14 |
$( '#slideshow img' ).each( function (){ |
17 |
createCanvasOverlay( this ); |
24 |
$( '#slideshow .arrow' ).click( function (){ |
25 |
var li = slides.eq(current), |
26 |
canvas = li.find( 'canvas' ), |
32 |
if ($( this ).hasClass( 'next' )){ |
33 |
nextIndex = current >= slides.length-1 ? 0 : current+1; |
36 |
nextIndex = current <= 0 ? slides.length-1 : current-1; |
39 |
var next = slides.eq(nextIndex); |
45 |
canvas.fadeIn( function (){ |
52 |
li.fadeOut( function (){ |
53 |
li.removeClass( 'slideActive' ); |
55 |
next.addClass( 'slideActive' ); |
65 |
next.addClass( 'slideActive' ).show(); |
66 |
li.removeClass( 'slideActive' ).hide(); |
Với document.createElement()
, bạn có thể tạo bất kỳ phần từ DOM nào. Vì vậy để kiểm tra trình duyệt có hỗ trợ canvas hay không, bạn có thể sử dụng toán tử in
để kiểm tra phương thức getContext()
. Kết quả của phép thử sẽ được dùng để kiểm tra trình duyệt có hỗ trợ canvas hay không.
Bạn cần chú ý là khi gọi hàm createCanvasOverlay chúng ta cần đặt vào trong setTimeout vì hàm này chạy khá nặng và có thể kiến trình duyệt bị treo (nếu cấu hình máy của bạn yếu). Và khi đó setTimeout sẽ giúp chia nhỏ thời gian xử lý giúp cải thiện tốc độ.
script.js – Phần 2
04 |
function createCanvasOverlay(image){ |
06 |
var canvas = document.createElement( 'canvas' ), |
07 |
canvasContext = canvas.getContext( "2d" ); |
10 |
canvas.width = image.width; |
11 |
canvas.height = image.height; |
14 |
canvasContext.drawImage(image,0,0); |
17 |
var imageData = canvasContext.getImageData(0,0,canvas.width,canvas.height), |
18 |
data = imageData.data; |
22 |
for ( var i = 0;i<imageData.height*imageData.width*4;i++){ |
27 |
data[i] = ((data[i] < 128) ? (2*data[i]*data[i] / 255) : |
28 |
(255 - 2 * (255 - data[i]) * (255 - data[i]) / 255)); |
29 |
data[++i] = ((data[i] < 128) ? (2*data[i]*data[i] / 255) : |
30 |
(255 - 2 * (255 - data[i]) * (255 - data[i]) / 255)); |
31 |
data[++i] = ((data[i] < 128) ? (2*data[i]*data[i] / 255) : |
32 |
(255 - 2 * (255 - data[i]) * (255 - data[i]) / 255)); |
39 |
canvasContext.putImageData(imageData,0,0,0,0,imageData.width,imageData.height); |
42 |
image.parentNode.insertBefore(canvas,image); |
Có thể nói hàm createCanvasOverlay là phần chính của bài hướng dẫn. Bạn có thể hiểu canvas là một tờ giấy trắng mà bạn có thể vẽ vào nhờ cái bút javascript. Đoạn mã trong hàm tạo một phần tử canvas trắng và đưa ảnh vào sử dụng phương thức drawImage()
. Sau đó, chúng ta sử dụng tiếpgetImageData()
để lấy từng điểm ảnh trong canvas vào mảng imageData.
Tiếp tục, với từng điểm ảnh chúng ta áp dụng bộ lọc đặc biệt (màu sáng thì sáng hơn và màu tối sẽ tối hơn) tương tự với chế độ overlay blending trong photoshop.
Vòng lặp for xử lý rất nhiều – với một bức ảnh 600×400 pixel sẽ phải có 240 000 lần lặp! Lý do đó bạn phải thực sự cẩn thận với đoạn mã, sao cho nó nhẹ nhất có thể, cũng vì vậy tác giả copy công thức 3 lần thay vì chuyển nó vào hàm. Việc này giúp vòng lặp chạy nhanh gấp ba lần.
ntuts.com