rtgk-screen-web/components/screen/CircleProcess/index.js

163 lines
4.5 KiB
JavaScript
Raw Permalink Normal View History

2024-06-20 11:26:44 +08:00
import React, { useRef, useEffect, useState, useMemo } from 'react'
const imgHeight = 951; //图片原始高度
const imgWidth = 184; //图片原始高度
const circleBorder = 2; //圆环的宽度
const baseSize = 170;//满状态宽度
const itemHeight = 370; //单个高度(包含空白)
const waveHeight = 29; //波浪高度
const colors = ["#8ee34d", "#f6c971", "#ea335d"]; //圆边框颜色
const colorIndexTrans = [2, 1, 0]; //调换第一个和最后一个位置
function CircleProcess(props) {
const sizeRef = useRef();
const outerRef = useRef();
const innerRef = useRef();
const [scale, setScale] = useState(1)
const [innerWidth, setInnerWidth] = useState(0)
//接受外部参数
let { percent:realPercent = 0.5, percentRule = [0, 0.8, 0.95], size = 0.9 } = props;
const percent = useMemo(() => {
return realPercent > 1 ? 1 : realPercent
}, [realPercent])
//颜色的下标
const colorIndex = useMemo(() => {
let res = 0;
percentRule.forEach((val, index) => {
if (percent > val) res = index;
})
return colorIndexTrans[res];
}, [percentRule, percent])
//颜色的位置
const positionY = useMemo(() => {
return -(-innerWidth + percent * innerWidth + waveHeight * scale + colorIndex * scale * itemHeight)
}, [innerWidth, percent, scale, colorIndex])
//计算组件宽度以及比例
const tableSetting = () => {
//组件实际宽度
let comWidth = sizeRef.current.clientWidth;
outerRef.current.style.height = comWidth * size + 'px';
outerRef.current.style.width = comWidth * size + 'px';
//波浪实际宽度
let innerWidth = innerRef.current.clientWidth;
setInnerWidth(innerWidth);
//计算比例
setScale(innerWidth / baseSize);
}
useEffect(() => {
//监听父级宽度变化
let innerWindow = sizeRef.current.contentDocument.defaultView;
innerWindow.addEventListener("resize", tableSetting);
tableSetting();
return () => {
innerWindow.removeEventListener("resize", tableSetting);
}
}, [])
return (
<div className='circle-process'>
<object
ref={sizeRef}
tabIndex="-1"
type="text/html"
aria-hidden="true"
data="about:blank"
style={{
display: "block",
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
border: "none",
padding: 0,
margin: 0,
opacity: 0,
zIndex: -1000,
pointerEvents: "none",
}} />
<div className='out-circle' ref={outerRef}>
<div className='in-circle' ref={innerRef}>
<div className='pic-one'></div>
<div className='pic-two'></div>
<div className='text'>{realPercent * 100 + "%"}</div>
</div>
</div>
<style jsx>{`
.circle-process{
position:relative;
height:100%;
}
.out-circle {
margin: auto;
overflow: hidden;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: ${circleBorder}px solid;
border-color: ${colors[colorIndex]};
padding: 2px;
}
.in-circle {
width: 100%;
height: 100%;
border-radius: 50%;
position: relative;
overflow: hidden;
}
.in-circle .pic-one, .in-circle .pic-two {
background-image: url('/img/hpPercent.png');
background-repeat: repeat-x;
background-size: ${scale * imgWidth}px ${scale * imgHeight}px;
width: 100%;
height: 100%;
position: absolute;
background-position-y: ${positionY}px;
}
.in-circle .pic-one {
animation: 5s one linear infinite normal;
}
.in-circle .pic-two {
opacity: 0.3;
animation: 10s one linear infinite normal;
}
.in-circle .text {
position: absolute;
color: #fff;
text-align: center;
width: 100%;
margin-top: 12px;
font-size: ${scale*30}px;
}
@keyframes one {
from {
background-position-x: 0;
}
to {
background-position-x: -${imgWidth * scale}px;
}
}
`}
</style>
</div>
)
}
export default CircleProcess