vantui-edit
Version:
一套适用于Taro3及React的vantui组件库
266 lines (238 loc) • 9.43 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
var _excluded = ["text", "lineCap", "value", "speed", "size", "fill", "layerColor", "color", "strokeWidth", "clockwise", "style", "className", "children"];
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
import { createCanvasContext, createSelectorQuery } from '@tarojs/taro';
import { useRef, useState, useEffect, useCallback } from 'react';
import { View, Canvas } from '@tarojs/components';
import { Current } from '@tarojs/runtime';
import { isObj } from '../common/validator';
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function format(rate) {
return Math.min(Math.max(rate, 0), 100);
}
var PERIMETER = 2 * Math.PI;
var BEGIN_ANGLE = -Math.PI / 2;
var STEP = 1;
export function Circle(props) {
var indexRef = useRef("van-circle_uni_".concat(+new Date()).concat(Math.ceil(Math.random() * 10000)));
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
ready = _useState2[0],
setReady = _useState2[1];
var ref = useRef({
ctx: undefined,
inited: false,
currentValue: undefined,
interval: undefined,
hoverColor: ''
});
var text = props.text,
_props$lineCap = props.lineCap,
lineCap = _props$lineCap === void 0 ? 'round' : _props$lineCap,
_props$value = props.value,
value = _props$value === void 0 ? 0 : _props$value,
_props$speed = props.speed,
speed = _props$speed === void 0 ? 50 : _props$speed,
_props$size = props.size,
size = _props$size === void 0 ? 100 : _props$size,
fill = props.fill,
_props$layerColor = props.layerColor,
layerColor = _props$layerColor === void 0 ? '#ffffff' : _props$layerColor,
_props$color = props.color,
color = _props$color === void 0 ? '#1989fa' : _props$color,
_props$strokeWidth = props.strokeWidth,
strokeWidth = _props$strokeWidth === void 0 ? 4 : _props$strokeWidth,
_props$clockwise = props.clockwise,
clockwise = _props$clockwise === void 0 ? true : _props$clockwise,
style = props.style,
className = props.className,
children = props.children,
others = _objectWithoutProperties(props, _excluded);
useEffect(function () {
var _Current$page;
Current.page = (_Current$page = Current.page) !== null && _Current$page !== void 0 ? _Current$page : {
path: "page-".concat(indexRef.current)
};
setTimeout(function () {
if (process.env.TARO_ENV !== 'h5' && process.env.TARO_ENV !== 'swan' && process.env.TARO_ENV !== 'kwai') {
var query = createSelectorQuery();
query.select("#".concat(indexRef.current)).fields({
node: true,
size: true
}).exec(function (res) {
var canvas = res[0].node;
var ctx = canvas.getContext('2d');
canvas.width = res[0].width * 3;
canvas.height = res[0].height * 3;
ctx.scale(3, 3);
ref.current.ctx = ctx;
setReady(true);
});
} else {
var ctx = createCanvasContext(indexRef.current);
ref.current.ctx = ctx;
setReady(true);
}
}, 100);
}, []);
var setHoverColor = function setHoverColor() {
if (isObj(color)) {
var _color = color;
try {
// 快手不支持渐变色
if (process.env.TARO_ENV === 'kwai') {
Object.keys(color).sort(function (a, b) {
return parseFloat(a) - parseFloat(b);
}).map(function (key) {
return ref.current.hoverColor = _color[key];
});
} else {
var LinearColor = ref.current.ctx.createLinearGradient(size, 0, 0, 0);
Object.keys(color).sort(function (a, b) {
return parseFloat(a) - parseFloat(b);
}).map(function (key) {
return LinearColor.addColorStop(parseFloat(key) / 100, _color[key]);
});
ref.current.hoverColor = LinearColor;
}
} catch (error) {
console.error(error);
}
} else {
ref.current.hoverColor = color;
}
return Promise.resolve();
};
var presetCanvas = useCallback(function (context, strokeStyle, beginAngle, endAngle, fill) {
var position = size / 2;
var radius = position - strokeWidth / 2;
if (process.env.TARO_ENV === 'swan') {
context.setStrokeStyle(strokeStyle);
context.setLineWidth(strokeWidth);
context.setLineCap(lineCap);
} else {
context.strokeStyle = strokeStyle;
context.lineWidth = strokeWidth;
context.lineCap = lineCap;
}
context.beginPath();
context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
context.stroke();
if (fill) {
if (process.env.TARO_ENV === 'swan') {
context.setFillStyle(fill);
} else {
context.fillStyle = fill;
}
context.fill();
}
}, [clockwise, lineCap, size, strokeWidth]);
var renderLayerCircle = useCallback(function (context) {
presetCanvas(context, layerColor, 0, PERIMETER, fill);
}, [fill, layerColor, presetCanvas]);
var renderHoverCircle = useCallback(function (context, formatValue) {
// 结束角度
var progress = PERIMETER * (formatValue / 100);
var endAngle = clockwise ? BEGIN_ANGLE + progress : 3 * Math.PI - (BEGIN_ANGLE + progress);
presetCanvas(context, ref.current.hoverColor, BEGIN_ANGLE, endAngle);
}, [clockwise, presetCanvas]);
var drawCircle = useCallback(function (currentValue) {
ref.current.ctx.clearRect(0, 0, size, size);
renderLayerCircle(ref.current.ctx);
var formatValue = format(currentValue);
if (formatValue !== 0) {
renderHoverCircle(ref.current.ctx, formatValue);
}
if (process.env.TARO_ENV === 'h5' || process.env.TARO_ENV === 'swan' || process.env.TARO_ENV === 'kwai') {
ref.current.ctx.draw();
}
}, [renderHoverCircle, renderLayerCircle, size]);
var clearMockInterval = function clearMockInterval() {
if (ref.current.interval) {
clearTimeout(ref.current.interval);
ref.current.interval = null;
}
};
var reRender = useCallback(function () {
if (speed <= 0 || speed > 1000) {
drawCircle(value);
return;
}
clearMockInterval();
ref.current.currentValue = ref.current.currentValue || 0;
var run = function run() {
ref.current.interval = setTimeout(function () {
if (ref.current.currentValue !== value) {
if (Math.abs(ref.current.currentValue - value) < STEP) {
ref.current.currentValue = value;
} else if (ref.current.currentValue < value) {
ref.current.currentValue += STEP;
} else {
ref.current.currentValue -= STEP;
}
drawCircle(ref.current.currentValue);
run();
} else {
clearMockInterval();
}
}, 1000 / speed);
};
run();
}, [drawCircle, speed, value]);
useEffect(function () {
if (ready) {
reRender();
}
}, [reRender, value, ready]);
useEffect(function () {
if (ready) {
drawCircle(ref.current.currentValue);
} // eslint-disable-next-line
}, [size, ready]);
useEffect(function () {
if (ready) {
setHoverColor().then(function () {
drawCircle(ref.current.currentValue);
}).catch(function () {});
} // eslint-disable-next-line
}, [color, ready]);
useEffect(function () {
return function () {
clearMockInterval();
};
/* eslint-disable-next-line */
}, []);
return /*#__PURE__*/_jsxs(View, _objectSpread(_objectSpread({
id: "page-".concat(indexRef.current),
className: "van-circle ".concat(className),
style: style
}, others), {}, {
children: [/*#__PURE__*/_jsx(Canvas // eslint-disable-next-line
// @ts-ignore
, {
width: size // @ts-ignore
,
height: size,
nativeProps: {
width: size,
height: size
},
className: "van-circle__canvas ".concat(indexRef.current),
style: 'width: ' + "".concat(size, "px") + ';height:' + "".concat(size, "px"),
id: indexRef.current,
type: "2d",
canvasId: indexRef.current
}), !text ? /*#__PURE__*/_jsx(View, {
className: "van-circle__text",
children: children
}) : /*#__PURE__*/_jsx(View, {
className: "van-circle__text",
children: text
})]
}));
}
export default Circle;