清凉一夏小风扇-React版

前言

本片文章主要是做一个小练习,通过react来制作一个风扇练习css动画。
vue3实现部分看这里–>

一、效果

在这里插入图片描述

二、代码分享

1、主体框架
“react”: “^18.2.0”
“sass”: “^1.62.1”

2、主要技术点
使用事件代理实现绑定多个方法。
使用animation实现动画效果

动态绑定动画样式

3、代码解析
页面结构:

  • 结构比较简单,主要是一个容器content,圆心circle,圆盘底座base,扇叶列表容器item-list,扇叶item
  • 按钮列表容器btn-list,按钮button
<div className="content">
  <div className="circle"></div>
  <div className="base"  style={
    
    {
    
     animation: `shakeHead linear ${
      
      shakeValue}s infinite alternate` }}>
    <div className="item-list">
      {
    
    
        itemList.map((item) => {
    
    
          return (
            <div key={
    
    item.id} className="item" style={
    
    {
    
     animation: item.animation }}></div>
          )
        })
      }
    </div>
  </div>

  <div className="btn-list" onClick={
    
    (event) => onChangeSpeed(event.target.dataset)}>
    {
    
    
      btnList.map((item) => {
    
    
        return (
          <button key={
    
    item.id} data-speedchange={
    
    item.dataSpeedchange} data-action={
    
    item.dataAction}>{
    
    item.btnName}</button>
        )
      })
    }
  </div>
</div>

代理方法处理:

  • 我们知道事件代理的实现技巧,也知道他的好处,但这里使用事件代理只是为了学习,毕竟现在的电脑配置,这些按钮绑定方法所使用的小号可以忽略不计。
  • 事件代理通过利用事件冒泡机制,将事件处理程序委托给父元素处理,从而避免了在子元素上单独绑定事件处理程序的麻烦
  • 通过元素所绑定的dataset来获取不同的action和参数。
const [speed, setSpeed] = useState(0)
const [shakeValue, setShakeValue] = useState(0)
const onChangeSpeed = (value) => {
    
    
  console.log(value)
  let {
    
     action, speedchange } = value
  switch (action) {
    
    
    case 'open':
      speedchange = speed ? speed : speedchange
      setSpeed(speedchange)
      break;
    case 'close':
      speedchange = 0
      setSpeed(speedchange)
      setShakeValue(speedchange)
      break;
    case 'change':
      speedchange = speed ? speedchange : 0
      setSpeed(speedchange)
      break;
    case 'shake':
      if (speed && shakeValue) {
    
    
        setShakeValue(0)
      } else if (speed) {
    
    
        setShakeValue(speedchange)
      }
      break;
    default:
      break;
  }
}

数据配置:
这里主要是为了配置dataset用的参数配置

const btnList = [
  {
    
    
    id: 1,
    dataSpeedchange: '3',
    dataAction: 'change',
    btnName: '1'
  },
  {
    
    
    id: 2,
    dataSpeedchange: '2',
    dataAction: 'change',
    btnName: '2'
  },
  {
    
    
    id: 3,
    dataSpeedchange: '1',
    dataAction: 'change',
    btnName: '3'
  },
  {
    
    
    id: 4,
    dataSpeedchange: '3',
    dataAction: 'open',
    btnName: 'open'
  },
  {
    
    
    id: 5,
    dataSpeedchange: '0',
    dataAction: 'close',
    btnName: 'close'
  },
  {
    
    
    id: 6,
    dataSpeedchange: '7',
    dataAction: 'shake',
    btnName: 'shake'
  },
]
const itemList = [
  {
    
    
    id: 1,
    animation: `identifier reverse linear ${
      
      speed}s infinite`
  },
  {
    
    
    id: 2,
    animation: `identifier reverse linear ${
      
      speed}s infinite`
  },
  {
    
    
    id: 3,
    animation: `identifier reverse linear ${
      
      speed}s infinite`
  },
  {
    
    
    id: 4,
    animation: `identifier reverse linear ${
      
      speed}s infinite`
  }
]

动画效果实现:
1、扇叶转动比较简单直接用transform: rotateZ(-360deg);这个就可以实现。
2、相对复杂一点的是摇头的效果,3d动画效果,所以需要用到3d属性rotate3d
3、主要keyframes动画

@keyframes identifier {
    
    
  to {
    
    
    transform: rotateZ(-360deg);
  }
}

@keyframes shakeHead {
    
    
  0% {
    
    
    transform: rotate3d(0, 1, 0, 45deg);
  }

  50% {
    
    
    transform: rotate3d(0, -1, 0, 45deg);
  }

  100% {
    
    
    transform: rotate3d(0, 1, 0, 45deg);
  }
}

这里说说摇头的动画
0,1,0表示y轴的正方向旋转
0,-1,0表示y轴的负方向旋转
最后的0,1,0恢复。

三、总结

总体来说,实现还是比较简单,实现的关键还是动画部分。

猜你喜欢

转载自blog.csdn.net/qq_43205326/article/details/130950933