diff --git a/README.md b/README.md
index 9235528..2c1cbc5 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,21 @@
# taro-f2-react
-> 支持在使用 Taro React 开发小程序中,按 React 组件书写方式使用 F2 。
->
使用 [@antv/f2](https://f2.antv.antgroup.com/tutorial/getting-started)
->
taro-f2-react 1.1.x 支持 4.x <= @antv/f2 < 5.x
->
taro-f2-react 1.2.x 支持 @antv/f2 >= 5.x
+> 在 Taro React 中使用 @antv/f2 。
# Demo
-
+
# Install
```bash
#via pnpm
-$ pnpm add taro-f2-react @antv/f2
+$ pnpm add taro-f2-react @antv/f2@4.0.51
# via npm
-$ npm i taro-f2-react @antv/f2
+$ npm i taro-f2-react
# via yarn
-$ yarn add taro-f2-react @antv/f2
+$ yarn add taro-f2-react
```
# Usage
@@ -28,30 +25,30 @@ $ yarn add taro-f2-react @antv/f2
接下来就可以愉快的在 Taro 中使用 F2 了
```javascript
-import React from 'react';
-import ReactDOM from 'react-dom';
-import { View } from '@tarojs/components';
-import F2Canvas from 'taro-f2-react';
-import { Chart, Interval } from '@antv/f2';
+import React from "react";
+import { View } from "@tarojs/components";
+import F2Canvas from "taro-f2-react";
+import { Chart, Interval } from "@antv/f2";
const data = [
- { genre: 'Sports', sold: 275 },
- { genre: 'Strategy', sold: 115 },
- { genre: 'Action', sold: 120 },
- { genre: 'Shooter', sold: 350 },
- { genre: 'Other', sold: 150 },
+ { genre: "Sports", sold: 275 },
+ { genre: "Strategy", sold: 115 },
+ { genre: "Action", sold: 120 },
+ { genre: "Shooter", sold: 350 },
+ { genre: "Other", sold: 150 },
];
-ReactDOM.render(
-
-
-
-
-
-
- ,
- document.getElementById('root')
-);
+function Index() {
+ return (
+
+
+
+
+
+
+
+ );
+}
```
## 多图表
@@ -94,11 +91,14 @@ Taro 在 >= 3.6.0 版本中 Dev 模式下新增了 split chunks,导致加载
}
```
+# 关于 @antv/f2 5.x
+* 由于开发者反馈 @antv/f2 5.x 版本的问题较多,最新版本修改为支持 4.x 版本
+* 如果想体验 @antv/f2 5.x 版本,可以安装 taro-f2-react 1.2.0 版本
+
# Support
Taro >= 3.x
-
taro-f2-react 1.1.x 支持 4.x <= @antv/f2 < 5.x
-
taro-f2-react 1.2.x 支持 @antv/f2 >= 5.x
+
@antv/f2@4.x
## LICENSE [MIT](LICENSE)
diff --git a/components/f2-canvas/index.tsx b/components/f2-canvas/index.tsx
index 47c9640..e26d9fd 100644
--- a/components/f2-canvas/index.tsx
+++ b/components/f2-canvas/index.tsx
@@ -1,10 +1,6 @@
-import { ReactNode, useCallback, useEffect, useRef } from 'react';
-import {
- createOffscreenCanvas,
- createSelectorQuery,
- getSystemInfoSync,
-} from '@tarojs/taro';
-import { Canvas } from '@tarojs/components';
+import { ReactNode, useEffect, useRef } from 'react';
+import { createSelectorQuery, getSystemInfoSync } from '@tarojs/taro';
+import { ITouchEvent, CanvasTouchEvent, Canvas } from '@tarojs/components';
import { Canvas as FFCanvas } from '@antv/f2';
interface F2CanvasProps {
@@ -12,47 +8,38 @@ interface F2CanvasProps {
children?: ReactNode;
}
-function convertTouches(touches) {
- if (!touches) return touches;
- touches.forEach((touch) => {
- touch.pageX = 0;
- touch.pageY = 0;
- touch.clientX = touch.x;
- touch.clientY = touch.y;
- });
- return touches;
+type CanvasEvent = ITouchEvent | CanvasTouchEvent;
+
+interface CanvasElement {
+ dispatchEvent: (type: string, event: CanvasEvent) => void;
}
-function dispatchEvent(el, event, type) {
- if (!el || !event) return;
- if (!event.preventDefault) {
- event.preventDefault = function () {};
- }
- const mergedEvent = {
- ...event,
- type,
- target: el,
- };
- const { touches, changedTouches, detail } = mergedEvent;
- mergedEvent.touches = convertTouches(touches);
- mergedEvent.changedTouches = convertTouches(changedTouches);
- if (detail) {
- mergedEvent.clientX = detail.x;
- mergedEvent.clientY = detail.y;
+function wrapEvent(e: CanvasEvent) {
+ if (e && !e.preventDefault) {
+ e.preventDefault = function () {};
}
- el.dispatchEvent(mergedEvent);
+ return e;
}
const F2Canvas = (props: F2CanvasProps) => {
const { id, children } = props;
- const idRef = useRef(id || 'f-canvas');
+ const idRef = useRef(id || 'f2Canvas');
const canvasRef = useRef();
const ffCanvasRef = useRef();
- const canvasElRef = useRef();
- // const childrenRef = useRef();
+ const canvasElRef = useRef();
+ const childrenRef = useRef();
- const renderCanvas = useCallback(() => {
+ useEffect(() => {
+ childrenRef.current = children;
+ ffCanvasRef.current?.update({ children });
+ }, [children]);
+
+ useEffect(() => {
+ return () => ffCanvasRef.current?.destroy();
+ }, []);
+
+ const renderCanvas = () => {
const query = createSelectorQuery();
query
.select(`#${idRef.current}`)
@@ -62,8 +49,6 @@ const F2Canvas = (props: F2CanvasProps) => {
})
.exec((res) => {
const { node, width, height } = res[0];
- const { requestAnimationFrame, cancelAnimationFrame } = node;
-
const pixelRatio = getSystemInfoSync().pixelRatio;
// 高清设置
node.width = width * pixelRatio;
@@ -74,20 +59,14 @@ const F2Canvas = (props: F2CanvasProps) => {
width,
height,
context,
- children,
- // @ts-ignore
- offscreenCanvas: createOffscreenCanvas({ type: '2d' }),
+ children: childrenRef.current,
createImage: () => node.createImage(), // fix: 解决图片元素不渲染的问题
- requestAnimationFrame,
- cancelAnimationFrame,
- isTouchEvent: (e) => e.type.startsWith('touch'),
- isMouseEvent: (e) => e.type.startsWith('mouse'),
});
- ffCanvasRef.current = canvas;
- canvasElRef.current = canvas.getCanvasEl();
canvas.render();
+ ffCanvasRef.current = canvas;
+ canvasElRef.current = canvas.canvas.get('el');
});
- }, []);
+ };
useEffect(() => {
if (canvasRef.current) {
@@ -95,13 +74,41 @@ const F2Canvas = (props: F2CanvasProps) => {
}
}, [canvasRef]);
- useEffect(() => {
- ffCanvasRef.current?.update({ children });
- }, [children]);
+ const handleClick = (e: ITouchEvent) => {
+ const canvasEl = canvasElRef.current;
+ if (!canvasEl) {
+ return;
+ }
- useEffect(() => {
- return () => ffCanvasRef.current?.destroy();
- }, []);
+ const event = wrapEvent(e);
+ // 包装成 touch 对象
+ event.touches = [e.detail];
+ canvasEl.dispatchEvent('click', event);
+ };
+
+ const handleTouchStart = (e: CanvasTouchEvent) => {
+ const canvasEl = canvasElRef.current;
+ if (!canvasEl) {
+ return;
+ }
+ canvasEl.dispatchEvent('touchstart', wrapEvent(e));
+ };
+
+ const handleTouchMove = (e: CanvasTouchEvent) => {
+ const canvasEl = canvasElRef.current;
+ if (!canvasEl) {
+ return;
+ }
+ canvasEl.dispatchEvent('touchmove', wrapEvent(e));
+ };
+
+ const handleTouchEnd = (e: CanvasTouchEvent) => {
+ const canvasEl = canvasElRef.current;
+ if (!canvasEl) {
+ return;
+ }
+ canvasEl.dispatchEvent('touchend', wrapEvent(e));
+ };
return (