UNPKG

@tarojsx/library

Version:
88 lines 4 kB
import { __rest } from "tslib"; import React, { useRef, useMemo, useCallback, useEffect } from 'react'; import Taro from '@tarojs/taro'; import classNames from 'classnames'; import retry from 'async-retry'; import equal from 'fast-deep-equal'; import { Canvas } from '@tarojs/components'; import { uuid } from '../utils'; export const F2Core = function (props) { const { className, style = {} } = props, _a = props.config, { Chart, Global } = _a, config = __rest(_a, ["Chart", "Global"]), { data, fontFamily, children } = props; const id = useMemo(() => `f2-canvas-${uuid()}`, []); const pixelRatio = useMemo(() => Taro.getSystemInfoSync().pixelRatio, []); const chartRef = useRef(); const canvasElRef = useRef(); const handleTouch = (eventName) => useCallback((e) => { var _a; return (_a = canvasElRef.current) === null || _a === void 0 ? void 0 : _a.dispatchEvent(eventName, wrapEvent(e)); }, [eventName]); // setup f2 并传递给 children useEffect(() => { !(async () => { const { node, width, height } = await getCanvasNodeFields(`#${id}`); if (!chartRef.current) { const context = node.getContext('2d'); // 高清设置 node.width = width * pixelRatio; node.height = height * pixelRatio; /** * 如果是多字体的话, ios会不显示, android下会闪退 * @see https://github.com/antvis/wx-f2/issues/260 */ if (fontFamily || (Global === null || Global === void 0 ? void 0 : Global.fontFamily.includes(','))) { Global.fontFamily = fontFamily || 'system-ui' || 'sans-serif'; } chartRef.current = new Chart(Object.assign(config || {}, { context, width, height, pixelRatio })); canvasElRef.current = chartRef.current.get('el'); } children({ chart: chartRef.current, data }); })(); return () => { var _a; return (_a = chartRef.current) === null || _a === void 0 ? void 0 : _a.destroy(); }; }, []); const prevDataRef = useRef(data); // // 数据变化时清空画布, 重新设置, 重新渲染. 首次 mount 时因为 chartRef 还未准备好, 此处的逻辑不会运行. useEffect(() => { if (!chartRef.current || equal(prevDataRef.current, data)) return; children({ chart: chartRef.current.clear(), data }); }, [data]); return (React.createElement(Canvas, { id: id, className: classNames('f2-canvas', className), style: Object.assign({ width: '100%', height: '100%' }, style), type: "2d", onTouchStart: handleTouch('touchstart'), onTouchMove: handleTouch('touchmove'), onTouchEnd: handleTouch('touchend') })); }; function wrapEvent(e) { if (!e) return; if (!e.preventDefault) { e.preventDefault = () => { }; } return e; } /** * 获取 canvas node 和 size. * * @param selector 选择器 */ async function getCanvasNodeFields(selector) { return await retry(async () => { if (process.env.TARO_ENV === 'h5') { const node = document.querySelector(selector).getElementsByTagName('canvas')[0]; return { node, width: node.clientWidth, height: node.clientHeight }; } return await new Promise((resolve, reject) => { Taro.createSelectorQuery() .select(selector) .fields({ node: true, size: true, }) .exec(([res]) => { // console.log(`${selector} fields`, res) if (res) { resolve(res); } else { reject(new Error(`获取 canvas fields 失败 ${selector}`)); } }); }); }, // 重试 10 次, 间隔 100ms. { retries: 10, minTimeout: 100, factor: 1 }); } //# sourceMappingURL=F2Core.js.map