使用 CSS 创建 3D 无限轮播图!

456 阅读4分钟

image.png

大家好!我想分享一些使用 CSS 创建无限轮播的 CSS 技巧。让我们开始吧。

HTML:

此 HTML 代码使用 <ul> 图库创建了一个图像轮播图。每个 <li> 包含一张图片和一个用于动画排序的 '--timer' 变量。

<section>
    <div class="carousel">
        <ul class="gallery">
            <li class="card" style="--timer: 1"><img src="img/1.jpg" alt=""></li>
            <li class="card" style="--timer: 2"><img src="img/2.jpg" alt=""></li>
            <li class="card" style="--timer: 3"><img src="img/3.jpg" alt=""></li>
            <li class="card" style="--timer: 4"><img src="img/4.jpg" alt=""></li>
            <li class="card" style="--timer: 5"><img src="img/3.jpg" alt=""></li>
            <li class="card" style="--timer: 6"><img src="img/2.jpg" alt=""></li>
            <li class="card" style="--timer: 7"><img src="img/1.jpg" alt=""></li>
            <li class="card" style="--timer: 8"><img src="img/2.jpg" alt=""></li>
            <li class="card" style="--timer: 9"><img src="img/3.jpg" alt=""></li>
        </ul>
    </div>
</section>

CSS:

--num 确定总图片数量。

--wd 确定 card div 的宽度。

* {
    margin: 0;
    padding: 0;
}

:root {
    --num: 9; /* 总图片数量 */
    --wd: 130; /* card 元素的宽度 */
    /* --gap: 20px; */
}

body {
    background-color: #e4e7ee;
}

section {
    width: clamp(480px, 80%, 90vw);
    margin: 0 auto;
}

.carousel {
    display: flex;
    align-items: flex-start;
    height: 100vh;
    overflow: hidden;
    /* 左右遮罩,类似渐变效果 */
    mask-image: linear-gradient(to right, transparent, #000 5% 95%, transparent);
}

.carousel .gallery {
    list-style-type: none;
    display: flex;
    align-items: center;
    width: 100%;
    height: 450px;
    position: relative;
    perspective: 40em;
}

.carousel .gallery .card {
    width: 130px;
    height: auto;
    position: absolute;
    transform-style: preserve-3d;
    left: 100%;
    animation: slide 9s linear infinite, scaleEffect 9s ease-in-out infinite;
    animation-delay: calc(9s * ((var(--timer) - 1) / var(--num) - 1));
    transition: transform 0.25s ease-in-out;
}

.carousel .gallery .card img {
    width: 100%;
    border-radius: 5px;
    box-shadow: 0px 0px 16px #cecece;
    /* 图片反射效果 */
    -webkit-box-reflect: below 0px linear-gradient(to bottom, rgba(0, 0, 0, 0.0), rgba(0, 0, 0, 0.4));
}

CSS 动画解释:

.carousel .gallery .card 中使用的动画:

slide 9s linear infinite:

以 9 秒为周期,无限次重复,以恒定速度移动元素。

scaleEffect 9s ease-in-out infinite:

在 9 秒内应用缩放效果,平滑加速和减速,无限重复。

animation-delay: calc(9s * ((var(--timer) - 1) / var(--num) - 1)):

根据每个元素的 --timer 值计算延迟,确保同步过渡。

slide 动画解释:

@keyframes slide: 定义了一个使元素水平移动的动画。

from { left: 100%; }: 从最右侧位置开始。

to { left: calc(-1 * var(--wd) * 1px); }: 向左移动 --wd 像素,完全移出视口。

此动画通常用于滚动效果,如连续移动的轮播图或新闻头条。

@keyframes slide {
    from {
        left: 100%;
    }

    to {
        left: calc(-1 * var(--wd)* 1px);
    }
}

缩放效果动画解释:

@keyframes scaleEffect: 定义了一个带有灰度和图层效果的缩放动画。

0%, 25%, 75%, 100%: 元素保持正常缩放(scale(1)),堆叠顺序较低(z-index: 0),完全灰度(grayscale(1))。

50%: 元素放大到两倍大小(scale(2)),移到前景(z-index: 10),完全着色(grayscale(0))。

此动画创建了一个脉冲式缩放效果,使元素动态弹出并淡入。

@keyframes scaleEffect {
    0%,
    25%,
    75%,
    100% {
        transform: scale(1);
        z-index: 0;
        filter: grayscale(1);
    }

    50% {
        transform: scale(2);
        z-index: 10;
        filter: grayscale(0);
    }
}

在下面的 GIF 中,你可以看到中心图像应用了缩放效果,以及两个相邻图像的中等缩放效果。

结果:

如果你只想让中心图像缩放,只需修改上面的 CSS 中的 scaleEffect

将 `@keyframes scaleEffect:` 中的 `0%, 25%, 75%, 100%` 替换为 `0%, 40%, 60%, 100%`。
然后你可以看到以下输出。

最后,让我们创建 3D 轮播图:

我已经在 .carousel .gallery 中设置了 perspective: 40em;,在 .carousel .gallery .card 中设置了 transform-style: preserve-3d;。现在,我们只需再次修改 scaleEffect

@keyframes scaleEffect {
    0%, 25%, 75%, 100% {
        transform: scale(1) rotateY(0deg);
        z-index: 0;
        filter: grayscale(1);
    }

    35% {
        transform: scale(1.25) rotateY(-45deg);
        z-index: 5;
        filter: grayscale(1);
    }

    50% {
        transform: scale(2) rotateY(0deg);
        z-index: 10;
        filter: grayscale(0);
    }

    65% {
        transform: scale(1.25) rotateY(45deg);
        z-index: 5;
        filter: grayscale(1);
    }
}

结果:

我们的 3D 轮播图 完成!不过,你仍然可以通过对 scaleEffect 进行微调来尝试不同的变换效果。

让我们创建 COVERFLOW

@keyframes scaleEffect {
    0%, 40%, 60%, 100% {
        transform: scale(1) rotateY(-90deg);
        z-index: 0;
        filter: grayscale(1);
    }

    50% {
        transform: scale(2) rotateY(0deg);
        z-index: 10;
        filter: grayscale(0);
    }
}

COVERFLOW 结果:

将 coverflow 代码中的变换值从 -90 改为 -180,得到以下输出。

transform: scale(1) rotateY(-180deg);

现在我们已经做了足够的修改,还剩下一个小调整。如果你想让每张图片从左到右依次缩放,而不仅仅是中心图片,请按照以下步骤操作:

  1. 注释掉 .carousel 中的 "mask" 效果和 "overflow: hidden"。
  2. .carousel .gallery 中添加 "margin-left: 50px;"。
  3. 注释掉 .carousel .gallery .card 中的 "position: absolute, left: 100%;",并添加 "margin: 0 20px;" 以增加图片之间的间隔。

这将产生以下输出。如有需要,进一步调整以满足你的需求。

.carousel {
    /* overflow: hidden; */
    /* mask-image: linear-gradient(to right, transparent, #000 5% 95%, transparent); */
}

.carousel .gallery {
    margin-left: 50px;
}

.carousel .gallery .card {
    /* position: absolute; */
    /* left: 100% */
    margin: 0 20px;
}

最后重要的是,它已经是响应式的!

如果你仍然想为不同屏幕调整图片大小,可以添加媒体查询。

/* 响应式 */
@media only screen and (max-width: 768px) {
    .carousel .gallery .card {
        width: calc(var(--wd) / 2 * 1px);
    }
}

感谢大家!

点击此处查看实际演示

原文:dev.to/prahalad/3d…