0

Tạo một Animated Picture Gallery

Bên cạnh một website có UI, UX tốt thì việc tạo ra các hiệu ứng cho website cũng là một cách để tăng tính sinh động. Và hôm nay mình sẽ hướng dẫn các bạn sử dụng thư viện Jquery và một vài tính năng animation của nó để tạo ra một thư viện ảnh với các hiểu ứng cơ bản.

Để làm được tuts này bạn cần có kiến thức cơ bản về HTML, CSS và Jquery. Ok, chúng ta hãy cùng bắt đầu.

1.Khởi tạo

Đơn giản là setup những file và thư viện cho dự án. Đầu tiên bạn tạo cho mình một thư mục có tên bắt kỳ, ví dụ Gallery. Trong thư mục này chúng ta sẽ tạo ra file index.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <link href="style.css" rel="stylesheet" />
    <script src="http://code.jquery.com/jquery.min.js"></script>
  	<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>
    <script src="Gallery.js"></script>
</head>
<body>
  <div id="gallery"></div>
</body>
</html>

Ở đây mình đã import 2 thư viện jquery và jquery-easing. Tiếp theo là file styles.css để viết code css và Gallery.js để viết code javascript


#gallery {
    position: relative;
    left: 80px;
    top: 80px;
    background-color: #555;
    border: 2px solid black;
    width: 700px;
    height: 400px;

    perspective: 250px;
    perspective-origin: 50% 50%;
}

Tiếp theo là ảnh, tất nhiên là làm một cái thư viện ảnh thì cẩn phải có ảnh rồi, mình sẽ cho tất cả các ảnh vào trong thư mục Images, mình sẽ lấy khoảng 10 cái để demo thôi. Ok có vẻ phần setup đã ổn. Tiếp theo là phần quan trọng nhất.

2.Viết code

Mình sẽ sử dụng Javascript để in ra ảnh, tất nhiên đây là cách lười thôi. Trong index.html

<script>

        $(function () {
            var loadCount = 0;
            for (var i = 1; i <= 12; i++) {
                var name = i + '.png';
                if (i < 10) name = '0' + name;
                var img = $('<img class="galleryImage" src="Images/' + name + '" />');
                $('#gallery').append(img);

                img.load(function () {
                    if (++loadCount == 12)
                        var g = new PS.Gallery('gallery');
                });
            }
        });

    </script>

Như vậy là việc hiển thị hình ảnh đã xong. Trong file Gallary.js, mình sẽ sử dụng biến window để tạo ra một biến global PS.

(function (ns) {

    ns.Gallery = function (id) {

        var gallery = $('#' + id);
}(window.PS = window.PS || {}));

Chỉnh sửa lại một chút css cho mấy cái ảnh.Trong style.css thêm vào:

.galleryImage {
    position: absolute;
    border: 1px solid black;
}

Trong file Gallery.js, mình sẽ sử dụng js để chỉnh sửa một số thông số cho các thẻ images

(function (ns) {

    ns.Gallery = function (id) {

        var gallery = $('#' + id);
        var images = gallery.find('.galleryImage');

        var xPos = 50; // khoảng cách trái
        var yPos = 50; // khoảng cách phải
        var gWidth = gallery.width();

        images.each(function (idx, el) {
            var img = $(el);
            // Chúng ta sẽ lưu các giá trị vị trí của img.
            img.data('homeX', xPos);
            img.data('homeY', yPos);
            img.data('currentScale', 1);
            img.css({
                'left': xPos,
                'top': yPos,
                'width': img.width() * 0.25
            });
            xPos += 95; // tăng dần khoảng cách trái
            if (xPos > gWidth - 100) {
                xPos = 50; // xuống hàng.
                yPos += 115;
            }
        });

    }
}(window.PS = window.PS || {}));

Tiếp theo là quá trình đi xây dựng các hiệu ứng khi hover trỏ chuột vào bức ảnh, khi hover vào bức ảnh , bức ảnh sẽ tự động phóng to ra và khi leave chuột nó sẽ quay trở về trạng thái bình thường.

Đầu tiên chúng ta sẽ cần phải break các công việc ra, khi mà bức ảnh được hover nó sẽ tự động to lên và như vậy các bức ảnh ở 2 bên của nó sẽ bị đè xuống hay nói cách khác là giảm z-index: 0 và tăng z-index: 1 của bức ảnh đang được hover. Thứ hai là khi đưa các images trở về trạng thái ban đầu ,chúng ta sẽ sử dụng css transform để chuyển cảnh,

(function (ns) {

    ns.Gallery = function (id) {

        var gallery = $('#' + id);
        var images = gallery.find('.galleryImage');

        var xPos = 50;
        var yPos = 50;
        var gWidth = gallery.width();

        images.each(function (idx, el) {
            var img = $(el);
            img.data('homeX', xPos);
            img.data('homeY', yPos);
            img.data('currentScale', 1);
            img.css({
                'left': xPos,
                'top': yPos,
                'width': img.width() * 0.25
            });
            xPos += 95;
            if (xPos > gWidth - 100) {
                xPos = 50;
                yPos += 115;
            }

            img.hover(
                function (event) {
                    var target = $(event.target);
                    bringImageToTop(target);
                    animateImage(target, 500, target.data('homeX'), target.data('homeY'), 2);
                },
                function (event) {
                    returnAllToNormal();
                }
            );

        });
        // Thay đổi z-index cho img
        var bringImageToTop = function (img) {
            images.each(function (idx, el) {
                $(el).css('z-index', 0);
            });
            img.css('z-index', 1);
        }
        // Chỉ đơn giản là đưa các bức ảnh trở lại bình thường.
        var returnAllToNormal = function () {

            images.each(function (idx, el) {
                var img = $(el);

                animateImage(img, 500, img.data('homeX'), img.data('homeY'), 1);

            });

        }
        //Tạo hiệu ứng cho bức ảnh img.
        var animateImage = function (img, duration, left, top, scale) {
            img.stop(); // Dừng các hiệu ứng lại

            img.css('textIndent', img.data('currentScale'));

            img.animate({
                'left': left,
                'top': top,
                'textIndent': scale,
            },
            {
                duration: duration,
                step: function (now, fx) {
                // đây là hàm phát hiện sự thay đổi của các thuộc tính.
                    if (fx.prop === 'textIndent') {
                        // scale
                        img.data('currentScale', now);
                        img.css('transform', 'scale(' + now + ')');// dùng transform để phóng to ảnh
                    }
                    else if (fx.prop === 'left')
                        img.css('left', now);
                    else if (fx.prop === 'top')
                        img.css('top', now);
                }
            });

        }

    }
}(window.PS = window.PS || {}));

Giờ khi chạy chương trình , bạn sẽ thấy bức ảnh của chúng ta sẽ được phóng to khi hover vào nhìn khá vui mắt. Tuy nhiên có một đặc điểm là bức ảnh được phóng to sẽ nằm đè lên 2 bức ảnh bên cạnh nó. Để giải quyết điều này, chúng ta sẽ kiểm tra khoảng cách giữa ảnh được hover và các ảnh còn lại để dịch chuyển.

 var avoidImage = function (target) {
            images.each(function (idx, el) {
                var img = $(el);
                if (img[0] != target[0]) {

                    var xdiff = img.data('homeX') - target.data('homeX');
                    var ydiff = img.data('homeY') - target.data('homeY');

                    var adj = 40;
                    var xAdjust = (xdiff > 0) ? adj : (xdiff < 0) ? -adj : 0;
                    var yAdjust = (ydiff > 0) ? adj : (ydiff < 0) ? -adj : 0;
                    if (yAdjust != 0) xAdjust = 0;

                    var newX = img.data('homeX') + xAdjust;
                    var newY = img.data('homeY') + yAdjust;

                    animateImage(img, 500, newX, newY, 1);
                }
            });
        }

Và gọi nó ngay sau hàm bringImageToTop(target);.Ok đây chỉ là một tuts đơn giản về tạo hiệu ứng cho web. Hiện nay có rất nhiều thư viện hỗ trợ và có lẽ các bạn cũng sẽ không phải viết code dài dòng như thế này.

Source code tham khảo tại đây


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.