react旋转木马动画效果(几个图片椭圆形旋转 鼠标移入暂停变色 移出继续旋转)

先定义一个数据data 数据中存放旋转的对象  给数据绑定状态(useState)

在给页面的dom元素绑定一个ref事件 在里面遍历渲染出data中的对象

在css页面中给渲染的盒子添加定位 和动画

在js页面  在useEffect中给每个盒子设置不同的出发时间

再给dw盒子 用onMouseEnter 和 onMouseLeave 写鼠标移入和移出事件

样式页面代码如下:

/* 最外层大盒子 */
.centerbox{
    width: 500px;
    height: 500px;
    background: pink;
    text-align: center;
    /* 弹性布局 */
    display: flex;
    /* 相对定位 */
    position: relative;
}
.dw{
    width: 200px;
    height: 200px;
    border: solid 1px red;
    margin: 5px;
    /* 绝对定位 */
    position: absolute;
    left: 0;
    top: 0;
    /* 动画名称 */
    animation-name: moveX ,moveY , moveScale; 
    /* 动画时长 */
    animation-duration: 10s,10s,20s;
    /* 动画次数 */
    animation-iteration-count: infinite;
    /* 动画贝塞尔函数 */
    animation-timing-function: cubic-bezier(0.36,0,0.64,1);
    /* 动画方向交互移动 */
    animation-direction: alternate;
  
}
/* X轴移动 */
@keyframes moveX{
    0%{
        left:-100px;
    }
    100%{
        left: 80%;
    }
}
/* Y轴移动 */
@keyframes moveY{
    0%{
        top: 10%;
    }
    100%{
        top: 60%;
    }
}
/* 放大缩小图片大小 */
@keyframes moveScale{
    0%{
        transform: scale(0.6);
    }
    50%{
         transform: scale(1);
    }
    100%{
        transform: scale(0.6);
    }
}

页面代码:

import React, { useEffect, useRef, useState } from 'react'
// 引入css样式
import './index.css'
// 引入图片
import img1 from "../../assect/images/lcar.png"
import img2 from "../../assect/images/hcar.png"
import img3 from "../../assect/images/ljiao.png"
import img4 from "../../assect/images/hjiao.png"
import img5 from "../../assect/images/lp.png"
import img6 from "../../assect/images/hp.png"
import img7 from "../../assect/images/ltai.png"
import img8 from "../../assect/images/htai.png"
import img9 from "../../assect/images/lshi.png"
import img10 from "../../assect/images/hshi.png"
import img11 from "../../assect/images/lz.png"
import img12 from "../../assect/images/hz.png"
const Index = () => {

  let [data, setdata] = useState([
    {
      id: 1,
      blueImg: img1,
      yellowImg: img2,
      flag: true,
      text: "定位"
    },
    {
      id: 2,
      blueImg: img3,
      yellowImg: img4,
      flag: true,
      text: "哦哦哦"
    },
    {
      id: 3,
      blueImg: img5,
      yellowImg: img6,
      flag: true,
      text: "哈哈哈"
    },
    {
      id: 4,
      blueImg: img7,
      yellowImg: img8,
      flag: true,
      text: "热热热"
    },
    {
      id: 5,
      blueImg: img9,
      yellowImg: img10,
      flag: true,
      text: "搜搜索"
    },
    {
      id: 6,
      blueImg: img11,
      yellowImg: img12,
      flag: true,
      text: "鹅鹅鹅饿"
    },
  ])
  let wrap = useRef(null)
  useEffect(() => {
    // 动画延迟效果
    for (let i = 0; i < wrap.current.children.length; i++) {
      wrap.current.children[i].style['animation-delay'] = `${-5 - i * 3.3}s,-${i * 3.3}s,-${i * 3.3}s`
    }
  }, [])

  // 鼠标移入暂停动画
  const onMouseEnter = (id) => {
    console.log(id)
    for (let i = 0; i < wrap.current.children.length; i++) {
      wrap.current.children[i].style['animation-play-state'] = `paused`
    }

    // 在data中找到鼠标下的id 
    let arr = data.find(item => item.id === id)
    //图片颜色取反
    arr.flag = !arr.flag
    //重新渲染数据
    setdata([...data])
  }

  // // 鼠标移出恢复动画
  const onmouseleave = (id) => {
    console.log(id)
    for (let i = 0; i < wrap.current.children.length; i++) {
      wrap.current.children[i].style['animation-play-state'] = `running`
    }

        // 在data中找到鼠标下的id 
    let arr = data.find(item => item.id === id)
    arr.flag = !arr.flag
    setdata([...data])
  }

  // 点击弹出提示框
  const onclick = (id) => {
    let arr = data.find(item => item.id === id)

    alert(arr.text)
  }
  return (
    <div className='centerbox' ref={wrap}>
      {
        data && data.map((item, index) => {
          return <div className='dw' key={index} onMouseEnter={(e) => onMouseEnter(item.id)} onMouseLeave={(e) => onmouseleave(item.id)} onClick={() => onclick(item.id)}>
          {/* 图片判断切换不同颜色 */}
            <img src={item.flag ? item.blueImg : item.yellowImg}></img>
            <p>{item.text}</p>
          </div>
        })
      }
    </div>
  )
}

export default Index

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值