这里写目录标题
- 前言
- 一、效果
- 二、代码分享
- 三、总结
前言
本片文章主要是做一个小练习,通过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恢复。
三、总结
总体来说,实现还是比较简单,实现的关键还是动画部分。