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-style
,transform-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>
评论区