@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
128 lines (127 loc) • 5.53 kB
JavaScript
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import React, { useEffect, useRef } from "react";
import classNames from "classnames";
import { View } from "@tarojs/components";
import { isObject } from "../../utils";
import { ComponentDefaults } from "../../utils/typings";
import { useForceUpdate } from "../../hooks/use-force-update";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
strokeWidth: 5,
radius: 50,
strokeLinecap: 'round',
color: '#FF0F23',
background: '#e5e9f2',
clockwise: true
});
var classPrefix = "nut-circleprogress";
export var CircleProgress = function(props) {
var _ref = _object_spread({}, defaultProps, props), children = _ref.children, percent = _ref.percent, className = _ref.className, radius = _ref.radius, background = _ref.background, clockwise = _ref.clockwise, color = _ref.color, strokeWidth = _ref.strokeWidth, style = _ref.style, strokeLinecap = _ref.strokeLinecap, restProps = _object_without_properties(_ref, [
"children",
"percent",
"className",
"radius",
"background",
"clockwise",
"color",
"strokeWidth",
"style",
"strokeLinecap"
]);
var oldValue = useRef(percent);
var forceUpdate = useForceUpdate();
var classes = classNames(classPrefix, className);
var refRandomId = Math.random().toString(36).slice(-8);
var animateIdRef = useRef(0);
var styles = _object_spread({
height: "".concat(Number(radius) * 2, "px"),
width: "".concat(Number(radius) * 2, "px")
}, style);
useEffect(function() {
var startTime = Date.now();
var startRate = Number(oldValue.current) // 30
;
var endRate = Number(percent) // 40
;
var duration = Math.abs((startRate - endRate) * 1000 / +100) // 100
;
var animate = function() {
var now = Date.now();
var progress = Math.min((now - startTime) / duration, 1);
var rate = progress * (endRate - startRate) + startRate;
oldValue.current = Math.min(Math.max(+rate, 0), 100);
if (endRate > startRate ? rate < endRate : rate > endRate) {
forceUpdate();
animateIdRef.current = window.requestAnimationFrame(animate);
} else {
window.cancelAnimationFrame(animateIdRef.current);
}
};
animateIdRef.current = window.requestAnimationFrame(animate);
return function() {
return window.cancelAnimationFrame(animateIdRef.current);
};
}, [
percent
]);
var stop = function() {
if (!isObject(color)) {
return [];
}
var colorArr = Object.keys(color).sort(function(a, b) {
return parseFloat(a) - parseFloat(b);
});
var stopArr = [];
colorArr.forEach(function(item) {
var obj = {
key: '',
value: ''
};
obj.key = item;
obj.value = color[item];
stopArr.push(obj);
});
return stopArr;
};
var transColor = function(color) {
return color && color.replace('#', '%23');
};
var format = function(progress) {
return Math.min(Math.max(+progress, 0), 100);
};
var circleStyle = function() {
var stopArr = stop();
var stopDom = [];
if (stopArr) {
stopArr.forEach(function(item) {
var obj = '';
obj = "%3Cstop offset='".concat(item.key, "' stop-color='").concat(transColor(item.value), "'/%3E");
stopDom.push(obj);
});
}
var perimeter = 283;
var progress = +oldValue.current;
var offset = perimeter * Number(format(parseFloat(progress.toFixed(1)))) / 100;
var isWise = clockwise ? 1 : 0;
var realColor = isObject(color) ? "url(%23".concat(refRandomId, ")") : transColor(color);
var d = "M 50 50 m 0 -45 a 45 45 0 1 ".concat(isWise, " 0 90 a 45 45 0 1, ").concat(isWise, " 0 -90");
var pa = "%3Cdefs%3E%3ClinearGradient id='".concat(refRandomId, "' x1='100%25' y1='0%25' x2='0%25' y2='0%25'%3E").concat(stopDom, "%3C/linearGradient%3E%3C/defs%3E");
var path = "%3Cpath d='".concat(d, "' stroke-width='").concat(strokeWidth, "' stroke='").concat(transColor(background), "' fill='none'/%3E");
var path1 = "%3Cpath d='".concat(d, "' stroke-width='").concat(strokeWidth, "' stroke-dasharray='").concat(offset, ",").concat(perimeter, "' stroke-linecap='round' stroke='").concat(transColor(realColor), "' fill='none'/%3E");
return {
background: "url(\"data:image/svg+xml,%3Csvg viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E".concat(pa).concat(path).concat(path1, '%3C/svg%3E")'),
width: '100%',
height: '100%'
};
};
return /*#__PURE__*/ React.createElement("div", _object_spread({
className: classes,
style: styles
}, restProps), /*#__PURE__*/ React.createElement(View, {
style: circleStyle()
}), /*#__PURE__*/ React.createElement(View, {
className: "nut-circleprogress-text"
}, children));
};
CircleProgress.displayName = 'NutCircleProgress';