新增第150个小实例:仿制B站PC端首页的吃豆人轮播图

This commit is contained in:
DESKTOP-BM6RJU5\wyanh 2022-05-12 17:23:18 +08:00
parent c6cc664e6b
commit fb35f1e54e
5 changed files with 343 additions and 1 deletions

9
.gitignore vendored
View File

@ -26,3 +26,12 @@ images/144/3.jpg
images/147/1.jpg
images/147/2.jpg
images/147/3.jpg
images/150/1.jpg
images/150/2.jpg
images/150/3.jpg
images/150/4.jpg
images/150/5.jpg
images/150/6.jpg
images/150/7.jpg
images/150/8.jpg
images/150/9.jpg

View File

@ -156,4 +156,5 @@
146. HTML5+CSS3+JS小实例祝福版的3D标签云动画特效
147. HTML5+CSS3小实例关门式的图文组合悬停特效
148. HTML5+CSS3+JS小实例简约的垂直选项卡
149. HTML5+CSS3+JS小实例可切换方向的无缝衔接图片滚动效果
149. HTML5+CSS3+JS小实例可切换方向的无缝衔接图片滚动效果
150. HTML5+CSS3+Vue小实例仿制B站PC端首页的吃豆人轮播图

173
code/150/150.css Normal file
View File

@ -0,0 +1,173 @@
*{
margin: 0;
padding: 0;
}
body{
/* 100%窗口高度 */
height: 100vh;
/* 弹性布局 居中显示 */
display: flex;
justify-content: center;
align-items: center;
/* 渐变背景 */
background: linear-gradient(200deg,#e6e9f0,#eef1f5);
}
li{
list-style: none;
}
.container{
width: 488px;
height: 360px;
border-radius: 6px;
overflow: hidden;
}
.img-box{
height: 275px;
display: flex;
/* 计算图片偏移量,--m-left是自定义属性,在js中赋值 */
margin-left: calc(-488px * var(--m-left));
/* 过渡 */
transition: 0.35s;
}
.img-box img{
width: 488px;
height: 100%;
object-fit: cover;
object-position: center;
}
.bottom-box{
/* 计算底部区域高度 */
height: calc(360px - 275px);
display: flex;
/* --b-color是自定义属性在js中会进行动态赋值 */
--b-color: #000;
background-color: var(--b-color);
color: #fff;
/* 相对定位 */
position: relative;
}
/* 图片底部的渐变部分 */
.bottom-box::before{
content: "";
width: 100%;
height: 50px;
/* 背景渐变(透明——底部区域同色,上到下) */
background: linear-gradient(to bottom,transparent,var(--b-color));
/* 绝对定位 位置上移它的高度 */
position: absolute;
top: -50px;
}
/* 底部区域的左侧部分 */
.bottom-box .l-box{
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 12px;
/* 计算宽度 */
width: calc(488px - 92px - 12px);
}
.bottom-box .title{
width: 100%;
font-size: 18px;
line-height: 25px;
/* 标题不换行,溢出显示省略号 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.bottom-box .dots{
display: flex;
margin-top: 10px;
}
/* 指示器(小圆点) */
.bottom-box li{
width: 8px;
height: 8px;
background-color: rgba(255,255,255,0.4);
margin: 4px;
border-radius: 50%;
cursor: pointer;;
}
/* 指示器选中态(吃豆人) */
.bottom-box li.pacman{
position: relative;
width: 14px;
height: 14px;
background-color: transparent;
margin-top: 1px;
}
/* 吃豆人由两个div组成 */
.bottom-box li.pacman div{
width: 0;
height: 0;
border: 7px solid #fff;
border-radius: 50%;
border-right-width: 7px;
border-right-color: transparent;
/* 绝对定位 两个重合 */
position: absolute;
}
/* 吃豆人朝向左 */
.bottom-box li.pacman.l{
transform: rotate(180deg);
}
/* 接下来分别为吃豆人的两个部分设置动画 */
.bottom-box li.pacman div:nth-child(1){
/* 执行动画:动画名 时长 线性的 停留在最后一帧 */
animation: pacman1 0.75s linear forwards;
}
.bottom-box li.pacman div:nth-child(2){
animation: pacman2 0.75s linear forwards;
}
/* 底部区域的右侧部分 */
.bottom-box .r-box{
display: flex;
padding-top: 12px;
padding-left: 12px;
}
/* 上一页、下一页按钮 */
.bottom-box .r-box i{
background-color: rgba(255,255,255,0.1);
width: 28px;
height: 28px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 8px;
font-size: 16px;
margin-right: 12px;
}
.bottom-box .r-box i:hover{
cursor: pointer;
background-color: rgba(255,255,255,0.2);
}
/* 定义吃豆人动画 */
@keyframes pacman1 {
0%{
transform: rotate(360deg);
}
40%{
transform: rotate(270deg);
}
60%{
transform: rotate(360deg);
}
100%{
transform: rotate(270deg);
}
}
@keyframes pacman2 {
0%{
transform: rotate(0deg);
}
40%{
transform: rotate(90deg);
}
60%{
transform: rotate(0deg);
}
100%{
transform: rotate(90deg);
}
}

42
code/150/150.html Normal file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>仿制B站PC端首页的吃豆人轮播图</title>
<!-- 引入字体图标库 -->
<link rel="stylesheet" href="/fonts/css/font-awesome.css">
<link rel="stylesheet" href="150.css">
<!-- 这个案例用到的是vue的语法 -->
<script src="/js/vue.min.js"></script>
</head>
<body>
<div class="container" id="app" @mouseover="stopAutoPlay" @mouseout="startAutoPlay">
<div class="img-box">
<img :src="item.image" alt="" v-for="item in list">
</div>
<div class="bottom-box" :style="{'--b-color':list[0].bottom_color}">
<div class="l-box">
<div class="title">{{list[active_index].title}}</div>
<ul class="dots">
<li :class="[index==active_index?'pacman':'dot',is_prev?'l':'']" v-for="(item,index) in list" @click="changeBanner(index)">
<!-- 吃豆人 -->
<div v-if="index==active_index"></div>
<div v-if="index==active_index"></div>
</li>
</ul>
</div>
<div class="r-box">
<i class="fa fa-angle-left" @click="changeBanner(-1,true)"></i>
<i class="fa fa-angle-right" @click="changeBanner(-1,false)"></i>
</div>
</div>
</div>
</body>
</html>
<script src="150.js"></script>

117
code/150/150.js Normal file
View File

@ -0,0 +1,117 @@
new Vue({
el:'#app',
data:{
timer:null, //定时器
active_index:0, //当前轮播下标
is_prev:false, //是否点击上一张(控制吃豆人朝向)
// 轮播图数据(json格式)
list:[{
title:'标题一',
image:'/images/150/1.jpg',
bottom_color:'#AB2E3E'
},
{
title:'标题二',
image:'/images/150/2.jpg',
bottom_color:'#2c84cd'
},
{
title:'标题三',
image:'/images/150/3.jpg',
bottom_color:'#49a4d8'
},
{
title:'标题四',
image:'/images/150/4.jpg',
bottom_color:'#4e4e4e'
},
{
title:'标题五',
image:'/images/150/5.jpg',
bottom_color:'#623E26'
},
{
title:'标题六',
image:'/images/150/6.jpg',
bottom_color:'#93504D'
},
{
title:'标题七',
image:'/images/150/7.jpg',
bottom_color:'#212121'
},
{
title:'标题八',
image:'/images/150/8.jpg',
bottom_color:'#000000'
},
{
title:'标题九',
image:'/images/150/9.jpg',
bottom_color:'#972924'
}]
},
methods:{
// 停止轮播
stopAutoPlay(){
// 清空定时器
for(let i=0;i<=this.timer;i++){
clearInterval(i);
}
},
// 开始轮播
startAutoPlay(){
// 停止轮播
this.stopAutoPlay();
let _t=this;
this.timer=setInterval(function(){
_t.active_index++;
if(_t.active_index>_t.list.length-1){
_t.active_index=0;
}
_t.is_prev=false;
_t.changeBanner(_t.active_index);
},3000);
},
// 切换banner 参数:index=轮播下标(点击上一张,下一张按钮时,该值为-1;点击指示器时,该值为对应的轮播下标),is_prev=是否上一张(true为上一张,false为下一张)
changeBanner(index,is_prev){
if(index>=0){
// 点击指示器时
// 默认是下一张,吃豆人向右
this.is_prev=false;
if(index<this.active_index){
// 点击时轮播下标小于当前轮播下标时,则为上一张,吃豆人向左
this.is_prev=true;
}
// 设置当前轮播下标
this.active_index=index;
}else{
// 点击按钮时
if(is_prev){
// 上一张
this.active_index--;
if(this.active_index<0){
this.active_index=this.list.length-1;
}
}else{
// 下一张
this.active_index++;
if(this.active_index>this.list.length-1){
this.active_index=0;
}
}
// 指明上一张或下一张
this.is_prev=is_prev;
}
// --m-left,--c-color是css的自定义属性,可通过var函数进行调用
// 设置偏移量以达到显示指定图片的目的
document.querySelector('.img-box').style.setProperty('--m-left',this.active_index);
// 设置图片底部的渐变效果
document.querySelector('.bottom-box').style.setProperty('--b-color',this.list[this.active_index].bottom_color);
}
},
mounted(){
// 初始化,自动轮播
this.startAutoPlay();
}
})