Very wow web special effects Ferris wheel photo album

Valentine's Day is here, and I would like to share with you a photo album page with the effect of imitating a ferris wheel. The effect is as follows:

The main part of the page is a list of images, wrapped in 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>

        ......

Then set the image position, z-index, transparency, and tilt angle through the style:

        .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);
        }

Among them --active indicates the ratio of the difference between the picture and the picture on the top layer. For example, if the fifth picture is currently displayed, the fourth picture's --active = (4-5) / (total number of pictures --items= 10). --zIndex indicates the z-index of the image.

After the style is set, add monitoring events to both the picture and the page. Clicking on the picture when the event is clicked will display the picture to the top layer, and the scrolling event will display the pictures forward and backward in order.

        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);

The main method is to obtain the index of the target image through events, and then modify the --active and --zIndex values ​​of all image styles to achieve animation effects:

        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)));

Page code download: https://download.csdn.net/download/evanyanglibo/87450156

Guess you like

Origin blog.csdn.net/evanyanglibo/article/details/129023302