目标
import React from "react";
import { Link } from "react-router-dom";
import { PropTypes } from "prop-types";
import "./header-nav.scss";
class HeaderNav extends React.Component {
constructor(props) {
super(props);
this.state = {
initDeg: 0
}
}
draw = (ctx, canvas, deg, points, step = 5) => {
if (this.state.initDeg >= deg) {
return;
}
this.setState({
initDeg: this.state.initDeg + step
})
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
// 设置默认样式
ctx.strokeStyle = 'rgb(143, 163, 239)';
ctx.lineWidth = 1;
ctx.lineCap = 'round';
ctx.translate(50, 50);
ctx.rotate(-90 * Math.PI / 180);
ctx.beginPath();
ctx.arc(0, 0, 40, 0, 360 * Math.PI / 180);
ctx.stroke();
// ctx.restore();
// 2. 画弧线
ctx.save();
ctx.strokeStyle = "rgb(204, 207,255)";
ctx.beginPath();
ctx.arc(0, 0, 40, 0, this.state.initDeg * Math.PI / 180);
ctx.stroke();
ctx.restore();
// 绘制一个第一层的外圆
ctx.beginPath();
ctx.shadowColor = "rgba(110, 145,218,1)";
ctx.shadowBlur = 10;
ctx.fillStyle = "rgba(241,243,255,0.15)";
ctx.rotate(this.state.initDeg * Math.PI / 180);
ctx.arc(40, 0, 10, 0, 360 * Math.PI / 180);
ctx.fill();
// 绘制一个第二层的外圆
ctx.beginPath();
ctx.shadowColor = "rgba(110, 145,218,1)";
ctx.shadowBlur = 10;
ctx.fillStyle = "rgba(241,243,255,0.25)";
ctx.arc(40, 0, 8, 0, 360 * Math.PI / 180);
ctx.fill();
// 绘制弧线前面的一个实心圆
ctx.beginPath();
ctx.fillStyle = "#eaecff";
ctx.arc(40, 0, 3, 0, 360 * Math.PI / 180);
ctx.fill();
ctx.restore();
// 写字
ctx.beginPath();
ctx.fillStyle = "white";
ctx.font = 14 + 'px PingFangSC, helvetica neue, hiragino sans gb, arial, microsoft yahei ui, microsoft yahei, simsun, sans-serif';
ctx.textAlign = 'center';
ctx.fillText('Points', 50, 50);
ctx.restore();
ctx.beginPath();
ctx.font = 'normal bold ' + 20 + 'px PingFangSC, helvetica neue, hiragino sans gb, arial, microsoft yahei ui, microsoft yahei, simsun, sans-serif';
ctx.fillText(points, 50, 72);
ctx.restore();
}
componentDidMount() {
let canvas = document.querySelector('#canvas');
if (!canvas.getContext) return;
let ctx = canvas.getContext('2d');
// pointDeg 弧线的旋转角度,是动态计算的,根据具体的points计算
let points = this.props.points;
let pointDeg = Number(360 * (points / 100000 (这里假设总数是这么多))).toFixed(2);
// 开启定时器 加载动画
let timer = setInterval(() => {
if (this.state.initDeg > pointDeg) {
clearInterval(timer);
}
this.draw(ctx, canvas, pointDeg, points);
}, 30);
this.draw(ctx, canvas, pointDeg, points);
}
render() {
return <>
<div className="canvas-box" style={{ backgroundImage: `url(${require('@imgs/jihe.png')})` }}>
<canvas id="canvas" width="100" height="100"></canvas>
<Link to="/redemption-history" className="redemption-history-link color-fff size-26 fw-500">
Redemption History <img alt="" src={require('@imgs/arrow-right.png')} />
</Link>
</div>
</>
}
}
HeaderNav.propTypes = {
points: PropTypes.number.isRequired
}
export default HeaderNav;