大屏可视化项目中的旋转木马的实现

  • react框架

css的样式代码如下

.carousel{
    color: #fff;
    margin-top: 80px;
    text-align: center;
    position: relative;
    width: 100%;
    height: 350px;
}
.carousel-item{
    width: 160px;
    font-size: 14px;
    height: 150px;
    position: absolute;
    left: 0;
    top: 0;
    animation-name: xAni,yAni,scaleAni;
    animation-iteration-count: infinite;
    animation-duration: 10s,10s,20s;
    animation-timing-function: cubic-bezier(0.36, 0, 0.64, 1);
    animation-direction: alternate;
}
.carousel-item p{
    padding: 0;
    margin: 0;
}
/* 定义动画 */
@keyframes xAni {
    0% {
        left: -50px;
    }
    100% {
        left: calc(100% - 110px);
    }
}
@keyframes yAni {
    0% {
        top: 0;
    }
    100% {
        top: 100%;
    }
}
@keyframes scaleAni {
    0% {
        transform: scale(0.5);
    }
    50% {
        transform: scale(1);
    }
    100% {
        transform: scale(0.5);
    }
}

主页面的代码

// 导入样式
import "./carousel.css"
// 导入图片
import dingwei from '../../../assets/images/dingwei_nor.png'
import dingwei_hov from '../../../assets/images/dingwei_hov.png'
import fenxi from '../../../assets/images/fenxi_nor.png'
import fenxi_hov from '../../../assets/images/fenxi_hov.png'
import huaxiang from '../../../assets/images/huaxiang_nor.png'
import huaxiang_hov from '../../../assets/images/huaxiang_hov.png'
import jiankong from '../../../assets/images/jiankong_nor.png'
import jiankong_hov from '../../../assets/images/jiankong_hov.png'
import tingche from '../../../assets/images/tingche_nor.png'
import tingche_hov from '../../../assets/images/tingche_hov.png'
import toukui from '../../../assets/images/toukui_nor.png'
import toukui_hov from '../../../assets/images/toukui_hov.png'

// 导入hooks
import {useRef, useEffect, useState} from 'react'
const Carousel = () => {
    // 定义数据用于渲染旋转木马
    const [data, setData] = useState([
        {
            id: 1,
            url: dingwei,
            hov_url: dingwei_hov,
            text: '车辆定位系统',
            active: false
        },
        {
            id: 2,
            url: fenxi,
            hov_url: fenxi_hov,
            text: '可视化作战平台',
            active: false
        },
        {
            id: 3,
            url: huaxiang,
            hov_url: huaxiang_hov,
            text: '交通安全画像系统',
            active: false
        },
        {
            id: 4,
            url: jiankong,
            hov_url: jiankong_hov,
            text: '交通态势监控系统',
            active: false
        },
        {
            id: 5,
            url: tingche,
            hov_url: tingche_hov,
            text: '自动停车系统',
            active: false
        },
        {
            id: 6,
            url: toukui,
            hov_url: toukui_hov,
            text: '未带头盔识别系统',
            active: false
        }
    ])
    // 定义变量用于获取标签
    const carouselBox = useRef(null)
    // 模拟生命周期中获取标签
    useEffect(() => {
        // console.log(111, carouselBox.current.children);
        // 遍历所有子标签设置延迟动画的时间
        for (let a = 0; a < carouselBox.current.children.length; a++) {
            carouselBox.current.children[a].style['animation-delay'] = `${-5 - a * 3.3}s,-${a * 3.3}s,-${a * 3.3}s`
        }
    }, [])
    // 事件函数
    const onmouseenter = (id) => {
        // 让动画停止
        for (let a = 0; a < carouselBox.current.children.length; a++) {
            carouselBox.current.children[a].style['animation-play-state'] = `paused`
        }
        // 让当前这个变 hov 图片 ==> 知道这是哪一个要变
        // console.log(222, id);
        // 根据id找到对应的这个数据
        let carouselData = data.find(item => item.id === id)
        // 修改这个数据的active
        carouselData.active = !carouselData.active
        // 重新设置data数据
        // setData(data) // 新data和旧data内存地址没有变化,其中的深层次数据变化了,但是监听不到,页面不会重新渲染
        setData([...data])
        // console.log(333, data);
    }
    const onmouseleave = (id) => {
        // 让动画停止
        for (let a = 0; a < carouselBox.current.children.length; a++) {
            carouselBox.current.children[a].style['animation-play-state'] = `running`
        }
        // 让当前这个变 hov 图片 ==> 知道这是哪一个要变
        // console.log(222, id);
        // 根据id找到对应的这个数据
        let carouselData = data.find(item => item.id === id)
        // 修改这个数据的active
        carouselData.active = !carouselData.active
        // 重新设置data数据
        setData([...data])
        // console.log(333, data);
    }
    const onclick = (id) => {
        let carouselData = data.find(item => item.id === id)
        alert(carouselData.text)
    }
    return (
        <div className="carousel" ref={carouselBox}>
            {/* 循环渲染:数组的map方法 */}
            {data.map(item => {
                return (
                    <div className="carousel-item" key={item.id} onMouseEnter={(e) => onmouseenter(item.id)} onMouseLeave={(e) => onmouseleave(item.id)} onClick={() => onclick(item.id)}>
                        {/* {item.active ? <img src={item.hov_url} /> : <img src={item.url} />} */}
                        <img src={item.active ? item.hov_url : item.url} />
                        <p>{item.text}</p>
                    </div>
                )
            })}
        </div>
    )
}

export default Carousel

上面的代码通过帧动画的形式进行走向和时间间隔多少秒走一个形成一个转盘的形式走动,并且实现了鼠标移入暂停,图片高亮。鼠标移出继续走动消除高亮(高亮的实现其实就是切换了一个图片)。以及点击每项的时候显示弹窗弹出该图片下的文本

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值