天天看點

很哇塞的網頁特效之摩天輪相冊

情人節到了,給大家分享一個仿摩天輪效果的相冊頁面,效果如下圖:

很哇塞的網頁特效之摩天輪相冊

頁面主要部分是圖檔清單,使用div包裹:

        <div class="carousel-item">
            <div class="carousel-box">
                <div class="title">北京</div>
                <div class="num">01</div>
                <img src="aaa.jpg"
                />
            </div>
        </div>

        <div class="carousel-item">
            <div class="carousel-box">
                <div class="title">上海</div>
                <div class="num">02</div>
                <img src="bbb.jpg" />
            </div>
        </div>

        ......
           

然後通過樣式設定圖檔位置、z-index、透明度、傾斜角度:

        .carousel-item {
            --items: 10;
            --width: clamp(150px, 30vw, 300px);
            --height: clamp(200px, 40vw, 400px);
            --x: calc(var(--active) * 800%);
            --y: calc(var(--active) * 200%);
            --rot: calc(var(--active) * 120deg);
            --opacity: calc(var(--zIndex) / var(--items) * 3 - 2);
            overflow: hidden;
            position: absolute;
            z-index: var(--zIndex);
            width: var(--width);
            height: var(--height);
            margin: calc(var(--height) * -0.5) 0 0 calc(var(--width) * -0.5);
            border-radius: 10px;
            top: 50%;
            left: 50%;
            user-select: none;
            transform-origin: 0% 100%;
            box-shadow: 0 10px 50px 10px rgba(0, 0, 0, .5);
            background: black;
            pointer-events: all;
            transform: translate(var(--x), var(--y)) rotate(var(--rot));
            transition: transform .8s cubic-bezier(0, 0.02, 0, 1);
        }
           

其中 --active 表示圖檔相對于正在頂層的圖檔比較的內插補點比例,比如目前展示第5張圖檔,則第四張圖檔的 --active = (4-5) / (總圖檔數量 --items=10)。--zIndex表示圖檔的z-index。

樣式設定好後,再給圖檔和頁面都加上監聽事件,點選事件時點選圖檔則将該圖檔展示到最上層,滾動事件則向前向後按順序展示圖檔。

        const $items = document.querySelectorAll('.carousel-item');        
        $items.forEach((item, i) => {
            item.addEventListener('click', () => {
                progress = (i / $items.length) * 100 + 10;
                animate();
            })
        });

        document.addEventListener('mousewheel', handleWheel);
        document.addEventListener('mousedown', handleMouseDown);
        document.addEventListener('mousemove', handleMouseMove);
        document.addEventListener('mouseup', handleMouseUp);
        document.addEventListener('touchstart', handleMouseDown);
        document.addEventListener('touchmove', handleMouseMove);
        document.addEventListener('touchend', handleMouseDown);
           

主要的方法是通過事件擷取目标圖檔的index,再修改全部圖檔樣式的 --active和 --zIndex 值進而實作動畫效果:

        const animate = () => {
            progress = Math.max(0, Math.min(progress, 100));
            active = Math.floor(progress / 100 * ($items.length - 1));

            $items.forEach((item, index) => displayItems(item, index, active));
        };

        const displayItems = (item, index, active) => {
            const zIndex = getZindex([...$items], active)[index];
            item.style.setProperty('--zIndex', zIndex);
            item.style.setProperty('--active', (index - active) / $items.length);
        };

        const getZindex = (array, index) => (array.map((_, i) => (index === i) ? array.length : array.length - Math.abs(index - i)));
           

頁面代碼下載下傳:https://download.csdn.net/download/evanyanglibo/87450156