Tạo hiệu ứng Before and After Photo Effect với jQuery

DOWNLOAD DEMO

Ngày trước mình có thấy một câu hỏi của ban nào đó đăng trên izwebz group hỏi về hiệu ứng này, hôm nay vô tình tìm thấy một tutorial hướng dẫn làm hiệu ứng này nên mình tranh thủ viết ngay và luôn :D, mục đích cũng chỉ là sưu tâm khi cần xem lại thôi.

Note: Bài này mình có tham khảo trên mạng để tổng hợp lại

1. HTML

Đối với hiệu ứng Before and After Photo Effect thì xây dựng HTML rất đơn giản, bạn chỉ cần copy nội dung sau vào trong thẻ body:

<div id="container">
    <div class="beforeafter">
        <img src="pic1a.jpg" alt="Before - Original Photo" width="392" height="294"/>
        <img src="pic1b.jpg" alt="After - Edited with lightroom" width="392" height="294"/>		
    </div>
</div>
Trong đó div#container chỉ là một wrapper bên ngoài, quan trọng nhất là div.beforeafter, bên trong mỗi div này sẽ là hai hình trước và sau của hiệu ứng. Nếu bạn muốn tạo nhiều khối thì chỉ cần nhân bản nội dung của div.beforeafter là được.

2. CSS hiệu ứng

Chúng ta sẽ style cho hiệu ứng này với nội dung CSS như sau:

#container {width:500px; margin:0 auto;}
.beforeafter {width:270px; height:294px;}	
.ba-mask {position:absolute; top:0; left:0; z-index:100; border-right:3px solid #333; overflow:hidden; box-shadow: 3px 5px 5px rgba(0, 0, 0, 0.6);box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.6); -webkit-box-shadow: 5px 5px 7px rgba(0, 0, 0, 0.6);  -moz-box-shadow: 5px 0 7px rgba(0, 0, 0, 0.6);}
.ba-bg {position:absolute; top:0; left:0; z-index:0;}
.ba-caption {
    position:absolute; 
    bottom:10px; 
    left:10px; 
    z-index:120;	
    background:#000; 
    color:#fff; 
    text-align:center;
    padding:5px; 
    font-size:12px; 
    font-family:arial; 
    filter:alpha(opacity=80);-moz-opacity:0.8;-khtml-opacity: 0.8;opacity: 0.8; 
    -webkit-border-radius:5px; -moz-border-radius:5px; border-radius:5px; 			
}

Trong đoạn CSS này thì phần CSS cho class beforeafter rất là quan trọng, chiều rộng và chiều cao của nó sẽ được sử dụng để tạo hiệu ứng.

3. Thêm thư viện jquery

Vì chúng ta đang viết hiệu ứng jquery nên bắt buộc phải thêm thư viện jquery vào.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>

4. Viết javascript tạo hiệu ứng

Đây là phần khó khăn nhất của chương trình, trong phần này mình sẽ comment từng dòng với hy vọng các bạn hiểu :D

$(document).ready(function() 
{
    // Điểm dừng bên trái so với lề
    var leftgap = 0; 

    // Điểm dừng bên phải so với lề
    var rightgap = 2;

    // Mặc định khi load sẽ nằm ở vị trí nào
    var defaultgap = 0;

    // Có sử dụng hiển thị caption hay không?
    var caption = true;

    // Khoảng cách để chuyển caption, 0.5 tương đương một nửa
    var reveal = 0.5;

    // lặp qua từng cặp hình để xử lý
    // Trong bài này tôi chỉ tạo một cặp duy nhất
    $('.beforeafter').each(function() 
    {
        // Cặp đang lặp
        var i = $(this);

        // Lấy hai hình ảnh cần xử lý
        var img_mask = i.children('img:eq(0)').attr('src');
        var img_bg = i.children('img:eq(1)').attr('src');

        // Lấy alt của hình thứ nhất 
        var img_cap_one = i.children('img:eq(0)').attr('alt');

        // Lấy chiều rộng và chiều cao hình thứ nhất
        var width = i.children('img:eq(0)').width();
        var height = i.children('img:eq(0)').height();

        // Ẩn đi cả hai hình
        i.find('img').hide();

        // Thêm thuộc tính CSS cho cặp hiện tại
        i.css({'overflow': 'hidden', 'position': 'relative'});

        // Thêm một số thẻ HTML để hiển thị caption và hình ảnh
        i.append('<div class="ba-mask"></div>');
        i.append('<div class="ba-bg"></div>');
        i.append('<div class="ba-caption">' + img_cap_one + '</div>');

        // Thiết lập chiều rộng và chiều cao cho
        // các thẻ vừa thêm đúng với hình
        i.children('.ba-mask, .ba-bg').width(width);
        i.children('.ba-mask, .ba-bg').height(height);

        // Thiết lập backgroud cho các thẻ div vừa thêm
        i.children('.ba-mask').css('backgroundImage', 'url(' + img_mask + ')');
        i.children('.ba-bg').css('backgroundImage', 'url(' + img_bg + ')');

        // Thiết lập div hình 1 animate vào đúng vị trí mặc định 
        i.children('.ba-mask').animate({'width': width - defaultgap}, 1000);

        // Nếu có caption thì hiên thị, ngược lại thì ẩn đi 
        if (caption)
            i.children('.caption').show();
        else
            i.children('.ba-caption').hide();

    }).mousemove(function(e) { // Khi hover qua từng hình

        // Hình đang hover
        var i = $(this);

        // Lấy vị trí left hiện tại của hình
        pos_img = i.offset()['left'];

        // Lấy vị tri hiện tại của chuột
        pos_mouse = e.pageX;

        // Tính toán khoảng cách của hình và chuột
        new_width = pos_mouse - pos_img;

        // Chiều rộng hiện tại của mình
        img_width = i.width();

        // Lấy hai capture alt của hai hình
        img_cap_one = i.children('img:eq(0)').attr('alt');
        img_cap_two = i.children('img:eq(1)').attr('alt');

        // Xác định điểm dừng khi lật hình
        if (new_width > leftgap && new_width < (img_width - rightgap)) {
            i.children('.ba-mask').width(new_width);
        }

        // Xác định hiển thị đúng capture
        if (new_width < (img_width * reveal)) {
            i.children('.ba-caption').html(img_cap_two);
        } else {
            i.children('.ba-caption').html(img_cap_one);
        }
    });
});

Các bạn để ý tôi có sử dụng một số hàm trong jquery như dùng each để lặp qua từng hình, và cái quan trọng nhất chính là xử lý chiều rộng, chiều cao và vị trí giữa các con trỏ và lề trái, lề phải. Nên các bạn cần xem kỹ và tự debug thì may ra mới hiểu được :D.

5. Chuyển thành plugin Before and After Photo Effect

Ở phần 4 ta đã viết xong nhưng sử dụng nó rất khó khăn và mang tính bị động. Nên để đơn giản thì ta sẽ chuyển nó thành một plugin jquery nhé. Bạn tạo file jquery.beforeafter.js với nội dung như sau:

(function($) {
    $.fn.extend({
        //plugin name - qbeforeafter
        qbeforeafter: function(options) {

            var defaults = {
                defaultgap: 0,
                leftgap: 0,
                rightgap: 2,
                caption: false,
                reveal: 0.5
            };

            var options = $.extend(defaults, options);

            return this.each(function() {

                var o = options;
                var i = $(this);
                var img_mask = i.children('img:eq(0)').attr('src');
                var img_bg = i.children('img:eq(1)').attr('src');
                var img_cap_one = i.children('img:eq(0)').attr('alt');

                var width = i.children('img:eq(0)').width();
                var height = i.children('img:eq(0)').height();

                i.children('img').hide();

                i.css({'overflow': 'hidden', 'position': 'relative'});
                i.append('<div class="ba-mask"></div>');
                i.append('<div class="ba-bg"></div>');
                i.append('<div class="ba-caption">' + img_cap_one + '</div>');

                i.children('.ba-mask, .ba-bg').width(width);
                i.children('.ba-mask, .ba-bg').height(height);
                i.children('.ba-mask').animate({'width': width - o.defaultgap}, 1000);

                i.children('.ba-mask').css('backgroundImage', 'url(' + img_mask + ')');
                i.children('.ba-bg').css('backgroundImage', 'url(' + img_bg + ')');

                if (o.caption)
                    i.children('.ba-caption').show();

            }).mousemove(function(e) {

                var o = options;
                var i = $(this);

                pos_img = i.offset()['left'];
                pos_mouse = e.pageX;
                new_width = pos_mouse - pos_img;
                img_width = i.width();
                img_cap_one = i.children('img:eq(0)').attr('alt');
                img_cap_two = i.children('img:eq(1)').attr('alt');

                if (new_width > o.leftgap && new_width < (img_width - o.rightgap)) {
                    i.children('.ba-mask').width(new_width);
                }

                if (new_width < (img_width * o.reveal)) {
                    i.children('.ba-caption').html(img_cap_two);
                } else {
                    i.children('.ba-caption').html(img_cap_one);
                }

            });
        }
    });
})(jQuery);
Như vậy ta đã chuyển thành một Plugin jQuery Before and After Photo Effect. Nếu bạn chưa biết viết plugin jquery thì hãy tìm hiểu video trên youtube mà tôi đã quay nhé.

Cách sử dụng:

$('.beforeafter').beforeafter({defaultgap:50, leftgap:0, rightgap:10, caption: true, reveal: 0.5});

6. Lời kết

Hiệu ứng Before and After Photo Effect này cũng đang có nhiều website sử dụng, nếu bạn thích hay ráp vào project của bạn nhé. Khi code với những loại thế này thì việc giải thích từng dòng sẽ rất khó khăn, vì thế để hiểu được thì bạn phải debug thật kỹ để hiểu hoặc là lấy sử dụng khỏi để ý đến nó. Tôi hy vọng rằng bạn là người thích tìm tòi và debug code :D

Hãy để lại link bài viết gốc khi chia sẻ bài viết này, mình sẽ report DMCA với những website lấy nội dung mà không để nguồn hoặc copy bài với số lượng lớn.

Nguồn: freetuts.net

Profile photo of adminTheHalfHeart

TheHalfHeart

Có sở thích viết tuts nên đã từng tham gia viết ở một số diễn đàn, đến năm 2014 mới có điều kiện sáng lập ra freetuts.net. Sinh năm 90 và có 1 vợ 2 con, thích ca hát và lập trình.

ĐĂNG BÌNH LUẬN: Đăng câu hỏi trên Group Facebook để được hỗ trợ nhanh nhất.