作一个ul列表结构的html
新建html,使用ul>li结构作图片容器:
<style>
:root {
--img-w: 200px;
--img-h: 200px;
}
body {
margin: 0;
padding: 0;
width: 100vw;
}
.carousel {
font-size: 0;
width: calc(var(--img-w) * 3);
position: relative;
top: 100px;
margin: 0 auto;
border: 10px solid rebeccapurple;
box-sizing: content-box;
/*overflow: hidden;*/
}
.carousel ul {
white-space: nowrap;
margin: 0;
padding: 0;
list-style-type: none;
}
.carousel ul li {
display: inline-block;
}
.carousel ul li img {
display: inline-block;
width: var(--img-w);
height: var(--img-h);
border: 1px solid red;
box-sizing: border-box;
}
</style>
<body>
<div id="app">
<div class="carousel">
<ul>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
</ul>
</div>
</div>
</body>
- 第一步,用
ul>li结构作为多张img的容器,到时轮播图片的动画就以ul元素整体移动,如图中的红色边框。 - 轮播需要只显示固定区域的画面,溢出的部分要hidden起来,所以外层套一个
div.carousel,如图中的粗线边框。 - 然后给
div.carousel设置position属性后用margin: 0 auto魔法把整个轮播图整体居中为了方便看。 - 因为
li设置成inline流动布局所以white-space: nowrap;可以生效不让行内元素li换行。
通过整体一个div.carousel,里面放ul.li,li里面放img图片,就构成了最基本的轮播图片模型!
下面我们给这个模型设置动画
只需要加上动画my_translate并设置关键帧@keyframes:
.carousel ul {
animation: my_translate 10s ease 1s infinite alternate;
}
@keyframes my_translate {
from {}
16% {translate: 0;}
33% {translate: calc(-1 * var(--img-w));}
49% {translate: calc(-2 * var(--img-w));}
65% {translate: calc(-3 * var(--img-w));}
81% {translate: calc(-4 * var(--img-w));}
to {translate: calc(-5 * var(--img-w));}
/*100% {translate: calc(-6 * var(--img-w));}*/
/*100% {translate: calc(-7 * var(--img-w));}*/
}
animation属性中第一个时间是整个动画的时间,第二个时间是延迟多久开始播放动画。
ease是每一帧动画的样式,表示首尾慢、中间快。
infinite表示播放无穷次。
alternate表示动画关键帧播放到to(100%)之后,倒过来播放,也就是一来一回为一次动画。
放开.carousel { overflow: hidden;}的注释后,效果如下:
最后,我们来给li元素添加轮播图片进去
给img加上自适应宽高属性object-fit和object-position
.carousel ul li img {
object-fit: cover;
object-position: center center;
}
然后使用js动态加载图片的src:
const srcString ="'https://img2.baidu.com/it/u=421347826,2792415000&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img2.baidu.com/it/u=3123880262,455523890&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img0.baidu.com/it/u=4139606063,194286789&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img0.baidu.com/it/u=130504489,1044576680&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img0.baidu.com/it/u=2696759067,1221490204&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img1.baidu.com/it/u=1423197334,186448263&fm=253&fmt=auto&app=138&f=JPEG?w=491&h=492', " +
"'https://img2.baidu.com/it/u=2391751777,1392423538&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img1.baidu.com/it/u=2241852295,652512022&fm=253&fmt=auto&app=138&f=JPEG?w=523&h=500'";
const imgNodeList = document.querySelectorAll(".carousel ul li img");
srcString.split(", ").forEach((src, index) => {
console.log(src)
imgNodeList[index].setAttribute("src", src.substring(1, src.length - 1));
});
图片动画效果如下:
总结上面3步:
- 第一步,html里,用一个
div,包裹住一个ul列表,li里面放img。 - 第二步,把li设置成行内
inline元素,然后设置nowrap不给换行。 - 第三步,给ul元素加
动画animation,动画效果就是translate-x水平位移,看起来就像是轮播。 - 补充:这里的img.src是JavaScript动态加载
- 补充:其中
font-size: 0; padding: 0;等其他不相关样式只是为了清除空白间隙。
最后,我们来美化轮播的样式效果
- 设置图片的外边距:
:root {
--img-w: 200px;
--img-h: 200px;
--img-m: 10px;
--img-x: calc(var(--img-w) + var(--img-m) * 2);
}
如上,我们之前在:root中设置图片的宽度--img-w,现在在img样式中给每个img加上--img-m的外边距。
那么,包裹ul>li>img的外层div.carousel也需要调整能够展示3个img的宽度(高度自适应就可以)。这里我们算好一个img加上边距的宽度是--img-x,然后统一用这个单位来计算:
.carousel ul li img {
width: var(--img-w);
height: var(--img-h);
/* 左右边距 --img-m */
margin: 15px var(--img-m);
}
.carousel {
/* 外层div设置为3个img(包括左右边距)的总宽度 */
width: calc(var(--img-x) * 3);
}
/*动画每一帧偏移宽度是img的整体宽度 */
@keyframes my_translate {
from {}
16% {translate: 0;}
33% {translate: calc(-1 * var(--img-x));}
49% {translate: calc(-2 * var(--img-x));}
65% {translate: calc(-3 * var(--img-x));}
81% {translate: calc(-4 * var(--img-x));}
to {translate: calc(-5 * var(--img-x));}
/*100% {translate: calc(-6 * var(--img-w));}*/
/*100% {translate: calc(-7 * var(--img-w));}*/
}
- 修改
div.carousel 和 img的box-shadow模糊效果样式、边框效果
.carousel {
border: 10px inset rebeccapurple;
box-shadow: 1px 1px 20px #999999;
}
.carousel ul li img {
border: 5px outset gold;
box-shadow: 1px 1px 10px dimgrey;
}
如上,border: inset就是设置边框内嵌,outset是外凸的效果。
box-shadow设置盒子边框阴影效果。1px 1px代表阴影区域的x、y偏移,第三个px是阴影放大模糊度,最后一个是颜色。
好了,修改好之后效果如下: github.lwrong.com/carousel.ht…
附上整体代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=0.5"/>
<meta name="keywords" content="轮播"/>
<title>轮播图</title>
<meta name="description" content="手写轮播图">
<style>
:root {
--img-w: 200px;
--img-h: 200px;
--img-m: 10px;
--img-x: calc(var(--img-w) + var(--img-m) * 2);
}
body {
margin: 0;
padding: 0;
width: 100vw;
}
.carousel {
font-size: 0;
width: calc(var(--img-x) * 3);
position: relative;
top: 100px;
margin: 0 auto;
border: 10px inset rebeccapurple;
box-shadow: 1px 1px 20px 5px #999999;
overflow: hidden;
}
.carousel ul {
white-space: nowrap;
margin: 0;
padding: 0;
list-style-type: none;
animation: my_translate 10s ease 1s infinite alternate;
}
@keyframes my_translate {
from {
}
16% {
translate: 0;
}
33% {
translate: calc(-1 * var(--img-x));
}
49% {
translate: calc(-2 * var(--img-x));
}
65% {
translate: calc(-3 * var(--img-x));
}
81% {
translate: calc(-4 * var(--img-x));
}
to {
translate: calc(-5 * var(--img-x));
}
/*100% {translate: calc(-6 * var(--img-w));}*/
/*100% {translate: calc(-7 * var(--img-w));}*/
}
.carousel ul li {
display: inline-block;
}
.carousel ul li img {
width: var(--img-w);
height: var(--img-h);
margin: 15px var(--img-m);
border: 10px outset gold;
box-sizing: border-box;
box-shadow: 1px 1px 10px 5px dimgrey;
object-fit: cover;
object-position: center center;
}
</style>
</head>
<body>
<div id="app">
<div class="carousel">
<ul>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
<li><img src="" alt=""/></li>
</ul>
</div>
</div>
</body>
<script>
const srcString = "'https://img2.baidu.com/it/u=421347826,2792415000&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img2.baidu.com/it/u=3123880262,455523890&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img0.baidu.com/it/u=4139606063,194286789&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img0.baidu.com/it/u=130504489,1044576680&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img0.baidu.com/it/u=2696759067,1221490204&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img1.baidu.com/it/u=1423197334,186448263&fm=253&fmt=auto&app=138&f=JPEG?w=491&h=492', " +
"'https://img2.baidu.com/it/u=2391751777,1392423538&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500', " +
"'https://img1.baidu.com/it/u=2241852295,652512022&fm=253&fmt=auto&app=138&f=JPEG?w=523&h=500'";
const imgNodeList = document.querySelectorAll(".carousel ul li img");
srcString.split(", ").forEach((src, index) => {
console.log(src)
imgNodeList[index].setAttribute("src", src.substring(1, src.length - 1));
});
</script>
</html>