@ahwui/react-wave
Version:
Wave Progress component
135 lines (121 loc) • 4.42 kB
JavaScript
import _typeof from "@babel/runtime/helpers/esm/typeof";
import React, { useRef, useEffect } from 'react';
import "./index.css";
var Wave = function Wave(props) {
var _props$radius = props.radius,
radius = _props$radius === void 0 ? 50 : _props$radius,
_props$progress = props.progress,
progress = _props$progress === void 0 ? 0 : _props$progress,
_props$lineWidth = props.lineWidth,
lineWidth = _props$lineWidth === void 0 ? 1 : _props$lineWidth,
_props$space = props.space,
space = _props$space === void 0 ? 3 : _props$space,
_props$color = props.color,
color = _props$color === void 0 ? '#B0E2FF' : _props$color,
_props$borderColor = props.borderColor,
borderColor = _props$borderColor === void 0 ? '#87CEFA' : _props$borderColor,
_props$textColor = props.textColor,
textColor = _props$textColor === void 0 ? '#63B8FF' : _props$textColor,
_props$min = props.min,
min = _props$min === void 0 ? 0 : _props$min,
_props$children = props.children,
children = _props$children === void 0 ? undefined : _props$children;
var waveRef = useRef(null);
var ctx;
useEffect(function () {
var canvas = waveRef.current;
var context = canvas.getContext('2d');
var offset = 0;
if (context) {
ctx = context;
drawCirle();
drawMark();
requestAnimationFrame(draw);
}
function drawMark() {
// 绘制遮罩
ctx.beginPath();
ctx.arc(radius, radius, radius - space - lineWidth, 0, 2 * Math.PI, true);
ctx.closePath();
ctx.clip();
}
function drawCirle() {
// 绘制圆
ctx.clearRect(0, 0, radius * 2, radius * 2);
ctx.strokeStyle = borderColor;
var borderW = lineWidth;
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.arc(radius, radius, radius - borderW / 2, 0, 2 * Math.PI, true);
ctx.closePath();
ctx.stroke();
}
function draw() {
ctx.clearRect(0, 0, radius * 2, radius * 2);
drawWave();
requestAnimationFrame(draw);
}
function drawWave() {
offset += radius / 50;
if (offset >= 2 * radius) {
offset = 0;
}
var progressOffset;
if (typeof progress === 'number' && progress >= 0 && progress <= 100) {
progressOffset = 2 * radius * progress / 100 - radius;
if (progress < min) {
progressOffset = 2 * radius * min / 100 - radius;
}
} else {
progressOffset = -radius;
}
var offsetHeight = radius / 5;
ctx.beginPath();
if (_typeof(color) === 'object' && color.length === 2) {
var grad = ctx.createLinearGradient(0, 0, 0, Number(progress));
grad.addColorStop(0, color[0]);
grad.addColorStop(1, color[1]);
ctx.fillStyle = grad;
} else {
ctx.fillStyle = String(color);
}
ctx.moveTo(-2 * radius + offset, radius - progressOffset);
ctx.quadraticCurveTo(-3 * radius / 2 + offset, radius - offsetHeight - progressOffset, -radius + offset, radius - progressOffset);
ctx.quadraticCurveTo(-radius / 2 + offset, radius + offsetHeight - progressOffset, 0 + offset, radius - progressOffset);
ctx.quadraticCurveTo(radius / 2 + offset, radius - offsetHeight - progressOffset, radius + offset, radius - progressOffset);
ctx.quadraticCurveTo(3 * radius / 2 + offset, radius + offsetHeight - progressOffset, 2 * radius + offset, radius - progressOffset);
ctx.lineTo(2 * radius + offset, 2 * radius);
ctx.lineTo(-2 * radius + offset, 2 * radius);
ctx.lineTo(-2 * radius + offset, radius);
ctx.closePath();
ctx.fill();
}
}, [waveRef.current, props.progress]);
return /*#__PURE__*/React.createElement("div", {
className: "i--wave",
style: {
width: "".concat(radius * 2, "px"),
height: "".concat(radius * 2, "px")
}
}, /*#__PURE__*/React.createElement("canvas", {
style: {
position: 'absolute',
left: '0',
top: '0'
},
width: radius * 2,
height: radius * 2,
ref: waveRef
}), /*#__PURE__*/React.createElement("div", {
className: "i--wave-text",
style: {
color: textColor
}
}, children ? children : /*#__PURE__*/React.createElement("span", {
style: {
fontSize: '18px'
}
}, progress, "%")));
};
export default Wave;
//# sourceMappingURL=index.js.map