본문 바로가기
Js

masonry 메이슨리 레이아웃

by 영감은어디에 2024. 6. 30.

https://masonry.desandro.com/

 

Masonry

Install Download CDN Link directly to Masonry files on unpkg. Package managers Install with Bower:  bower install masonry --save Install with npm:  npm install masonry-layout Getting started HTML Include the Masonry .js file in your site. Masonry works o

masonry.desandro.com

 

head

<link rel="stylesheet" href="./css/colorbox.css" />
<link rel="stylesheet" href="./css/main.css" />
<script src="./js/vendor/jquery-1.10.2.min.js"></script>
<script src="./js/vendor/jquery.ba-throttle-debounce.min.js"></script>
<script src="./js/vendor/imagesloaded.pkgd.min.js"></script>
<script src="./js/vendor/masonry.pkgd.min.js"></script>
<script src="./js/vendor/jquery.colorbox-min.js"></script>
<script src="./js/main.js"></script>

 

<header class="page-header" role="banner">
    <div class="inner clearfix">
        <h1 class="site-logo"><a href="./">Home</a></h1>
        <form class="filter-form" id="gallery-filter">
            <span class="form-item">
                <input
                    type="radio"
                    name="filter"
                    id="filter-all"
                    value="all"
                    checked
                />
                <label for="filter-all">All</label>
            </span>
            <span class="form-item">
                <input
                    type="radio"
                    name="filter"
                    id="filter-people"
                    value="people"
                />
                <label for="filter-people">People</label>
            </span>
            <span class="form-item">
                <input
                    type="radio"
                    name="filter"
                    id="filter-animals"
                    value="animals"
                />
                <label for="filter-animals">Animals</label>
            </span>
            <span class="form-item">
                <input
                    type="radio"
                    name="filter"
                    id="filter-nature"
                    value="nature"
                />
                <label for="filter-nature">Nature</label>
            </span>
            <span class="form-item">
                <input
                    type="radio"
                    name="filter"
                    id="filter-plantes"
                    value="plantes"
                />
                <label for="filter-plantes">Plantes</label>
            </span>
            <span class="form-item">
                <input
                    type="radio"
                    name="filter"
                    id="filter-architects"
                    value="architects"
                />
                <label for="filter-architects">Architects</label>
            </span>
        </form>
    </div>
</header>

<div class="page-main" role="main">
    <ul class="gallery" id="gallery"></ul>
    <button class="load-more" id="load-more">Load more</button>
</div>
$(function () {


$('#gallery').each(function () {

    var $container = $(this),
        $loadMoreButton = $('#load-more'), // 추가 버튼
        $filter = $('#gallery-filter'),    // 필터링 양식
        addItemCount = 16,                 // 한 번에 표시 할 항목 수
        addedd = 0,                        // 표시된 항목 수
        allData = [],                      // 모든 JSON 데이터
        filteredData = [];                 // 필터링 된 JSON 

    $container.masonry({
        columnWidth: 230,
        gutter: 10,
        itemSelector: '.gallery-item'
    });

    $.getJSON('./data/content.json', initGallery); //이미지경로 및 타이틀 제이슨파일

    //갤러리 초기화
    function initGallery (data) {
        allData = data;
        filteredData = allData;             // 처음엔 필터링 없음 
        addItems();                         // 첫 번째 항목을 표시
        $loadMoreButton.on('click', addItems);
        $filter.on('change', 'input[type="radio"]', filterItems);
        $container.on('mouseenter mouseleave', '.gallery-item a', hoverDirection);
    }

    // 항목을 생성 뿌림
    function addItems (filter) {
        var elements = [],
        // 추가 데이터의 배열
        slicedData = filteredData.slice(addedd, addedd + addItemCount);

        // slicedData에 DOM 요소를 생성
        $.each(slicedData, function (i, item) {
            var itemHTML =
                    '<li class="gallery-item is-loading">' +
                        '<a href="' + item.images.large + '">' +
                            '<img src="' + item.images.thumb + '" alt="">' +
                            '<span class="caption">' +
                                '<span class="inner">' +
                                    '<b class="title">' + item.title + '</b>' +
                                    '<time class="date" datatime="' + item.date + '">' +
                                        item.date.replace(/-0?/g, '/') +
                                    '</time>' +
                                '</span>' +
                            '</span>' +
                        '</a>' +
                    '</li>';
            elements.push($(itemHTML).get(0));
        });

        // DOM 요소의 배열을 컨테이너에 넣고 Masonry 레이아웃을 실행
        $container
            .append(elements)
            .imagesLoaded(function () {
                $(elements).removeClass('is-loading');
                $container.masonry('appended', elements);

                if (filter) {           // 필터링시 재배치
                    $container.masonry();
                }
            });

        // 이미지링크에 Colorbox 설정
        $container.find('a').colorbox({
            maxWidth: '970px',
            maxHeight: '95%',
            title: function () {
                return $(this).find('.inner').html();
            }
        });

        addedd += slicedData.length;  // 추가 된 항목 수량 갱신

        if (addedd < filteredData.length) {     // JSON 데이터가 추가 된 후 추가 버튼
            $loadMoreButton.show();
        } else {
            $loadMoreButton.hide();
        }
    }

    function filterItems () {
        var key = $(this).val(), 
        masonryItems = $container.masonry('getItemElements');

        $container.masonry('remove', masonryItems); // Masonry 항목을 삭제
        filteredData = [];          // 필터링 된 항목의 데이터를 재설정
        addedd = 0;                 // 추가 된 항목 수를 재설정

        if (key === 'all') {
            filteredData = allData;
        } else {
            filteredData = $.grep(allData, function (item) {
                return item.category === key;
            });
        }

        addItems(true);
    }


    // 호버 효과
    function hoverDirection (event) {
        var $overlay = $(this).find('.caption'),
            side = getMouseDirection(event),
            animateTo,
            positionIn = { top: '0%',left: '0%'},
            positionOut = (function () {
                switch (side) {
                    // case 0: top, case 1: right, case 2: bottom, default: left
                    case 0:  return { top: '-100%', left:    '0%' }; break; // top
                    case 1:  return { top:    '0%', left:  '100%' }; break; // right
                    case 2:  return { top:  '100%', left:    '0%' }; break; // bottom
                    default: return { top:    '0%', left: '-100%' }; break; // left
                }
            })();
        if (event.type === 'mouseenter') {
            animateTo = positionIn;
            $overlay.css(positionOut);
        } else {
            animateTo = positionOut;
        }
        $overlay.stop(true).animate(animateTo, 250);
    }

    // 마우스 방향 감지
    function getMouseDirection (event) {
        var $el = $(event.currentTarget),
            offset = $el.offset(),
            w = $el.outerWidth(),
            h = $el.outerHeight(),
            x = (event.pageX - offset.left - w / 2) * ((w > h)? h / w: 1),
            y = (event.pageY - offset.top - h / 2) * ((h > w)? w / h: 1),
            direction = Math.round((Math.atan2(y, x) * (180 / Math.PI) + 180) / 90  + 3) % 4;
        return direction;
    }
});


});

'Js' 카테고리의 다른 글

addEventListener  (1) 2024.07.01
scroll, resize  (0) 2024.06.30
다크모드 로컬 저장  (0) 2024.06.30
플러그인없이 이미지 슬라이드  (0) 2024.06.30
rect() 를 이용한 마스크 효과  (0) 2024.06.30
플러그인 없이 패럴렉스 효과  (0) 2024.06.29
플러그인 없이 원페이지 메뉴 스크롤하기  (0) 2024.06.29
썸네일이 있는 갤러리  (0) 2024.06.29