动画:
圆环旋转、圆环虚线运动
实现:
圆环使用svg来设置,通过设置圆的实现和虚线距离来产生圆环运动效果
使用插槽特性,来指定需要加载的区域
参数:
loading: PropTypes.bool, 是否将区域加载
background:PropTypes.string, 加载背景色,传入具有透明度的rgba颜色
fontSize: PropTypes.string, 加载背景中的字体大小
strokeColor: PropTypes.string, 加载圆环的颜色
效果图:
代码示例:
使用:
import React,{useState,useEffect} from 'react'
import Loading from './loading/loading'
function App(){
const [loading, setLoading ] = useState(true);
useEffect(() => {
setTimeout(() => {
setLoading(!loading);
},3000)
},[])
return(
<div
>
<Loading
loading={loading}
>
<div style={{width:'400px'}}>
<ul>
<li>哇咔咔</li>
<li>啊哈哈</li>
<li>哇啦啦</li>
<li>哇咔咔</li>
<li>啊哈哈</li>
<li>哇啦啦</li>
<li>哇咔咔</li>
<li>啊哈哈</li>
<li>哇啦啦</li>
<li>哇咔咔</li>
<li>啊哈哈</li>
<li>哇啦啦</li>
</ul>
</div>
</Loading>
</div>
)
}
export default App
loading.jsx:
import React,{useState,useCallback,useRef,useEffect} from 'react'
import PropTypes from 'prop-types';
import './loading.css'
function App(props) {
const loadingf = useRef(null);
useEffect(() => {
_styleHandler('background');
_styleHandler('fontSize');
_styleHandler('strokeColor');
}, [])
// 统一样式处理
const _styleHandler = useCallback((key) => {
props[key] && loadingf.current.style.setProperty('--' + key, props[key])
}, [])
return(
<div className='jf-loading-container' ref={loadingf}>
{props.children}
{props.loading &&
<div className='jf-loading-mask'>
<div>
<svg className='jf-loading-circle-container' xmlns="http://www.w3.org/2000/svg" width='42' height='42' >
<circle className='jf-loading-circle' cx='21' cy='21' r='19' fill='none'></circle>
</svg>
</div>
<span className='jf-loading-text'>
加载中
</span>
</div>
}
</div>
)
}
App.propTypes = {
loading: PropTypes.bool,
background:PropTypes.string,
fontSize: PropTypes.string,
strokeColor: PropTypes.string,
}
App.defaultProps = {
}
export default App
loading.css:
.jf-loading-container {
display: inline-block;
box-sizing: border-box;
position: relative;
--background: rgba(214, 214, 213, 0.9);
--fontSize: 14px;
--strokeColor: #409eff;
}
.jf-loading-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--background);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.jf-loading-circle-container {
animation: loading-rotate 2s linear infinite;
}
.jf-loading-circle {
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: var(--strokeColor);
stroke-linecap: round;
}
.jf-loading-text {
font-size: var(--fontSize);
}
@keyframes loading-rotate {
100% {
transform: rotate(1turn);
}
}
@keyframes loading-dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -40px; /*出现圆环进度倒退效果*/
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -120px; /*出现圆环进度倒退效果*/
}
}