实现的功能为一个轮播图,分为纵向四栏,切换的时候四部分延迟切换。
主题思想:将底部整体的div分为四部分,纵向四等分,每部分都是当前要展示的图片,通过定位拼接到一起,看起来跟原版的图片一样,给四部分css设置时间,从左往右依次递增,这样切换的时候就会依次出现了。css部分不细讲,这里主要讲一下函数组件怎么写
import React, { useState, useEffect } from "react";
import "./index.css";
export default function Staring() {
const [activeSlide, setactiveSlide] = useState(-1);
const [prevSlide, setprevSlide] = useState(-1);
const [sliderReady, setsliderReady] = useState(false);
let IMAGE_PARTS = 4;
useEffect(() => {
setTimeout(() => {
setactiveSlide(0);
setsliderReady(true);
}, 0);
}, []);
function changeSlides(change) {
const { length } = slides;
const prevSlide1 = activeSlide;
let activeSlide1 = prevSlide1 + change;
if (activeSlide1 < 0) activeSlide1 = length - 1;
if (activeSlide1 >= length) activeSlide1 = 0;
setactiveSlide(activeSlide1);
setprevSlide(prevSlide1);
}
const slides = [
{
name: "杨扬",
message:
"杨扬在2002年盐湖城冬奥会上,为中国获得了第一枚冬奥会金牌。2006年都灵冬奥会结束后,杨扬宣布退出国家队。2010年2月,她以退役运动员身份当选国际奥委会委员。",
img: "img/stars/yangyang600.jpg",
},
{
name: "张虹",
message:
"张虹在2014年索契冬奥会速度滑冰女子1000米决赛中,滑出了1分14秒02的成绩,力压其他选手夺冠,这是中国冬奥会历史上的第一枚速度滑冰金牌。",
img: "img/stars/zhanghong600.jpg",
},
{
name: "李坚柔",
message:
"李坚柔在索契冬奥会短道速滑女子500米决赛中获得冠军,为中国代表团夺得索契冬奥会首枚金牌。",
img: "img/stars/lijianrou600.jpg",
},
{
name: "王濛",
message:
"王濛在2006年都灵冬奥会获得短道速滑女子500米冠军,4年后又在温哥华冬奥会上夺得短道速滑女子500米、1000米以及3000米接力的金牌。",
img: "img/stars/wangmeng600.jpg",
},
{
name: "申雪/赵宏博",
message:
"申雪、赵宏博在2010年温哥华冬奥会上力压庞清、佟健及德国组合夺冠,完成花样滑冰双人滑项目的大满贯。2012年2月,两人退役。",
img: "img/stars/shenxuezhaohongbo190.jpg",
},
{
name: "韩晓鹏",
message:
"韩晓鹏在2006年都灵冬奥会上一鸣惊人,在决赛中以250.77分力挫群雄,以完美的两个动作获得了都灵冬奥会自由式滑雪男子空中技巧金牌,也是中国第一枚自由式滑雪项目的金牌 。",
img: "img/stars/hanxiaopeng600.jpg",
},
{
name: "金妍儿",
message:
"1990年9月出生,韩国著名女单花样滑冰运动员,出生于韩国京畿道富川市。7岁开始学习花样滑冰。2009年洛杉矶世锦赛上,金妍儿以创造女子短节目和总成绩两项记录的成绩获得冠军。",
img: "img/stars/jinyaner_big.jpg",
},
{
name: "浅田真央",
message:
"日本著名花样滑冰选手,出生于爱知县名古屋市,她是亚洲第一位三次夺得世界花样滑冰锦标赛金牌并赢得三次“世界冠军”头衔的女子单人滑选手。",
img: "img/stars/qiantianzhenyang_big.jpg",
},
{
name: "普鲁申科",
message:
"1982年11月出生,俄罗斯花样滑冰男子单人滑选手。国际滑冰联盟花样滑冰大奖赛分站冠军、世界花样滑冰青年锦标赛冠军、欧洲青年奥运会冠军、友好运动会冠军。",
img: "img/stars/pulushenke_big.jpg",
},
{
name: "安贤洙",
message:
"1985年出生,俄罗斯籍韩国裔男子短道速滑运动员。加入俄罗斯籍并出战2014年索契冬奥会,并获得男子个人1000米冠军,以及1500米季军,500米冠军和5000米接力金牌",
img: "img/stars/name_ann.png",
},
{
name: "奥拉·比约达伦",
message:
"挪威滑雪运动员,绰号“国王”,曾在2002年冬奥会冬季两项项目一人独得男子10公里、15公里和12.5公里追逐赛三枚金牌,被誉为“冬季两项之王”。",
img: "img/stars/biyuedalun_big.jpg",
},
{
name: "劳琳-威廉姆斯",
message:
"1983年出生,美国运动员,世界上跑的最快的女飞人之一,在2005年的赫尔辛基世界田径锦标赛上,威廉姆斯以10秒93获得了女子100米比赛金牌",
img: "img/stars/weilianmusi.jpg",
},
{
name: "肖恩-怀特",
message:
"1986年出生,单板滑雪运动员,曾获得2006年,2010年冬奥会单板滑雪U型槽男子冠军。绰号飞翔的番茄。他是世界上最好的单板滑雪选手、最有才能的滑板选手之一。",
img: "img/stars/huaite.jpg",
},
{
name: "佩希施泰因",
message:
"1972年出生,德国速度滑冰的女运动员。德国成就最大的冬奥会选手,共获得5枚奥运金牌、2枚奥运银牌和2枚奥运铜牌。",
img: "img/stars/peisixidaien.jpg",
},
];
function slideName(index) {
if (activeSlide === index && prevSlide === index) {
return "slider__slide s--active s--prev";
} else if (activeSlide === index && prevSlide !== index) {
return "slider__slide s--active";
} else if (activeSlide !== index && prevSlide === index) {
return "slider__slide s--prev";
} else if (activeSlide !== index && prevSlide !== index) {
return "slider__slide";
}
}
return (
<>
<div className={sliderReady ? "slider s--ready" : "slider"}>
<p className="slider__top-heading">奥运明星</p>
<div className="slider__slides">
{slides.map((slide, index) => (
<div className={slideName(index)} key={slide.name}>
<div className="slider__slide-content">
<h3 className="slider__slide-subheading">
{slide.message || slide.name}
</h3>
<h2 className="slider__slide-heading">
{slide.name.split("").map((l) => (
<span key={l}>{l}</span>
))}
</h2>
</div>
<div className="slider__slide-parts">
{[...Array(IMAGE_PARTS).fill()].map((x, i) => (
<div className="slider__slide-part" key={i}>
<div
className="slider__slide-part-inner"
style={{ backgroundImage: `url(${slide.img})` }}
></div>
</div>
))}
</div>
</div>
))}
</div>
<div className="slider__control" onClick={() => changeSlides(-1)}></div>
<div
className="slider__control slider__control--right"
onClick={() => changeSlides(1)}
></div>
</div>
</>
);
}
设置三个值,当前页,上一页和是否开始
页面初始化阶段将是否开始设置为true,当前页为0。
点击上下页时调用函数,传入一个值,如果是下一个就传入1,如果上一页就传入-1
讲当前页的值加上传入的值,然后判断是否超出范围(小于0或者大于length),超出范围作出对应处理
内容中根据当前值去获取对应的数据,这样通过useState改变数据后页面数据也会对应改变,因为css时间的问题,所以就会产生层次变换。
最后附上css代码
h3,
h2 {
color: #fff;
}
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: "Roboto", Helvetica, Arial, sans-serif;
}
.slider {
overflow: hidden;
position: relative;
height: 100vh;
color: #fff;
}
.slider__top-heading {
z-index: 12;
position: absolute;
left: 0;
top: 100px;
width: 100%;
text-align: center;
font-size: 20px;
text-transform: uppercase;
letter-spacing: 2.5px;
transition: all 0.5s 1s;
transform: translateY(-30px);
opacity: 0;
}
.slider.s--ready .slider__top-heading {
transform: translateY(0);
opacity: 1;
}
.slider__slides {
position: relative;
height: 100%;
}
.slider__slide {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.slider__slide.s--active {
pointer-events: auto;
}
.slider__slide-content {
z-index: 6;
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100%;
text-transform: uppercase;
}
.slider__slide-subheading {
margin: 0 50px 50px 50px;
font-size: 24px;
letter-spacing: 2px;
transform: translateY(20px);
opacity: 0;
transition: 0.5s;
}
.slider__slide.s--active .slider__slide-subheading {
transition-delay: 0.65s;
opacity: 1;
transform: translateY(0);
}
.slider__slide-heading {
display: flex;
margin-bottom: 20px;
font-size: 60px;
letter-spacing: 12px;
}
.slider__slide-heading span {
display: block;
opacity: 0;
transform: translateY(-60px);
transition: all 0.3333333333s;
}
.slider__slide.s--prev .slider__slide-heading span {
transform: translateY(60px);
}
.slider__slide.s--active .slider__slide-heading span {
opacity: 1;
transform: translateY(0);
}
.slider__slide-heading span:nth-child(1) {
transition-delay: 0s;
}
.slider__slide.s--active .slider__slide-heading span:nth-child(1) {
transition-delay: 0.3333333333s;
}
.slider__slide-heading span:nth-child(2) {
transition-delay: 0.1s;
}
.slider__slide.s--active .slider__slide-heading span:nth-child(2) {
transition-delay: 0.4333333333s;
}
.slider__slide-heading span:nth-child(3) {
transition-delay: 0.2s;
}
.slider__slide.s--active .slider__slide-heading span:nth-child(3) {
transition-delay: 0.5333333333s;
}
.slider__slide-heading span:nth-child(4) {
transition-delay: 0.3s;
}
.slider__slide.s--active .slider__slide-heading span:nth-child(4) {
transition-delay: 0.6333333333s;
}
.slider__slide-heading span:nth-child(5) {
transition-delay: 0.4s;
}
.slider__slide.s--active .slider__slide-heading span:nth-child(5) {
transition-delay: 0.7333333333s;
}
.slider__slide-heading span:nth-child(6) {
transition-delay: 0.5s;
}
.slider__slide.s--active .slider__slide-heading span:nth-child(6) {
transition-delay: 0.8333333333s;
}
.slider__slide-heading span:nth-child(n+7) {
transition-delay: 0.6s;
}
.slider__slide.s--active .slider__slide-heading span:nth-child(n+7) {
transition-delay: 0.9333333333s;
}
.slider__slide-readmore {
position: relative;
font-size: 14px;
text-transform: lowercase;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
transform: translateY(-20px);
cursor: pointer;
opacity: 0;
transition: 0.5s;
}
.slider__slide.s--active .slider__slide-readmore {
transition-delay: 0.65s;
opacity: 1;
transform: translateY(0);
}
.slider__slide-readmore:before {
content: "";
position: absolute;
left: -2px;
top: -3px;
width: calc(100% + 4px);
height: calc(100% + 6px);
background: rgba(255, 255, 255, 0.4);
transform: scaleX(0.3);
transform-origin: 0 50%;
transition: transform 0.3s;
}
.slider__slide-readmore:hover:before {
transform: scaleX(1);
}
.slider__slide-parts {
position: absolute;
left: 0;
top: 0;
display: flex;
width: 100%;
height: 100%;
}
.slider__slide-parts:after {
content: "";
z-index: 5;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.1);
}
.slider__slide-part {
position: relative;
width: 25%;
height: 100%;
}
.slider__slide-part-inner {
overflow: hidden;
position: relative;
width: 100%;
height: 100%;
background-size: 0 0;
background-repeat: no-repeat;
transition: transform 0.5s ease-in-out;
}
.slider__slide-part-inner:before {
content: "";
position: absolute;
width: 100vw;
height: 100%;
background-image: inherit;
background-size: cover;
background-position: center center;
transition: opacity 0.25s;
opacity: 0;
}
.slider__slide-part:nth-child(1) .slider__slide-part-inner {
z-index: 3;
transition-delay: 0.24s;
transform: translateX(-32.5%);
}
.slider__slide.s--active .slider__slide-part:nth-child(1) .slider__slide-part-inner {
transition-delay: 0.28s;
}
.slider__slide-part:nth-child(1) .slider__slide-part-inner:before {
left: 0vw;
transition-delay: 0.365s;
}
.slider__slide.s--active .slider__slide-part:nth-child(1) .slider__slide-part-inner:before {
transition-delay: 0.28s;
}
.slider__slide-part:nth-child(2) .slider__slide-part-inner {
z-index: 2;
transition-delay: 0.16s;
transform: translateX(-65%);
}
.slider__slide.s--active .slider__slide-part:nth-child(2) .slider__slide-part-inner {
transition-delay: 0.36s;
}
.slider__slide-part:nth-child(2) .slider__slide-part-inner:before {
left: -25vw;
transition-delay: 0.285s;
}
.slider__slide.s--active .slider__slide-part:nth-child(2) .slider__slide-part-inner:before {
transition-delay: 0.36s;
}
.slider__slide-part:nth-child(3) .slider__slide-part-inner {
z-index: 1;
transition-delay: 0.08s;
transform: translateX(-97.5%);
}
.slider__slide.s--active .slider__slide-part:nth-child(3) .slider__slide-part-inner {
transition-delay: 0.44s;
}
.slider__slide-part:nth-child(3) .slider__slide-part-inner:before {
left: -50vw;
transition-delay: 0.205s;
}
.slider__slide.s--active .slider__slide-part:nth-child(3) .slider__slide-part-inner:before {
transition-delay: 0.44s;
}
.slider__slide-part:nth-child(4) .slider__slide-part-inner {
z-index: 0;
transition-delay: 0s;
transform: translateX(-130%);
}
.slider__slide.s--active .slider__slide-part:nth-child(4) .slider__slide-part-inner {
transition-delay: 0.52s;
}
.slider__slide-part:nth-child(4) .slider__slide-part-inner:before {
left: -75vw;
transition-delay: 0.125s;
}
.slider__slide.s--active .slider__slide-part:nth-child(4) .slider__slide-part-inner:before {
transition-delay: 0.52s;
}
.slider__slide.s--active .slider__slide-part-inner {
transform: translateX(0);
transition-timing-function: ease;
}
.slider__slide.s--active .slider__slide-part-inner:before {
opacity: 1;
}
.slider__control {
z-index: 100;
position: absolute;
left: 50px;
top: 50%;
width: 50px;
height: 50px;
margin-top: -25px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.4);
transform: translateX(-50px);
opacity: 0;
transition: all 0.5s 1s;
cursor: pointer;
}
.slider__control:before {
content: "";
position: absolute;
left: 50%;
top: 50%;
width: 20px;
height: 20px;
margin-left: -10px;
margin-top: -10px;
border: 2px solid #000;
border-bottom: none;
border-right: none;
transform: translateX(5px) rotate(-45deg);
}
.slider__control--right {
left: auto;
right: 50px;
transform: translateX(50px);
}
.slider__control--right:before {
transform: translateX(-5px) rotate(135deg);
}
.slider.s--ready .slider__control {
transform: translateX(0);
opacity: 1;
}
.icon-link {
z-index: 100;
position: absolute;
left: 5px;
bottom: 5px;
width: 32px;
}
.icon-link img {
width: 100%;
vertical-align: top;
}
.icon-link--twitter {
left: auto;
right: 5px;
}
版权声明:本文为small_shadow原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。