UNPKG

vantui-edit

Version:

一套适用于Taro3及React的vantui组件库

266 lines (238 loc) 9.43 kB
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;