侧边栏壁纸
  • 累计撰写 53 篇文章
  • 累计创建 12 个标签
  • 累计收到 8 条评论

目 录CONTENT

文章目录

倒影轮播图

Kirito
2024-04-08 / 0 评论 / 0 点赞 / 36 阅读 / 5642 字 / 正在检测是否收录...

HTML和JS很简单,主要是CSS实现

<script setup lang="ts" name="index">
const images: string[] = [
  'https://images.wallpaperscraft.com/image/single/sakura_art_sky_122545_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/piano_silhouette_space_156662_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/creature_mystical_fantastic_139179_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/torii_art_solitude_129792_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/city_aerial_view_road_156925_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/japan_shirakawa_houses_112963_480x800.jpg'
]
</script>

<template>
  <div class="refection-carousel">
    <div class="carousel-container">
      <div class="card" v-for="(image, index) in images" :key="index" :style="`--i: ${index}`">
        <img :src="image" :alt="image" />
      </div>
    </div>
  </div>
</template>

:style:"--i: ${index}"此处利用了CSS中 var()函数,在这种 for循环 多个Dom元素时传参分别设置属性很有实用性,更多详细此处不描述。

倒影

-webkit-box-reflect: below 0.5rem
      linear-gradient(transparent 60%, transparent, rgba(0, 0, 0, 0.4));

看到 -webkit-就应该知道,这个属性在个别浏览器是存在兼容问题的,并非所有浏览器都可以实现此效果;

第一个参数 below表示了倒影的方向,above向上,below向下,left向左,right向右;

第二个参数表示本体Dom和倒影之间的间距;

第三个参数则可以做出蒙层效果,仅显示部分倒影。

3D 偏移

这里我使用了三层的结构,carousel为最外部的视角容器,container为实现旋转动画的辅助容器,以及最后的card主体。

perspective: 200rem; // 视图深度
transform-style: preserve-3d; // 3d 布局

为父元素设置这两个属性,可以确保我们的3D效果,此处为carousel设置 perspective,为container设置 transform-styletransform-style需设置给Card元素的最近父元素才会对子元素生效。

transform: rotateY(calc(var(--i) * 60deg)) translateZ(20rem);

利用 var()函数,给每个子元素设置不同的偏移量,实现我们想要的3D效果。

动画

@keyframes rotate {
  from {
    transform: rotateY(0deg);
  }
  to {
    transform: rotateY(360deg);
  }
}

.carousel-container {
  transform-style: preserve-3d; // 3d 布局
  animation: rotate 15s linear infinite; // 旋转容器
}

一个简单的旋转动画。

整体代码

<script setup lang="ts" name="index">
const images: string[] = [
  'https://images.wallpaperscraft.com/image/single/sakura_art_sky_122545_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/piano_silhouette_space_156662_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/creature_mystical_fantastic_139179_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/torii_art_solitude_129792_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/city_aerial_view_road_156925_480x800.jpg',
  'https://images.wallpaperscraft.com/image/single/japan_shirakawa_houses_112963_480x800.jpg'
]
</script>

<template>
  <div class="refection-carousel">
    <div class="carousel-container">
      <div class="card" v-for="(image, index) in images" :key="index" :style="`--i: ${index}`">
        <img :src="image" :alt="image" />
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
@keyframes rotate {
  from {
    transform: rotateY(0deg);
  }
  to {
    transform: rotateY(360deg);
  }
}
.refection-carousel {
  display: flex;
  flex: 1;
  justify-content: center;
  align-items: center;
  position: relative;
  perspective: 200rem; // 视图深度
  overflow: hidden;
  .carousel-container {
    display: flex;
    flex: 1;
    justify-content: center;
    align-items: center;
    transform-style: preserve-3d; // 3d 布局
    animation: rotate 15s linear infinite; // 旋转容器
  }
  .carousel-container:hover {
    animation-play-state: paused; // 动画暂停
  }
  .card {
    display: inline-flex;
    position: absolute;
    width: 10rem;
    border: 0.2rem solid rgba(217, 217, 217, 0.5);
    border-radius: 2rem;
    overflow: hidden;
    -webkit-box-reflect: below 0.5rem
      linear-gradient(transparent 60%, transparent, rgba(0, 0, 0, 0.4));
    transform: rotateY(calc(var(--i) * 60deg)) translateZ(20rem);
    img {
      width: 100%;
      height: calc(100% * 5 / 3);
    }
  }
}
</style>
0

评论区