效果(动态)
npm i react-tsparticles@2.12.2
npm i tsparticles@2.12.0
注意:最好和上面的版本一样,不然会出现一个报错,具体如何解决的话去官网吧,上面的版本是没有问题的
代码块
总计6个代码块, options里面是相关粒子的配置
完整代码
import './index.sass'
import { Form, Input, Button, Card, Checkbox, message } from 'antd';
import type { LoginData } from '../../types/login'
import Particles from 'react-tsparticles'
import { loadFull } from "tsparticles";
import { getLogin } from '../../api/login'
import { useNavigate } from "react-router-dom";
const LoginIndex = () => {
const navigate = useNavigate();
//组件的最外层
const particlesInit = async (main: any) => {
await loadFull(main);
};
//粒子被正确加载到画布中时,这个函数被调用
const particlesLoaded: any = (container: any) => {
console.log("123", container);
};
const options: any = {
"background": {
"color": {
"value": "#232741"
},
"position": "50% 50%",
"repeat": "no-repeat",
"size": "cover"
},
// 帧数,越低越卡,默认60
"fpsLimit": 120,
"fullScreen": {
"zIndex": 1
},
"interactivity": {
"events": {
"onClick": {
"enable": true,
"mode": "push"
},
"onHover": {
"enable": true,
"mode": "slow"
}
},
"modes": {
"push": {
//点击是添加1个粒子
"quantity": 3,
},
"bubble": {
"distance": 200,
"duration": 2,
"opacity": 0.8,
"size": 20,
"divs": {
"distance": 200,
"duration": 0.4,
"mix": false,
"selectors": []
}
},
"grab": {
"distance": 400
},
//击退
"repulse": {
"divs": {
//鼠标移动时排斥粒子的距离
"distance": 200,
//翻译是持续时间
"duration": 0.4,
"factor": 100,
"speed": 1,
"maxSpeed": 50,
"easing": "ease-out-quad",
"selectors": []
}
},
//缓慢移动
"slow": {
//移动速度
"factor": 2,
//影响范围
"radius": 200,
},
//吸引
"attract": {
"distance": 200,
"duration": 0.4,
"easing": "ease-out-quad",
"factor": 3,
"maxSpeed": 50,
"speed": 1
},
}
},
// 粒子的参数
"particles": {
//粒子的颜色
"color": {
"value": "#ffffff"
},
//是否启动粒子碰撞
"collisions": {
"enable": true,
},
//粒子之间的线的参数
"links": {
"color": {
"value": "#ffffff"
},
"distance": 150,
"enable": true,
"warp": true
},
"move": {
"attract": {
"rotate": {
"x": 600,
"y": 1200
}
},
"enable": true,
"outModes": {
"bottom": "out",
"left": "out",
"right": "out",
"top": "out"
},
"speed": 6,
"warp": true
},
"number": {
"density": {
"enable": true
},
//初始粒子数
"value": 60
},
//透明度
"opacity": {
"value": 0.5,
"animation": {
"speed": 3,
"minimumValue": 0.1
}
},
//大小
"size": {
"random": {
"enable": true
},
"value": {
"min": 1,
"max": 3
},
"animation": {
"speed": 20,
"minimumValue": 0.1
}
}
}
};
const getLoginMessage = (data: LoginData) => {
try {
getLogin(data).then(res => {
if (res.data.code === 200) {
message.success(res.data.message);
localStorage.setItem('token', res.data.data.token);
localStorage.setItem('username', res.data.data.username);
// 跳转到首页
setTimeout(() => {
navigate('/dashboard', { replace: true })
}, 1000)
} else {
message.error(res.data.message);
}
});
} catch (err) {
console.log(err)
}
};
const onFinish = (values: LoginData) => {
getLoginMessage(values);
};
return (
<div >
<Card className='login-card'>
<Particles id="tsparticles" init={particlesInit} loaded={particlesLoaded} options={options} />
<Form
name="normal_login"
initialValues={{ remember: true }}
onFinish={onFinish}
className='login-index'
>
<Form.Item>
<h3 className='login-title'>Welcome KoaSystem</h3>
</Form.Item>
<Form.Item
name="username"
rules={[{ required: true, message: '请输入你的用户名!' }]}
>
<Input placeholder="用户名" />
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: '请输入你的密码!' }]}
>
<Input.Password placeholder="密码" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" block>
登录
</Button>
</Form.Item>
<Form.Item<LoginData>
name="remember"
valuePropName="checked"
wrapperCol={{ offset: 8, span: 16 }}
>
<Checkbox>记住密码</Checkbox>
</Form.Item>
</Form>
</Card>
</div>
)
}
export default LoginIndex