├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .fatherrc.js ├── .github └── workflows │ ├── auto-release.yml │ ├── ci.yml │ └── ci_schedule.yml ├── .gitignore ├── .npmignore ├── .prettierrc.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── jest-setup.js ├── jest.config.js ├── lerna.json ├── package.json ├── packages ├── f-engine │ ├── .fatherrc.js │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── jsx-dev-runtime.d.ts │ ├── jsx-dev-runtime.js │ ├── jsx-runtime.d.ts │ ├── jsx-runtime.js │ ├── package.json │ ├── src │ │ ├── canvas │ │ │ ├── cssRule.ts │ │ │ ├── equal.ts │ │ │ ├── index.ts │ │ │ ├── render │ │ │ │ ├── animation.ts │ │ │ │ ├── animator.ts │ │ │ │ ├── applyStyle.ts │ │ │ │ ├── computeLayout.ts │ │ │ │ ├── createShape.ts │ │ │ │ ├── css-layout.ts │ │ │ │ ├── findClosestShapeNode.ts │ │ │ │ └── index.ts │ │ │ ├── shape │ │ │ │ ├── circle.ts │ │ │ │ ├── index.ts │ │ │ │ ├── line.ts │ │ │ │ ├── marker.ts │ │ │ │ ├── rect.ts │ │ │ │ └── text.ts │ │ │ ├── theme.ts │ │ │ ├── timeline.ts │ │ │ ├── util.ts │ │ │ ├── vnode.ts │ │ │ └── workTags.ts │ │ ├── children.ts │ │ ├── component │ │ │ ├── index.ts │ │ │ └── updater.ts │ │ ├── createContext.ts │ │ ├── createRef.ts │ │ ├── gesture.ts │ │ ├── index.ts │ │ ├── jsx │ │ │ ├── fragment.ts │ │ │ ├── index.ts │ │ │ ├── jsx-automatic.ts │ │ │ ├── jsx-classic.ts │ │ │ ├── jsx-namespace.d.ts │ │ │ ├── jsx-runtime.ts │ │ │ └── tag.ts │ │ ├── player.ts │ │ ├── playerFrames.ts │ │ ├── shape │ │ │ ├── arc.ts │ │ │ ├── index.ts │ │ │ ├── marker.ts │ │ │ ├── sector.ts │ │ │ ├── smoothPolyline.ts │ │ │ └── util │ │ │ │ ├── smooth.ts │ │ │ │ └── util.ts │ │ ├── timeline.ts │ │ └── types │ │ │ ├── index.ts │ │ │ ├── jsx.ts │ │ │ └── shape.ts │ ├── test │ │ ├── __image_snapshots__ │ │ │ ├── create-context-test-tsx-create-context-inject-context-inject-context-1-snap.png │ │ │ ├── create-context-test-tsx-create-context-provider-context-context-type-1-snap.png │ │ │ ├── create-context-test-tsx-create-context-provider-context-create-context-1-snap.png │ │ │ └── create-context-test-tsx-create-context-provider-context-create-context-2-snap.png │ │ ├── canvas │ │ │ ├── FragFunction.test.tsx │ │ │ ├── __image_snapshots__ │ │ │ │ ├── animation-test-tsx-动画-animate-false-1-snap.png │ │ │ │ ├── animation-test-tsx-动画-animation-1-snap.png │ │ │ │ ├── animation-test-tsx-动画-animation-2-snap.png │ │ │ │ ├── animation-test-tsx-动画-animation-3-snap.png │ │ │ │ ├── animation-test-tsx-动画-animation-4-snap.png │ │ │ │ ├── animation-test-tsx-动画-clip-animation-1-snap.png │ │ │ │ ├── animation-test-tsx-动画-component-animation-1-snap.png │ │ │ │ ├── animation-test-tsx-动画-component-update-1-snap.png │ │ │ │ ├── animation-test-tsx-动画-duration-empty-1-snap.png │ │ │ │ ├── animation-test-tsx-动画-property-empty-1-snap.png │ │ │ │ ├── diff-test-tsx-canvas-渲染顺序-1-snap.png │ │ │ │ ├── diff-test-tsx-canvas-渲染顺序-2-snap.png │ │ │ │ ├── frag-function-test-tsx-canvas-fragment-function-1-snap.png │ │ │ │ ├── index-test-tsx-canvas-g-render-1-snap.png │ │ │ │ ├── layout-test-tsx-canvas-component-layout-1-snap.png │ │ │ │ ├── layout-test-tsx-canvas-layout-1-snap.png │ │ │ │ ├── layout-test-tsx-canvas-layout-2-snap.png │ │ │ │ ├── layout-test-tsx-canvas-line-1-snap.png │ │ │ │ ├── layout-test-tsx-canvas-marker-1-snap.png │ │ │ │ ├── layout-test-tsx-canvas-text-1-snap.png │ │ │ │ ├── layout-test-tsx-canvas-text-2-snap.png │ │ │ │ ├── resize-test-tsx-canvas-resize-1-snap.png │ │ │ │ ├── resize-test-tsx-canvas-resize-2-snap.png │ │ │ │ └── resize-test-tsx-canvas-resize-context-1-snap.png │ │ │ ├── animation.test.tsx │ │ │ ├── canvas │ │ │ │ └── canvas.test.tsx │ │ │ ├── diff.test.tsx │ │ │ ├── event.test.tsx │ │ │ ├── index.test.tsx │ │ │ ├── layout.test.tsx │ │ │ ├── render │ │ │ │ ├── __image_snapshots__ │ │ │ │ │ ├── compute-layout-test-tsx-compute-layout-布局计算-1-snap.png │ │ │ │ │ ├── create-animation-test-tsx-图形绘制顺序-图形绘制顺序-1-snap.png │ │ │ │ │ └── create-animation-test-tsx-图形绘制顺序-图形绘制顺序-2-snap.png │ │ │ │ ├── computeLayout.test.tsx │ │ │ │ ├── createAnimation.test.tsx │ │ │ │ └── vnodeUpdate.test.tsx │ │ │ ├── resize.test.tsx │ │ │ ├── svg │ │ │ │ └── svg.test.tsx │ │ │ ├── theme.test.tsx │ │ │ ├── util │ │ │ │ └── px2hd.test.ts │ │ │ └── webgl │ │ │ │ └── webgl.test.tsx │ │ ├── children.test.tsx │ │ ├── component │ │ │ ├── component.test.tsx │ │ │ ├── defaultProps.test.tsx │ │ │ └── equal.test.tsx │ │ ├── createContext.test.tsx │ │ ├── g.test.tsx │ │ ├── index.test.tsx │ │ ├── jsx │ │ │ ├── jsx-automatic.test.tsx │ │ │ └── jsx-classic.test.tsx │ │ ├── lifecycle.test.tsx │ │ ├── shape │ │ │ ├── __image_snapshots__ │ │ │ │ ├── animation-test-tsx-canvas-clip-animation-1-snap.png │ │ │ │ ├── animation-test-tsx-canvas-custom-shape-animation-1-snap.png │ │ │ │ ├── animation-test-tsx-canvas-line-offset-path-1-snap.png │ │ │ │ ├── animation-test-tsx-canvas-offset-path-为-ref-1-snap.png │ │ │ │ ├── animation-test-tsx-canvas-text-number-1-snap.png │ │ │ │ ├── animation-test-tsx-canvas-text-number-2-snap.png │ │ │ │ ├── arc-test-tsx-arc-arc-cx-cy-1-snap.png │ │ │ │ ├── arc-test-tsx-arc-arc-大角-1-snap.png │ │ │ │ ├── arc-test-tsx-arc-arc-大角-2-snap.png │ │ │ │ ├── arc-test-tsx-arc-arc-弧度-1-snap.png │ │ │ │ ├── arc-test-tsx-arc-arc-整圆-1-snap.png │ │ │ │ ├── arc-test-tsx-arc-arc-逆时针-1-snap.png │ │ │ │ ├── arc-test-tsx-arc-arc-默认-1-snap.png │ │ │ │ ├── arc-test-tsx-arc-角度从非-0-到-0-1-snap.png │ │ │ │ ├── arc-test-tsx-arc-角度从非-0-到-0-2-snap.png │ │ │ │ ├── clip-test-tsx-clip-animation-clip-function-1-snap.png │ │ │ │ ├── clip-test-tsx-clip-clip-1-snap.png │ │ │ │ ├── clip-test-tsx-clip-clip-function-1-snap.png │ │ │ │ ├── index-test-tsx-canvas-arc-1-snap.png │ │ │ │ ├── index-test-tsx-canvas-arrow-1-snap.png │ │ │ │ ├── polyline-test-tsx-polyline-polyline-1-snap.png │ │ │ │ ├── polyline-test-tsx-polyline-step-end-polyline-1-snap.png │ │ │ │ ├── polyline-test-tsx-polyline-step-middle-polyline-1-snap.png │ │ │ │ ├── polyline-test-tsx-polyline-step-start-polyline-1-snap.png │ │ │ │ ├── register-tag-test-tsx-自定义标签-使用自定义标签-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-clockwise-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-radius-不同-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-sector-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-sector-clip-clip-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-临界数值-0-angle-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-内角合并-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-整圆-逆时针-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-整圆-顺时针-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-极小角度扇形区域-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-角度从非-0-到-0-1-snap.png │ │ │ │ ├── sector-test-tsx-sector-角度从非-0-到-0-2-snap.png │ │ │ │ ├── sector-test-tsx-sector-逆时针绘制-1-snap.png │ │ │ │ └── z-index-test-tsx-z-index-z-index-1-snap.png │ │ │ ├── animation.test.tsx │ │ │ ├── arc.test.tsx │ │ │ ├── clip.test.tsx │ │ │ ├── index.test.tsx │ │ │ ├── polyline.test.tsx │ │ │ ├── registerTag.test.tsx │ │ │ ├── sector.test.tsx │ │ │ └── zIndex.test.tsx │ │ ├── timeline │ │ │ ├── __image_snapshots__ │ │ │ │ ├── component-test-tsx-测试组件变化-tranform-ref-嵌套-1-snap.png │ │ │ │ ├── component-test-tsx-测试组件变化-指定-tranform-ref-1-snap.png │ │ │ │ ├── component-test-tsx-测试组件变化-组件切换-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-finish-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-key-frames-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-key-frames-连续变化-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-leave-动画-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-pause-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-props-未变-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-props-未变-2-snap.png │ │ │ │ ├── key-frames-test-tsx-player-子组件-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-播放中finish-1-snap.png │ │ │ │ ├── key-frames-test-tsx-player-暂停完播放-1-snap.png │ │ │ │ ├── morph-test-tsx-形变动画-circle-到-group-1-snap.png │ │ │ │ ├── morph-test-tsx-形变动画-group-到-circle-1-snap.png │ │ │ │ ├── player-ref-func-test-tsx-player-go-to等于总时长时-1-snap.png │ │ │ │ ├── player-test-tsx-clip-animation-clip-增加-delete-after-complete-1-snap.png │ │ │ │ ├── player-test-tsx-clip-animation-暂停-1-snap.png │ │ │ │ ├── player-test-tsx-clip-animation-结束后播放-1-snap.png │ │ │ │ ├── player-test-tsx-clip-animation-跳转超出总时长-1-snap.png │ │ │ │ ├── player-test-tsx-player-go-to-1-snap.png │ │ │ │ ├── player-test-tsx-player-go-to-2-snap.png │ │ │ │ ├── player-test-tsx-player-go-to-3-snap.png │ │ │ │ ├── player-test-tsx-player-多组动画回跳-1-snap.png │ │ │ │ ├── timeline-test-tsx-timeline-timeline-播放-1-snap.png │ │ │ │ └── timeline-test-tsx-timeline-timeline-播放-2-snap.png │ │ │ ├── component.test.tsx │ │ │ ├── keyFrames.test.tsx │ │ │ ├── morph.test.tsx │ │ │ ├── player.test.tsx │ │ │ ├── playerRefFunc.test.tsx │ │ │ └── timeline.test.tsx │ │ ├── types.test.tsx │ │ └── util.ts │ ├── tsconfig.json │ └── typings.d.ts ├── f-lottie │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.tsx │ ├── test │ │ ├── data │ │ │ └── data.json │ │ └── index.test.tsx │ ├── tsconfig.json │ └── typings.d.ts ├── f-my │ ├── .eslintrc.js │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── examples │ │ ├── test │ │ │ ├── .mini-ide │ │ │ │ └── project-ide.json │ │ │ ├── app.acss │ │ │ ├── app.js │ │ │ ├── app.json │ │ │ ├── babel.config.json │ │ │ ├── mini.project.json │ │ │ ├── package.json │ │ │ ├── pages │ │ │ │ └── index │ │ │ │ │ ├── index.acss │ │ │ │ │ ├── index.axml │ │ │ │ │ ├── index.js │ │ │ │ │ ├── index.json │ │ │ │ │ ├── index.jsx │ │ │ │ │ ├── rect.js │ │ │ │ │ └── rect.jsx │ │ │ └── snapshot.png │ │ └── typescript │ │ │ ├── .fatherrc.js │ │ │ ├── .mini-ide │ │ │ └── project-ide.json │ │ │ ├── app.acss │ │ │ ├── app.js │ │ │ ├── app.json │ │ │ ├── mini.project.json │ │ │ ├── package.json │ │ │ ├── snapshot.png │ │ │ ├── src │ │ │ └── index │ │ │ │ ├── index.acss │ │ │ │ ├── index.axml │ │ │ │ ├── index.json │ │ │ │ ├── index.tsx │ │ │ │ └── rect.tsx │ │ │ └── tsconfig.json │ ├── package.json │ ├── src │ │ ├── adapter.ts │ │ ├── index.acss │ │ ├── index.axml │ │ ├── index.json │ │ ├── index.tsx │ │ ├── web.acss │ │ ├── web.axml │ │ ├── web.json │ │ └── web.tsx │ ├── tsconfig.json │ └── typings.d.ts ├── f-react │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── examples │ │ └── my-app │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── index.html │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── robots.txt │ │ │ └── src │ │ │ ├── App.js │ │ │ ├── App.test.js │ │ │ ├── index.js │ │ │ └── setupTests.js │ ├── package.json │ ├── src │ │ ├── createCanvas.tsx │ │ └── index.tsx │ ├── test │ │ ├── index.test.tsx │ │ └── react.test.tsx │ ├── tsconfig.json │ └── typings.d.ts ├── f-test-utils │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.tsx │ ├── tsconfig.json │ └── typings.d.ts ├── f-vue │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── examples │ │ ├── vite │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── package.json │ │ │ ├── src │ │ │ │ ├── App.vue │ │ │ │ ├── main.js │ │ │ │ └── rect.jsx │ │ │ └── vite.config.js │ │ └── vue3 │ │ │ ├── babel.config.js │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── App.vue │ │ │ ├── main.js │ │ │ └── rect.jsx │ │ │ └── vue.config.js │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── typings.d.ts └── f-wx │ ├── .eslintrc.js │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── examples │ └── test │ │ ├── app.js │ │ ├── app.json │ │ ├── app.wxss │ │ ├── babel.config.json │ │ ├── package.json │ │ ├── pages │ │ └── index │ │ │ ├── index.js │ │ │ ├── index.json │ │ │ ├── index.jsx │ │ │ ├── index.wxml │ │ │ ├── index.wxss │ │ │ ├── rect.js │ │ │ └── rect.jsx │ │ ├── project.config.json │ │ └── sitemap.json │ ├── package.json │ ├── src │ ├── index.json │ ├── index.ts │ ├── index.wxml │ └── index.wxss │ ├── tsconfig.json │ └── typings.d.ts ├── tsconfig.json └── typings.d.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | indent_size = 1 18 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | packages/hammer 2 | build/ 3 | coverage/ 4 | demos/assets/ 5 | dist/ 6 | lib/ 7 | es/ 8 | mocks/ 9 | node_modules/ 10 | miniprogram_npm/ 11 | demos/assets/ 12 | lib/ 13 | demos/index.html 14 | site/ 15 | docs/ 16 | public 17 | types/ 18 | types-test/ 19 | **/*.test.ts 20 | **/*.test.tsx 21 | **/*.test.js 22 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true, 6 | jest: true, 7 | }, 8 | extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], 9 | parser: '@typescript-eslint/parser', 10 | parserOptions: { 11 | sourceType: 'module', 12 | ecmaVersion: 12, 13 | ecmaFeatures: { 14 | jsx: true, 15 | }, 16 | jsxPragma: 'jsx', 17 | jsxFragmentName: 'Fragment', 18 | }, 19 | plugins: ['@typescript-eslint'], 20 | rules: { 21 | '@typescript-eslint/no-inferrable-types': 0, 22 | 'no-constant-condition': 0, 23 | '@typescript-eslint/ban-types': 0, 24 | '@typescript-eslint/ban-ts-comment': 0, 25 | '@typescript-eslint/no-empty-function': 0, 26 | 'no-prototype-builtins': 0, 27 | 'no-case-declarations': 0, 28 | '@typescript-eslint/explicit-module-boundary-types': 0, 29 | '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], 30 | '@typescript-eslint/no-namespace': 0, 31 | '@typescript-eslint/no-explicit-any': 0, 32 | }, 33 | settings: { 34 | 'import/parsers': { 35 | '@typescript-eslint/parser': ['.ts', '.tsx'], 36 | }, 37 | 'import/resolver': { 38 | typescript: { 39 | alwaysTryTypes: true, 40 | }, 41 | }, 42 | }, 43 | }; 44 | -------------------------------------------------------------------------------- /.fatherrc.js: -------------------------------------------------------------------------------- 1 | export default { 2 | cjs: { 3 | type: 'babel', 4 | }, 5 | esm: { 6 | type: 'babel', 7 | }, 8 | runtimeHelpers: true, 9 | lessInBabelMode: true, 10 | cssModules: true, 11 | extraBabelPlugins: ['@babel/plugin-proposal-class-static-block'], 12 | pkgs: ['f-engine', 'f-lottie', 'f-react', 'f-my', 'f-vue', 'f-wx', 'f-test-utils'], 13 | }; 14 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: [push, pull_request] 8 | 9 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 10 | jobs: 11 | # This workflow contains a single job called "ci" 12 | ci: 13 | # The type of runner that the job will run on 14 | runs-on: macos-latest 15 | 16 | strategy: 17 | matrix: 18 | node_version: ['18'] 19 | 20 | # Steps represent a sequence of tasks that will be executed as part of the job 21 | steps: 22 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 23 | - uses: actions/checkout@v2 24 | 25 | # Runs a single command using the runners shell 26 | - name: Use Node.js ${{ matrix.node_version }} 27 | uses: actions/setup-node@v2 28 | with: 29 | node-version: ${{ matrix.node_version }} 30 | 31 | - name: install 32 | run: | 33 | yarn install 34 | 35 | - name: lint 36 | run: | 37 | npm run lint 38 | env: 39 | CI: true 40 | 41 | - name: build 42 | run: | 43 | npm run build 44 | env: 45 | CI: true 46 | 47 | - name: test 48 | run: | 49 | npm run test 50 | env: 51 | CI: true 52 | 53 | - name: save diff snapshot 54 | uses: actions/upload-artifact@v4 55 | if: ${{ failure() }} 56 | with: 57 | name: diff snapshot 58 | path: | 59 | packages/**/__image_snapshots__/__diff_output__/*.png 60 | !**/node_modules/** 61 | -------------------------------------------------------------------------------- /.github/workflows/ci_schedule.yml: -------------------------------------------------------------------------------- 1 | # 定时巡检 2 | name: CI_Schedule 3 | 4 | on: 5 | schedule: 6 | # 北京时间 09:00 7 | - cron: '0 1 * * *' 8 | 9 | jobs: 10 | ci: 11 | runs-on: macos-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Use Node.js 16 | uses: actions/setup-node@v2 17 | with: 18 | node-version: 18 19 | 20 | - name: install 21 | run: | 22 | yarn install 23 | 24 | - name: lint 25 | run: | 26 | npm run lint 27 | env: 28 | CI: true 29 | 30 | - name: build 31 | run: | 32 | npm run build 33 | env: 34 | CI: true 35 | 36 | - name: test 37 | run: | 38 | npm run test 39 | env: 40 | CI: true 41 | 42 | # 发布失败通知内部开发群 43 | - name: CI failure notify 44 | if: ${{ failure() }} 45 | uses: zcong1993/actions-ding@master 46 | with: 47 | dingToken: ${{ secrets.DING_TALK_ACCESS_TOKEN }} 48 | ignoreError: true 49 | body: | 50 | { 51 | "msgtype": "link", 52 | "link": { 53 | "title": "😳 FEngine CI 巡检失败", 54 | "text": "🔗 请点击链接查看具体原因", 55 | "messageUrl": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}", 56 | "picUrl": "https://gw.alipayobjects.com/zos/finxbff/compress-tinypng/ea88c724-38fb-42aa-8055-0e08155368b9.png" 57 | } 58 | } 59 | 60 | # 保存巡检失败的 diff 图片 61 | - name: save diff snapshot 62 | uses: actions/upload-artifact@v4 63 | if: ${{ failure() }} 64 | with: 65 | name: diff snapshot 66 | path: | 67 | packages/**/__image_snapshots__/__diff_output__/*.png 68 | !**/node_modules/** 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | yarn.lock 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # nyc test coverage 25 | .nyc_output 26 | 27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 28 | .grunt 29 | 30 | # Bower dependency directory (https://bower.io/) 31 | bower_components 32 | 33 | # node-waf configuration 34 | .lock-wscript 35 | 36 | # Compiled binary addons (http://nodejs.org/api/addons.html) 37 | build/Release 38 | 39 | # Dependency directories 40 | node_modules/ 41 | jspm_packages/ 42 | miniprogram_npm 43 | 44 | # Typescript v1 declaration files 45 | typings/ 46 | 47 | # Optional npm cache directory 48 | .npm 49 | 50 | # Optional eslint cache 51 | .eslintcache 52 | 53 | # Optional REPL history 54 | .node_repl_history 55 | 56 | # Output of 'npm pack' 57 | *.tgz 58 | 59 | # Yarn Integrity file 60 | .yarn-integrity 61 | 62 | # dotenv environment variables file 63 | .env 64 | 65 | build 66 | dist 67 | lib 68 | es 69 | temp 70 | .DS_Store 71 | .vscode 72 | .idea 73 | es5/ 74 | es6/ 75 | es/ 76 | demos/index.html 77 | demos/assets/screenshots 78 | demos/debug.html 79 | .npmrc 80 | 81 | *.sw* 82 | *.un~ 83 | .cache 84 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | .DS_Store 64 | 65 | # npmignore - content above this line is automatically generated and modifications may be omitted 66 | # see npmjs.com/npmignore for more details. 67 | test 68 | 69 | *.sw* 70 | *.un~ 71 | .idea 72 | bin 73 | demos 74 | docs 75 | temp 76 | webpack-dev.config.js 77 | webpack.config.js 78 | examples 79 | site 80 | gatsby-browser.js 81 | gatsby-config.js 82 | .cache 83 | public 84 | .npmrc 85 | -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | # 详细配置请移步:https://prettier.io/docs/en/configuration.html 2 | --- 3 | trailingComma: all 4 | singleQuote: true 5 | proseWrap: never 6 | endOfLine: lf 7 | printWidth: 100 8 | tabWidth: 2 9 | useTabs: false 10 | semi: true 11 | bracketSpacing: true 12 | jsxBracketSameLine: false 13 | arrowParens: 'always' 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FEngine 是 AntV F 系列可视化引擎的底层渲染引擎,为移动端提供了一套完整的渲染、事件、动画能力,能方便的构建可视化 UI 2 | 3 | ## 快速开始 4 | 5 | ```jsx 6 | const { props } = ( 7 | 8 | 9 | 10 | ); 11 | 12 | const canvas = new Canvas(props); 13 | await canvas.render(); 14 | ``` 15 | 16 | ## 本地开发 17 | 18 | ```bash 19 | # 安装依赖 (推荐用 yarn) 20 | $ yarn 21 | 22 | # 先执行下 build 23 | $ npm run build 24 | 25 | # 通过单测调试 26 | $ npm run test-watch 'packages/f-engine/test/canvas/index.test.tsx' 27 | 28 | ``` 29 | 30 | ## License 31 | 32 | [MIT license](./LICENSE). 33 | -------------------------------------------------------------------------------- /jest-setup.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line 2 | const { configureToMatchImageSnapshot } = require('jest-image-snapshot'); 3 | // eslint-disable-next-line 4 | const CanvasConverter = require('canvas-to-buffer'); 5 | const toMatchImageSnapshot = configureToMatchImageSnapshot({ 6 | failureThreshold: 0.001, 7 | failureThresholdType: 'percent', 8 | }); 9 | 10 | expect.extend({ 11 | toMatchImageSnapshot(received) { 12 | const converter = new CanvasConverter(received.canvas, { 13 | image: { types: ['png'] }, 14 | }); 15 | 16 | const execPath = process.execPath; 17 | // toMatchImageSnapshot 需要使用 node 环境 18 | process.execPath = 'node'; 19 | const result = toMatchImageSnapshot.call(this, converter.toBuffer()); 20 | process.execPath = execPath; 21 | 22 | return result; 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | runner: 'jest-electron/runner', 3 | testEnvironment: 'jest-electron/environment', 4 | preset: 'ts-jest', 5 | collectCoverage: false, 6 | collectCoverageFrom: [ 7 | 'packages/*/src/**/*.{ts,tsx,js}', 8 | '!packages/f-engine/src/canvas/render/css-layout.ts', 9 | '!packages/f-engine/src/canvas/timeline.ts', 10 | '!packages/f-my/src/**/*.{ts,tsx,js}', 11 | '!packages/f-wx/src/**/*.{ts,tsx,js}', 12 | '!packages/f-test-utils/src/**/*.{ts,tsx,js}', 13 | '!packages/f-vue/src/**/*.{ts,tsx,js}', 14 | '!**/node_modules/**', 15 | ], 16 | modulePathIgnorePatterns: ['packages/*/dist'], 17 | testPathIgnorePatterns: [], 18 | testRegex: '/test/.*\\.test\\.tsx?$', 19 | setupFilesAfterEnv: ['/jest-setup.js'], 20 | testTimeout: 10000, 21 | transform: { 22 | '^.+\\.[tj]s$': 'ts-jest', 23 | }, 24 | globals: { 25 | 'ts-jest': { 26 | tsConfig: { 27 | allowJs: true, 28 | target: 'ES2019', 29 | }, 30 | }, 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "useWorkspaces": true, 4 | "version": "1.7.0", 5 | "command": { 6 | "bootstrap": { 7 | "ci": false, 8 | "npmClientArgs": [ 9 | "--no-package-lock" 10 | ] 11 | }, 12 | "publish": { 13 | "commitHooks": false, 14 | "conventionalCommits": true, 15 | "createRelease": "github", 16 | "message": "🤖 publish", 17 | "exact": true 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "f-engine", 3 | "private": true, 4 | "workspaces": [ 5 | "packages/*" 6 | ], 7 | "description": "", 8 | "keywords": [], 9 | "homepage": "https://github.com/antvis/FEngine", 10 | "author": "https://github.com/orgs/antvis/people", 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/antvis/FEngine" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/antvis/FEngine/issues" 17 | }, 18 | "devDependencies": { 19 | "@babel/plugin-proposal-class-static-block": "^7.17.6", 20 | "@types/jest": "^26.0.20", 21 | "@types/jest-image-snapshot": "^6.1.0", 22 | "@typescript-eslint/eslint-plugin": "^5.10.0", 23 | "@typescript-eslint/parser": "^5.10.0", 24 | "canvas-to-buffer": "^1.1.1", 25 | "eslint": "^7.32.0", 26 | "father": "^2.30.0", 27 | "jest": "^26.6.3", 28 | "jest-electron": "^0.1.12", 29 | "jest-image-snapshot": "^6.1.0", 30 | "lerna": "^6.6.2", 31 | "pre-commit": "^1.2.2", 32 | "ts-jest": "^26.4.4", 33 | "typescript": "^4.1.3" 34 | }, 35 | "scripts": { 36 | "bootstrap": "lerna bootstrap", 37 | "clean": "lerna clean", 38 | "dev": "npm run test-watch", 39 | "build": "father build", 40 | "build-watch": "CI=true father build -w", 41 | "build-ci": "CI=true npm run build", 42 | "test": "jest", 43 | "test-cov": "jest --coverage", 44 | "test-live": "npm run test-watch packages", 45 | "test-watch": "DEBUG_MODE=1 jest --watch", 46 | "coverage": "jest --coverage", 47 | "snapshot": "jest --updateSnapshot", 48 | "lint": "eslint ./", 49 | "lint-fix": "eslint --fix ./", 50 | "release": "lerna publish --yes --summary-file", 51 | "canary": "lerna publish --canary --dist-tag next", 52 | "ci": "npm run lint && npm run build && npm run test", 53 | "prettier": "prettier --write './packages/**/*.{ts,tsx}'" 54 | }, 55 | "pre-commit": { 56 | "run": [ 57 | "lint", 58 | "test" 59 | ], 60 | "silent": false 61 | }, 62 | "resolutions": { 63 | "signal-exit": "3.0.3", 64 | "react-monaco-editor": "0.34.0", 65 | "monaco-editor": "0.20.0", 66 | "monaco-editor-webpack-plugin": "1.9.1", 67 | "cheerio": "1.0.0-rc.12" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/f-engine/.fatherrc.js: -------------------------------------------------------------------------------- 1 | export default process.env.CI && process.env.CI === 'true' 2 | ? {} 3 | : { 4 | umd: { 5 | name: 'FEngine', 6 | file: 'index', 7 | // minFile: true, 8 | }, 9 | entry: ['src/index.ts', 'src/jsx/jsx-runtime.ts'], 10 | overridesByEntry: { 11 | 'src/index.ts': { 12 | umd: { name: 'FEngine', file: 'index' }, 13 | }, 14 | // for weixin miniapp 15 | 'src/jsx/jsx-runtime.ts': { 16 | umd: { name: 'FJSXRuntime', file: 'jsx-runtime' }, 17 | }, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /packages/f-engine/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | .DS_Store 64 | 65 | # npmignore - content above this line is automatically generated and modifications may be omitted 66 | # see npmjs.com/npmignore for more details. 67 | test 68 | 69 | *.sw* 70 | *.un~ 71 | .idea 72 | bin 73 | demos 74 | docs 75 | temp 76 | webpack-dev.config.js 77 | webpack.config.js 78 | examples 79 | site 80 | gatsby-browser.js 81 | gatsby-config.js 82 | .cache 83 | public 84 | -------------------------------------------------------------------------------- /packages/f-engine/LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /packages/f-engine/README.md: -------------------------------------------------------------------------------- 1 | FEngine 是 AntV F 系列可视化引擎的底层渲染引擎,为移动端提供了一套完整的渲染、事件、动画能力,能方便的构建可视化 UI 2 | 3 | See our GitHub [https://github.com/antvis/FEngine](https://github.com/antvis/FEngine) for more information 4 | 5 | ## Install 6 | 7 | Using npm: 8 | 9 | ```sh 10 | npm install --save @antv/f-engine 11 | ``` 12 | 13 | or using yarn: 14 | 15 | ```sh 16 | yarn add @antv/f-engine 17 | ``` 18 | 19 | ## License 20 | 21 | [MIT license](./LICENSE). 22 | -------------------------------------------------------------------------------- /packages/f-engine/jsx-dev-runtime.d.ts: -------------------------------------------------------------------------------- 1 | export * from './jsx-runtime'; 2 | -------------------------------------------------------------------------------- /packages/f-engine/jsx-dev-runtime.js: -------------------------------------------------------------------------------- 1 | export * from './jsx-runtime'; 2 | -------------------------------------------------------------------------------- /packages/f-engine/jsx-runtime.d.ts: -------------------------------------------------------------------------------- 1 | export * from './es/jsx/jsx-runtime'; 2 | -------------------------------------------------------------------------------- /packages/f-engine/jsx-runtime.js: -------------------------------------------------------------------------------- 1 | export * from './es/jsx/jsx-runtime'; 2 | -------------------------------------------------------------------------------- /packages/f-engine/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antv/f-engine", 3 | "version": "1.5.0", 4 | "main": "lib/index.js", 5 | "module": "es/index.js", 6 | "types": "es/index.d.ts", 7 | "miniprogram": "dist", 8 | "sideEffects": false, 9 | "dependencies": { 10 | "@antv/g-gesture": "~2.2.0", 11 | "@antv/g-lite": "~1.2.0", 12 | "@antv/g-mobile-canvas": "~0.11.0", 13 | "@antv/g-mobile-canvas-element": "~0.8.0", 14 | "@antv/g-mobile-svg": "~0.10.0", 15 | "@antv/g-mobile-webgl": "~0.9.0", 16 | "@antv/g-web-animations-api": "~1.2.0", 17 | "@antv/util": "^3.0.6", 18 | "@babel/runtime": "^7.12.5", 19 | "eventemitter3": "^4.0.0", 20 | "tslib": "^2.3.1" 21 | }, 22 | "devDependencies": { 23 | "@antv/f-test-utils": "1.0.9" 24 | }, 25 | "homepage": "https://github.com/antvis/FEngine", 26 | "author": "https://github.com/orgs/antvis/people", 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/antvis/FEngine" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/antvis/FEngine/issues" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/equal.ts: -------------------------------------------------------------------------------- 1 | import { isArray, isFunction, isPlainObject } from '@antv/util'; 2 | 3 | function objToString(obj) { 4 | return Object.prototype.toString.call(obj); 5 | } 6 | 7 | function objectKeys(obj) { 8 | return Object.keys(obj); 9 | } 10 | 11 | function equal(a, b): boolean { 12 | if (a === b) return true; 13 | 14 | if (typeof a !== typeof b) { 15 | return false; 16 | } 17 | 18 | // null 和 undefined 19 | if (a == null || b == null) { 20 | return false; 21 | } 22 | 23 | // 特殊处理NaN 24 | if (Number.isNaN(a) && Number.isNaN(b)) { 25 | return true; 26 | } 27 | 28 | if (objToString(a) !== objToString(b)) { 29 | return false; 30 | } 31 | 32 | // 函数不相等,也认为不同 33 | if (isFunction(a)) { 34 | return false; 35 | } 36 | 37 | // 值类型,Number String Boolean 38 | if (typeof a !== 'object') { 39 | return false; 40 | } 41 | 42 | if (isArray(a)) { 43 | if (a.length !== b.length) { 44 | return false; 45 | } 46 | for (let i = a.length - 1; i >= 0; i--) { 47 | if (!equal(a[i], b[i])) { 48 | return false; 49 | } 50 | } 51 | return true; 52 | } 53 | 54 | if (!isPlainObject(a)) { 55 | return false; 56 | } 57 | 58 | const ka = objectKeys(a); 59 | const kb = objectKeys(b); 60 | // having the same number of owned properties (keys incorporates hasOwnProperty) 61 | if (ka.length !== kb.length) { 62 | return false; 63 | } 64 | 65 | // the same set of keys (although not necessarily the same order), 66 | ka.sort(); 67 | kb.sort(); 68 | // ~~~cheap key test 69 | for (let i = ka.length - 1; i >= 0; i--) { 70 | if (ka[i] != kb[i]) { 71 | return false; 72 | } 73 | } 74 | 75 | // equivalent values for every corresponding key, and ~~~possibly expensive deep test 76 | for (let i = ka.length - 1; i >= 0; i--) { 77 | const key = ka[i]; 78 | if (!equal(a[key], b[key])) { 79 | return false; 80 | } 81 | } 82 | 83 | return true; 84 | } 85 | 86 | export default equal; 87 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/render/applyStyle.ts: -------------------------------------------------------------------------------- 1 | import { DisplayObject, isDisplayObject } from '@antv/g-lite'; 2 | import { isFunction } from '@antv/util'; 3 | import { createShape } from './createShape'; 4 | 5 | function applyStyle(shape: DisplayObject, style) { 6 | if (!style) return; 7 | Object.keys(style).forEach((key) => { 8 | // 特殊处理 clip 和 offset 9 | if (key === 'clip' || key === 'offset') { 10 | const effect = style[key]; 11 | 12 | // value 为 ref 13 | if (isDisplayObject(effect?.current)) { 14 | (shape as DisplayObject).setAttribute(`${key}Path`, effect.current); 15 | return; 16 | } 17 | 18 | const effectConfig = isFunction(effect) ? effect(style) : effect; 19 | if (effectConfig) { 20 | const { type, style } = effectConfig; 21 | const effectShape = createShape(type, { style }); 22 | (shape as DisplayObject).setAttribute(`${key}Path`, effectShape); 23 | } 24 | } else { 25 | (shape as DisplayObject).setAttribute(key, style[key]); 26 | } 27 | }); 28 | } 29 | 30 | export default applyStyle; 31 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/render/findClosestShapeNode.ts: -------------------------------------------------------------------------------- 1 | import Children from '../../children'; 2 | import { VNode } from '../vnode'; 3 | import { Shape } from '../workTags'; 4 | 5 | // 查找 transform 最近的 shape 元素 6 | function findClosestShapeNode(vNode: VNode) { 7 | const { tag, children } = vNode; 8 | if (tag === Shape) { 9 | return vNode; 10 | } 11 | let shapeNode; 12 | Children.map(children, (child) => { 13 | if (shapeNode) return; 14 | shapeNode = findClosestShapeNode(child); 15 | }); 16 | return shapeNode; 17 | } 18 | 19 | export default findClosestShapeNode; 20 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/shape/circle.ts: -------------------------------------------------------------------------------- 1 | export default (layout) => { 2 | const { left, top, width } = layout; 3 | const r = width / 2; 4 | return { 5 | cx: left + r, 6 | cy: top + r, 7 | r, 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/shape/index.ts: -------------------------------------------------------------------------------- 1 | import rect from './rect'; 2 | import line from './line'; 3 | import text from './text'; 4 | import circle from './circle'; 5 | import marker from './marker'; 6 | 7 | const map = { 8 | rect, 9 | line, 10 | text, 11 | circle, 12 | marker, 13 | group: rect, 14 | }; 15 | 16 | export default (type: string, layout) => { 17 | if (!layout) return null; 18 | const fn = map[type] || rect; 19 | return fn(layout); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/shape/line.ts: -------------------------------------------------------------------------------- 1 | export default (layout) => { 2 | const { left, top, width, height } = layout; 3 | return { 4 | x1: left, 5 | y1: top, 6 | x2: left + width, 7 | y2: top + height, 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/shape/marker.ts: -------------------------------------------------------------------------------- 1 | export default (layout) => { 2 | const { left, top, width } = layout; 3 | const r = width / 2; 4 | return { 5 | x: left + r, 6 | y: top, 7 | radius: r, 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/shape/rect.ts: -------------------------------------------------------------------------------- 1 | export default (layout) => { 2 | const { left, top, width, height } = layout; 3 | return { 4 | x: left, 5 | y: top, 6 | width, 7 | height, 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/shape/text.ts: -------------------------------------------------------------------------------- 1 | export default (layout) => { 2 | const { height, left, top } = layout; 3 | return { 4 | x: left, 5 | y: top + height / 2, 6 | // 通过middle + top 才能比较好的实现文本对齐 7 | textBaseline: 'middle', 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/theme.ts: -------------------------------------------------------------------------------- 1 | // 全局默认主题 2 | export type Theme = Record; 3 | 4 | const THEME: Theme = { 5 | fontSize: '24px', 6 | fontFamily: 7 | '"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif', 8 | pixelRatio: 1, 9 | padding: [0, 0, 0, 0], 10 | }; 11 | 12 | // function setTheme(theme: Theme) { 13 | // Object.assign(THEME, theme); 14 | // } 15 | 16 | // function getTheme() { 17 | // return THEME; 18 | // } 19 | 20 | export default THEME; 21 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/util.ts: -------------------------------------------------------------------------------- 1 | import { isPlainObject, isNumber, isString, isArray } from '@antv/util'; 2 | import checkCSSRule from './cssRule'; 3 | 4 | // 默认设置50 5 | let ONE_REM: number; 6 | try { 7 | // xgraph下这段会抛错 8 | ONE_REM = parseInt(document.documentElement.style.fontSize, 10) || 50; 9 | } catch (e) { 10 | ONE_REM = 50; 11 | } 12 | const SCALE = ONE_REM / 100; 13 | 14 | /** 15 | * 像素转换 16 | * @param {Number} px - 750视觉稿像素 17 | * @return {Number} 屏幕上实际像素 18 | */ 19 | function defaultPx2hd(px: number): number { 20 | if (!px) { 21 | return 0; 22 | } 23 | return Number((px * SCALE).toFixed(1)); 24 | } 25 | 26 | function parsePadding(padding: number | number[]) { 27 | if (isNumber(padding)) { 28 | return [padding, padding, padding, padding]; 29 | } 30 | const top = padding[0]; 31 | const right = isNumber(padding[1]) ? padding[1] : padding[0]; 32 | const bottom = isNumber(padding[2]) ? padding[2] : top; 33 | const left = isNumber(padding[3]) ? padding[3] : right; 34 | return [top, right, bottom, left]; 35 | } 36 | 37 | function batch2hd(px2hd) { 38 | const batchPx2hd = (value: number | number[] | string | string[] | any) => { 39 | // 处理带px的数据 40 | if (isString(value) && /^-?\d+(\.\d+)?px$/.test(value)) { 41 | const num = value.substr(0, value.length - 2); 42 | return px2hd(Number(num)); 43 | } 44 | if (isArray(value)) { 45 | return value.map((v) => { 46 | return batchPx2hd(v); 47 | }); 48 | } 49 | if (isPlainObject(value)) { 50 | const result = {}; 51 | for (const key in value) { 52 | if (value.hasOwnProperty(key)) { 53 | const rst = batchPx2hd(value[key]); 54 | if (!rst) { 55 | result[key] = rst; 56 | continue; 57 | } 58 | if (key === 'padding' || key === 'margin') { 59 | const paddingArray = parsePadding(rst); 60 | result[key] = paddingArray; 61 | result[`${key}Top`] = paddingArray[0]; 62 | result[`${key}Right`] = paddingArray[1]; 63 | result[`${key}Bottom`] = paddingArray[2]; 64 | result[`${key}Left`] = paddingArray[3]; 65 | continue; 66 | } 67 | result[key] = rst; 68 | } 69 | } 70 | return result; 71 | } 72 | // 默认直接返回 73 | return value; 74 | }; 75 | return batchPx2hd; 76 | } 77 | 78 | const px2hd = batch2hd(defaultPx2hd); 79 | 80 | export { px2hd, batch2hd, parsePadding, checkCSSRule }; 81 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/vnode.ts: -------------------------------------------------------------------------------- 1 | import { JSX } from '../jsx/jsx-namespace'; 2 | import { DisplayObject } from '@antv/g-lite'; 3 | import Component from '../component'; 4 | import { IContext } from '../types'; 5 | import { Updater } from '../component/updater'; 6 | import Animator from './render/animator'; 7 | import { WorkTag } from './workTags'; 8 | 9 | export interface VNodeLayout { 10 | width: number; 11 | height: number; 12 | left: number; 13 | top: number; 14 | right?: number; 15 | bottom?: number; 16 | } 17 | 18 | // virtual dom 的节点 19 | export interface VNode extends JSX.Element { 20 | // 节点类型 21 | tag: WorkTag; 22 | 23 | // Instance 24 | component?: Component; 25 | shape: DisplayObject; 26 | context: IContext; 27 | updater: Updater; 28 | 29 | parent: VNode; 30 | // VNode 31 | children: VNode | VNode[] | null; 32 | 33 | // Layout 34 | layout: VNodeLayout; 35 | 36 | // Style 37 | style: any; // 当前应用的样式 38 | 39 | // 是否执行动画 40 | animate: boolean; 41 | // animation 42 | animator: Animator; 43 | 44 | transform?: VNode; 45 | } 46 | -------------------------------------------------------------------------------- /packages/f-engine/src/canvas/workTags.ts: -------------------------------------------------------------------------------- 1 | import { ElementType } from '../types'; 2 | import { isString } from '@antv/util'; 3 | 4 | export type WorkTag = 0 | 1 | 2; 5 | 6 | export const FunctionComponent = 0; 7 | export const ClassComponent = 1; 8 | export const Shape = 2; 9 | 10 | export function getWorkTag(type: ElementType): WorkTag { 11 | if (isString(type)) { 12 | return Shape; 13 | } 14 | if (type.prototype && type.prototype.isF2Component) { 15 | return ClassComponent; 16 | } 17 | return FunctionComponent; 18 | } 19 | -------------------------------------------------------------------------------- /packages/f-engine/src/component/index.ts: -------------------------------------------------------------------------------- 1 | import { JSX } from '../jsx/jsx-namespace'; 2 | import { IProps, IState } from '../types/jsx'; 3 | import { Group } from '@antv/g-lite'; 4 | import { IContext, LayoutProps } from '../types'; 5 | import { Updater } from './updater'; 6 | import { VNode } from '../canvas/vnode'; 7 | import Animator from '../canvas/render/animator'; 8 | 9 | export interface Props extends IProps { 10 | zIndex?: number; 11 | } 12 | 13 | class Component

{ 14 | props: P; 15 | state: S; 16 | context: IContext; 17 | refs: { 18 | [key: string]: Component; 19 | }; 20 | updater: Updater; 21 | // 对应 G 的group, 每个组件渲染的父节点 22 | container: Group; 23 | layout: LayoutProps; 24 | // render 返回的节点 25 | children: VNode | VNode[] | null; 26 | isMounted = false; 27 | 28 | animate: boolean; 29 | animator: Animator; 30 | 31 | // State 内部私有属性 32 | destroyed = false; 33 | _vNode: VNode; 34 | 35 | constructor(props: P, context?: IContext, updater?: Updater) { 36 | this.props = props; 37 | this.state = {} as S; 38 | this.context = context; 39 | this.updater = updater; 40 | } 41 | willMount() {} 42 | didMount() {} 43 | shouldUpdate(_nextProps: P): boolean { 44 | return true; 45 | } 46 | willReceiveProps(_props: P, _context?: IContext) {} 47 | willUpdate() {} 48 | didUpdate() {} 49 | render(): JSX.Element | null { 50 | return null; 51 | } 52 | willUnmount() {} 53 | didUnmount() {} 54 | setState(partialState: S, callback?: () => void) { 55 | if (this.destroyed) { 56 | return; 57 | } 58 | this.updater.enqueueSetState(this, partialState, callback); 59 | } 60 | forceUpdate(callback?: () => void) { 61 | if (this.destroyed) { 62 | return; 63 | } 64 | this.updater.enqueueForceUpdate(this, {} as S, callback); 65 | } 66 | setAnimate(animate: boolean) { 67 | this.animate = animate; 68 | this._vNode.animate = animate; 69 | } 70 | destroy() { 71 | this.destroyed = true; 72 | this.animator = null; 73 | } 74 | } 75 | 76 | // 标识是否是组件 77 | // @ts-ignore 78 | Component.prototype.isF2Component = true; 79 | 80 | export default Component; 81 | -------------------------------------------------------------------------------- /packages/f-engine/src/component/updater.ts: -------------------------------------------------------------------------------- 1 | import Canvas from '../canvas'; 2 | import Component from '.'; 3 | 4 | export interface Updater { 5 | enqueueSetState: (component: Component, partialState: S, callback?: () => void) => void; 6 | enqueueForceUpdate: (component: Component, partialState: S, callback?: () => void) => void; 7 | } 8 | 9 | function createUpdater(canvas: Canvas) { 10 | const setStateQueue = []; 11 | 12 | function process() { 13 | let item; 14 | 15 | const renderComponents = []; 16 | const renderCallbackQueue = []; 17 | 18 | while ((item = setStateQueue.shift())) { 19 | const { state, component, callback } = item; 20 | 21 | // 组件已销毁,不再触发 setState 22 | if (component.destroyed) { 23 | continue; 24 | } 25 | 26 | // 如果没有prevState,则将当前的state作为初始的prevState 27 | if (!component.prevState) { 28 | component.prevState = Object.assign({}, component.state); 29 | } 30 | 31 | // 如果stateChange是一个方法,也就是setState的第二种形式 32 | if (typeof state === 'function') { 33 | Object.assign(component.state, state(component.prevState, component.props)); 34 | } else { 35 | // 如果stateChange是一个对象,则直接合并到setState中 36 | Object.assign(component.state, state); 37 | } 38 | 39 | component.prevState = component.state; 40 | 41 | if (typeof callback === 'function') { 42 | renderCallbackQueue.push({ callback, component }); 43 | } 44 | 45 | if (renderComponents.indexOf(component) < 0) { 46 | renderComponents.push(component); 47 | } 48 | } 49 | 50 | canvas.updateComponents(renderComponents); 51 | 52 | // callback queue 53 | commitRenderQueue(renderCallbackQueue); 54 | } 55 | 56 | function enqueueSetState(component: Component, state, callback?: () => void) { 57 | if (setStateQueue.length === 0) { 58 | setTimeout(process, 0); 59 | } 60 | setStateQueue.push({ 61 | component, 62 | state, 63 | callback, 64 | }); 65 | } 66 | 67 | function commitRenderQueue(callbackQueue) { 68 | for (let i = 0; i < callbackQueue.length; i++) { 69 | const { callback, component } = callbackQueue[i]; 70 | callback.call(component); 71 | } 72 | } 73 | 74 | const updater = { 75 | // isMounted: function(publicInstance) { 76 | // return false; 77 | // }, 78 | enqueueForceUpdate: enqueueSetState, 79 | // enqueueReplaceState: function(publicInstance, completeState) { 80 | // }, 81 | enqueueSetState, 82 | }; 83 | 84 | return updater; 85 | } 86 | 87 | export { createUpdater }; 88 | -------------------------------------------------------------------------------- /packages/f-engine/src/createContext.ts: -------------------------------------------------------------------------------- 1 | import { JSX } from './jsx/jsx-namespace'; 2 | import { FunctionComponent } from './types'; 3 | 4 | export interface ReactContext { 5 | Provider: FunctionComponent<{ value: T; children: JSX.Element }>; 6 | Injecter: FunctionComponent<{ children: JSX.Element; [key: string]: any }>; 7 | Consumer: FunctionComponent<{ children: (value: T) => JSX.Element | null }>; 8 | } 9 | 10 | export default function createContext(defaultValue?: T) { 11 | // 创建 Context 对象 12 | const context = { 13 | _currentValue: defaultValue, 14 | } as any; 15 | 16 | // 定义 Provider 组件 17 | const Provider = function Provider({ value, children }) { 18 | context._currentValue = value; 19 | return children; 20 | }; 21 | 22 | // Injecter 可以往全局的 context 注入内容 23 | const Injecter = function Injecter({ children, ...props }, context) { 24 | Object.assign(context, props); 25 | return children; 26 | }; 27 | Injecter.contextInjecter = context; 28 | 29 | // 定义 Consumer 组件 30 | const Consumer = function Consumer({ children }) { 31 | return children(context._currentValue); 32 | }; 33 | 34 | context.Provider = Provider; 35 | context.Injecter = Injecter; 36 | context.Consumer = Consumer; 37 | 38 | return context as ReactContext; 39 | } 40 | -------------------------------------------------------------------------------- /packages/f-engine/src/createRef.ts: -------------------------------------------------------------------------------- 1 | export default function createRef() { 2 | const ref = { 3 | current: null as T, 4 | }; 5 | return ref; 6 | } 7 | -------------------------------------------------------------------------------- /packages/f-engine/src/gesture.ts: -------------------------------------------------------------------------------- 1 | import { DisplayObject, Canvas } from '@antv/g-lite'; 2 | 3 | class Gesture { 4 | private el: DisplayObject | Canvas; 5 | 6 | constructor(element: DisplayObject | Canvas) { 7 | this.el = element; 8 | } 9 | 10 | on(eventName: string, listener: (...args: any[]) => void) { 11 | if (!eventName) return; 12 | const { el } = this; 13 | el.addEventListener(eventName, listener); 14 | } 15 | 16 | off(eventName: string, listener: (...args: any[]) => void) { 17 | if (!eventName) return; 18 | const { el } = this; 19 | el.removeEventListener(eventName, listener); 20 | } 21 | } 22 | 23 | export default Gesture; 24 | -------------------------------------------------------------------------------- /packages/f-engine/src/index.ts: -------------------------------------------------------------------------------- 1 | import { computeLayout } from './canvas/render'; 2 | import { Renderer as CanvasRenderer } from '@antv/g-mobile-canvas'; 3 | import { parseColor } from '@antv/g-lite'; 4 | import * as Smooth from './shape/util/smooth'; 5 | 6 | export { JSX } from './jsx/jsx-namespace'; 7 | // export createElement 别名 8 | export { jsx as createElement, Fragment, jsx } from './jsx'; 9 | export { registerTag } from './jsx/tag'; 10 | export { default as Canvas, CanvasProps } from './canvas'; 11 | export { default as Component } from './component'; 12 | export { default as Children } from './children'; 13 | export { default as createRef } from './createRef'; 14 | export { default as createContext } from './createContext'; 15 | export { default as Timeline, TimelineProps } from './timeline'; 16 | export { default as Gesture } from './gesture'; 17 | export { CanvasRenderer, computeLayout, Smooth, parseColor }; 18 | export { default as isEqual } from './canvas/equal'; 19 | export { default as Player, PlayerProps } from './player'; 20 | 21 | // 导出 ts 类型 22 | export { 23 | IProps, 24 | IState, 25 | IContext, 26 | ComponentType, 27 | FC, 28 | HOC, 29 | ClassComponent, 30 | Ref, 31 | LayoutProps, 32 | AnimationProps, 33 | ShapeProps, 34 | GroupShapeProps, 35 | RectShapeProps, 36 | CircleShapeProps, 37 | LineShapeProps, 38 | PolygonShapeProps, 39 | PolylineShapeProps, 40 | TextShapeProps, 41 | ImageShapeProps, 42 | PathShapeProps, 43 | ArcShapeProps, 44 | SectorShapeProps, 45 | MarkerShapeProps, 46 | ShapeStyleProps, 47 | GroupStyleProps, 48 | RectStyleProps, 49 | CircleStyleProps, 50 | LineStyleProps, 51 | PolygonStyleProps, 52 | PolylineStyleProps, 53 | TextStyleProps, 54 | ImageStyleProps, 55 | PathStyleProps, 56 | ArcStyleProps, 57 | SectorStyleProps, 58 | MarkerStyleProps, 59 | } from './types'; 60 | -------------------------------------------------------------------------------- /packages/f-engine/src/jsx/fragment.ts: -------------------------------------------------------------------------------- 1 | export default (props) => { 2 | return props.children; 3 | }; 4 | -------------------------------------------------------------------------------- /packages/f-engine/src/jsx/index.ts: -------------------------------------------------------------------------------- 1 | import { jsx } from './jsx-classic'; 2 | import Fragment from './fragment'; 3 | 4 | export { jsx, Fragment }; 5 | -------------------------------------------------------------------------------- /packages/f-engine/src/jsx/jsx-automatic.ts: -------------------------------------------------------------------------------- 1 | import { JSX as JSXNamespace } from './jsx-namespace'; 2 | import { ElementType } from '../types'; 3 | 4 | // 实现jsx-automatic 入口 5 | export function jsx(type: ElementType, config, key?: string): JSXNamespace.Element { 6 | const { ref, ...props } = config || {}; 7 | 8 | // Resolve default props 9 | // This is a simplified version of the React's defaultProps resolution. 10 | // See https://github.com/facebook/react/blob/main/packages/react/src/jsx/ReactJSXElement.js 11 | if (typeof type === 'function' && type['defaultProps']) { 12 | const defaultProps = type['defaultProps']; 13 | for (const propName in defaultProps) { 14 | if (props[propName] === undefined) { 15 | props[propName] = defaultProps[propName]; 16 | } 17 | } 18 | } 19 | 20 | return { 21 | key, 22 | ref, 23 | type, 24 | props, 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /packages/f-engine/src/jsx/jsx-classic.ts: -------------------------------------------------------------------------------- 1 | import { JSX as JSXNamespace } from './jsx-namespace'; 2 | import { ElementType } from '../types'; 3 | 4 | export namespace jsx { 5 | // https://www.tslang.cn/docs/handbook/jsx.html 6 | export namespace JSX { 7 | export type Element = JSXNamespace.Element; 8 | export type ElementClass = JSXNamespace.ElementClass; 9 | export type IntrinsicElements = JSXNamespace.IntrinsicElements; 10 | export type ElementAttributesProperty = JSXNamespace.ElementAttributesProperty; 11 | export type ElementChildrenAttribute = JSXNamespace.ElementChildrenAttribute; 12 | export type IntrinsicAttributes = JSXNamespace.IntrinsicAttributes; 13 | export type IntrinsicClassAttributes = JSXNamespace.IntrinsicClassAttributes; 14 | } 15 | } 16 | 17 | // 实现jsx-classic 入口 18 | export function jsx(type: ElementType, config, ...children): JSXNamespace.Element { 19 | const { key, ref, ...props } = config || {}; 20 | 21 | // 保持和automatic模式一致 22 | if (children.length) { 23 | props.children = children.length === 1 ? children[0] : children; 24 | } 25 | 26 | // Resolve default props 27 | // This is a simplified version of the React's defaultProps resolution. 28 | // See https://github.com/facebook/react/blob/main/packages/react/src/jsx/ReactJSXElement.js 29 | if (typeof type === 'function' && type['defaultProps']) { 30 | const defaultProps = type['defaultProps']; 31 | for (const propName in defaultProps) { 32 | if (props[propName] === undefined) { 33 | props[propName] = defaultProps[propName]; 34 | } 35 | } 36 | } 37 | 38 | return { 39 | key, 40 | ref, 41 | type, 42 | props, 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /packages/f-engine/src/jsx/jsx-namespace.d.ts: -------------------------------------------------------------------------------- 1 | import { Ref, ElementType, IProps } from '../types/jsx'; 2 | import { 3 | GroupShapeProps, 4 | RectShapeProps, 5 | CircleShapeProps, 6 | LineShapeProps, 7 | PolygonShapeProps, 8 | PolylineShapeProps, 9 | ArcShapeProps, 10 | SectorShapeProps, 11 | TextShapeProps, 12 | MarkerShapeProps, 13 | ImageShapeProps, 14 | PathShapeProps, 15 | } from '../types/shape'; 16 | 17 | export namespace JSX { 18 | export interface Element { 19 | key: string | null; 20 | ref?: Ref; 21 | type: ElementType; 22 | props: IProps; 23 | [key: string]: any; 24 | } 25 | 26 | export interface ElementClass { 27 | props: IProps; 28 | render(): Element | null | Promise; 29 | } 30 | 31 | export interface ElementAttributesProperty { 32 | props: IProps; 33 | } 34 | 35 | export interface IntrinsicAttributes { 36 | key?: number | string; 37 | ref?: Ref; 38 | animate?: boolean; 39 | transformFrom?: any; 40 | children?: any; 41 | } 42 | 43 | export interface IntrinsicClassAttributes { 44 | key?: number | string; 45 | ref?: Ref; 46 | animate?: boolean; 47 | transformFrom?: any; 48 | children?: any; 49 | } 50 | 51 | export interface ElementChildrenAttribute { 52 | children: {}; 53 | } 54 | 55 | export interface IntrinsicElements { 56 | group: GroupShapeProps; 57 | rect: RectShapeProps; 58 | circle: CircleShapeProps; 59 | line: LineShapeProps; 60 | polygon: PolygonShapeProps; 61 | polyline: PolylineShapeProps; 62 | arc: ArcShapeProps; 63 | sector: SectorShapeProps; 64 | text: TextShapeProps; 65 | marker: MarkerShapeProps; 66 | image: ImageShapeProps; 67 | path: PathShapeProps; 68 | [key: string]: any; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /packages/f-engine/src/jsx/jsx-runtime.ts: -------------------------------------------------------------------------------- 1 | import { jsx } from './jsx-automatic'; 2 | import Fragment from './fragment'; 3 | 4 | export { Fragment, jsx, jsx as jsxs, jsx as jsxDEV }; 5 | export { JSX } from './jsx-namespace'; 6 | -------------------------------------------------------------------------------- /packages/f-engine/src/jsx/tag.ts: -------------------------------------------------------------------------------- 1 | import { DisplayObject } from '@antv/g-lite'; 2 | 3 | type DisplayObjectConstructor = typeof DisplayObject; 4 | 5 | const SHAPE_TAG: Record = {}; 6 | 7 | /** 8 | * 注册新的标签 9 | */ 10 | const registerTag = (name: string, ShapeConstructor): void => { 11 | SHAPE_TAG[name] = ShapeConstructor; 12 | }; 13 | 14 | const getTag = (type: string): DisplayObjectConstructor => { 15 | return SHAPE_TAG[type]; 16 | }; 17 | 18 | export { registerTag, getTag }; 19 | -------------------------------------------------------------------------------- /packages/f-engine/src/playerFrames.ts: -------------------------------------------------------------------------------- 1 | import Children from './children'; 2 | 3 | export interface playerFrame { 4 | to: Record; 5 | duration?: number; 6 | delay?: number; 7 | } 8 | 9 | export function generateFrameElement(cur: Record, element) { 10 | if (!element) return; 11 | return Children.map(element, (child) => { 12 | const { key, props } = child; 13 | 14 | const newProps = cur[key] ? cur[key].to : {}; 15 | 16 | const children = generateFrameElement(cur, props.children); 17 | return Children.cloneElement(child, { ...newProps, children }); 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/f-engine/src/shape/index.ts: -------------------------------------------------------------------------------- 1 | export * from './arc'; 2 | export * from './marker'; 3 | export * from './sector'; 4 | export * from './smoothPolyline'; 5 | -------------------------------------------------------------------------------- /packages/f-engine/src/shape/marker.ts: -------------------------------------------------------------------------------- 1 | import { DisplayObjectConfig, BaseStyleProps } from '@antv/g-lite'; 2 | import { Path } from '@antv/g-lite'; 3 | import { PathArray } from '@antv/util'; 4 | 5 | export interface MarkerStyleProps extends BaseStyleProps { 6 | x?: string | number; 7 | y?: string | number; 8 | symbol?: 'circle' | 'square' | 'arrow'; 9 | radius?: string | number; 10 | } 11 | 12 | const SYMBOLS = { 13 | circle(x, y, r): PathArray { 14 | return [ 15 | ['M', x - r, y], 16 | ['A', r, r, 0, 1, 0, x + r, y], 17 | ['A', r, r, 0, 1, 0, x - r, y], 18 | ]; 19 | }, 20 | 21 | square(x, y, r): PathArray { 22 | return [ 23 | ['M', x - r, y - r], 24 | ['L', x + r, y - r], 25 | ['L', x + r, y + r], 26 | ['L', x - r, y + r], 27 | ['Z'], 28 | ]; 29 | }, 30 | 31 | arrow(x, y, r): PathArray { 32 | return [ 33 | ['M', x - r, y + (2 * r) / Math.sqrt(3)], 34 | ['L', x + r, y + (2 * r) / Math.sqrt(3)], 35 | ['L', x, y - (2 * r) / Math.sqrt(3)], 36 | ['Z'], 37 | ]; 38 | }, 39 | }; 40 | 41 | export class Marker extends Path { 42 | parsedStyle: any; 43 | 44 | constructor(config: DisplayObjectConfig) { 45 | super(config); 46 | this.updatePath(); 47 | } 48 | 49 | setAttribute(name, value, force?: boolean) { 50 | super.setAttribute(name, value, force); 51 | if (['x', 'y', 'symbol', 'radius'].indexOf(name) > -1) { 52 | this.updatePath(); 53 | } 54 | } 55 | 56 | updatePath() { 57 | const { x = 0, y = 0 } = this.parsedStyle; 58 | const { radius, symbol } = this.attributes as MarkerStyleProps; 59 | if (!symbol) return; 60 | const method = SYMBOLS[symbol]; 61 | if (!method) return; 62 | 63 | const path = method(x, y, radius); 64 | 65 | super.setAttribute('path', path); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /packages/f-engine/src/shape/smoothPolyline.ts: -------------------------------------------------------------------------------- 1 | import { Path } from '@antv/g-lite'; 2 | import { PathArray } from '@antv/util'; 3 | import * as Smooth from './util/smooth'; 4 | 5 | 6 | export class SmoothPolyline extends Path { 7 | static tag = 'smooth-polyline'; 8 | parsedStyle: any; 9 | 10 | constructor(config) { 11 | super(config); 12 | this.updatePath(); 13 | } 14 | 15 | setAttribute(name, value, force?: boolean) { 16 | super.setAttribute(name, value, force); 17 | if (['smooth', 'points', 'step'].indexOf(name) > -1) { 18 | this.updatePath(); 19 | } 20 | } 21 | 22 | private updatePath() { 23 | const { smooth, points, step } = this.parsedStyle; 24 | const { points: pos } = points; 25 | 26 | const d: PathArray = [['M', pos[0][0], pos[0][1]]]; 27 | 28 | if (smooth) { 29 | const constaint = [ 30 | [0, 0], 31 | [1, 1], 32 | ]; 33 | const sps = Smooth.smooth( 34 | pos.map((d) => { 35 | return { 36 | x: d[0], 37 | y: d[1], 38 | }; 39 | }), 40 | false, 41 | constaint 42 | ); 43 | 44 | for (let i = 0, n = sps.length; i < n; i++) { 45 | const sp = sps[i]; 46 | d.push(['C', sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]); 47 | } 48 | } else if (step) { 49 | let i; 50 | let l; 51 | switch (step) { 52 | case "start": 53 | for (i = 1, l = pos.length; i < l; i++) { 54 | const x = pos[i - 1][0] 55 | d.push(['L', x, pos[i - 1][1]]) 56 | d.push(['L', x, pos[i][1]]) 57 | d.push(['L', pos[i][0], pos[i][1]]); 58 | } 59 | break; 60 | case "middle": 61 | for (i = 1, l = pos.length; i < l; i++) { 62 | const x = (pos[i][0] + pos[i - 1][0]) / 2 63 | d.push(['L', x, pos[i - 1][1]]) 64 | d.push(['L', x, pos[i][1]]) 65 | d.push(['L', pos[i][0], pos[i][1]]); 66 | } 67 | break; 68 | case "end": 69 | for (i = 1, l = pos.length; i < l; i++) { 70 | const x = pos[i][0] 71 | d.push(['L', x, pos[i - 1][1]]) 72 | d.push(['L', x, pos[i][1]]) 73 | d.push(['L', pos[i][0], pos[i][1]]); 74 | } 75 | break; 76 | } 77 | } else { 78 | let i; 79 | let l; 80 | for (i = 1, l = pos.length - 1; i < l; i++) { 81 | d.push(['L', pos[i][0], pos[i][1]]); 82 | } 83 | d.push(['L', pos[l][0], pos[l][1]]); 84 | } 85 | super.setAttribute('path', d); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /packages/f-engine/src/shape/util/util.ts: -------------------------------------------------------------------------------- 1 | const polarToCartesian = ( 2 | centerX: number, 3 | centerY: number, 4 | radius: number, 5 | angleInRadian: number 6 | ) => { 7 | return { 8 | x: centerX + radius * Math.cos(angleInRadian), 9 | y: centerY + radius * Math.sin(angleInRadian), 10 | }; 11 | }; 12 | 13 | export { polarToCartesian }; 14 | -------------------------------------------------------------------------------- /packages/f-engine/src/timeline.ts: -------------------------------------------------------------------------------- 1 | import { JSX } from './jsx/jsx-namespace'; 2 | import Component from './component'; 3 | import Children from './children'; 4 | import { isNumber } from '@antv/util'; 5 | 6 | export interface TimelineProps { 7 | /** 8 | * @title 起始索引 9 | * @description 开始的组件索引 10 | */ 11 | start?: number; 12 | /** 13 | * @title 延迟(ms) 14 | * @description 组件播放的延迟时间 15 | */ 16 | delay?: number; 17 | /** 18 | * @title 自动循环 19 | * @description 是否自动循环 20 | */ 21 | loop?: boolean; 22 | /** 23 | * @ignore 24 | * 自动播放 25 | */ 26 | autoPlay?: boolean; 27 | /** 28 | * @ignore 29 | * 子组件 30 | */ 31 | children?: any; 32 | } 33 | 34 | class Timeline extends Component { 35 | index: number; 36 | delay: number; 37 | 38 | private timer: any; 39 | 40 | constructor(props: TimelineProps) { 41 | super(props); 42 | const { delay, start = 0, children, autoPlay } = props; 43 | const count = Children.toArray(children as JSX.Element).length; 44 | 45 | this.state = { 46 | delay, 47 | count, 48 | index: start, 49 | autoPlay, 50 | }; 51 | } 52 | 53 | didMount() { 54 | this.animator.on('end', this.next); 55 | } 56 | 57 | willReceiveProps(nextProps: TimelineProps): void { 58 | const { start: nextStart, delay: nextDelay, autoPlay: nextAutoPlay } = nextProps; 59 | const { index, delay, autoPlay } = this.state; 60 | 61 | if (isNumber(nextStart) || nextDelay !== delay || nextAutoPlay !== autoPlay) { 62 | // 更新时清除 setTimeout 63 | clearTimeout(this.timer); 64 | this.setState({ 65 | delay: nextDelay, 66 | index: isNumber(nextStart) ? nextStart : index, 67 | autoPlay: nextAutoPlay, 68 | }); 69 | } 70 | } 71 | 72 | didUnmount(): void { 73 | this.animator.off('end', this.next); 74 | } 75 | 76 | next = () => { 77 | const { state, props } = this; 78 | const { index, count, delay, autoPlay } = state; 79 | const { loop } = props; 80 | 81 | if (autoPlay === false) { 82 | return; 83 | } 84 | const next = loop ? (index + 1) % count : index + 1; 85 | if (next >= count) { 86 | return; 87 | } 88 | this.timer = setTimeout(() => { 89 | this.setState({ 90 | index: next, 91 | }); 92 | }, delay || 0); 93 | }; 94 | 95 | render() { 96 | const { state, props } = this; 97 | const { children } = props; 98 | const { index } = state; 99 | const childrenArray = Children.toArray(children); 100 | return childrenArray[index]; 101 | } 102 | } 103 | 104 | export default Timeline; 105 | -------------------------------------------------------------------------------- /packages/f-engine/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './jsx'; 2 | export * from './shape'; 3 | -------------------------------------------------------------------------------- /packages/f-engine/src/types/jsx.ts: -------------------------------------------------------------------------------- 1 | import { JSX } from '../jsx/jsx-namespace'; 2 | import Component from '../component'; 3 | 4 | export interface Ref { 5 | current?: T; 6 | } 7 | 8 | export interface IProps { 9 | [key: string]: any; 10 | } 11 | 12 | export interface IState { 13 | [key: string]: any; 14 | } 15 | 16 | export interface IContext { 17 | [key: string]: any; 18 | } 19 | 20 | export type ElementType = 21 | | string 22 | | ((props: IProps, context?: IContext) => JSX.Element | null) 23 | | (new (props: IProps, context?: IContext) => Component); 24 | 25 | export interface FunctionComponent

{ 26 | (props: P, context?: any): JSX.Element | null; 27 | } 28 | 29 | export interface ComponentClass

{ 30 | new (props: P, context?: any): Component; 31 | } 32 | 33 | export type ComponentType

= ComponentClass

| FunctionComponent

; 34 | 35 | export type ClassComponent

= ComponentClass; 36 | export type FC

= FunctionComponent

; 37 | export type HOC, P = {}, S = {}> = FC

& T; 38 | -------------------------------------------------------------------------------- /packages/f-engine/test/__image_snapshots__/create-context-test-tsx-create-context-inject-context-inject-context-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/__image_snapshots__/create-context-test-tsx-create-context-inject-context-inject-context-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/__image_snapshots__/create-context-test-tsx-create-context-provider-context-context-type-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/__image_snapshots__/create-context-test-tsx-create-context-provider-context-context-type-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/__image_snapshots__/create-context-test-tsx-create-context-provider-context-create-context-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/__image_snapshots__/create-context-test-tsx-create-context-provider-context-create-context-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/__image_snapshots__/create-context-test-tsx-create-context-provider-context-create-context-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/__image_snapshots__/create-context-test-tsx-create-context-provider-context-create-context-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/FragFunction.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Fragment, Canvas, Component } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | const context = createContext(); 4 | import { Renderer } from '@antv/g-mobile-canvas'; 5 | class View extends Component { 6 | render() { 7 | return ( 8 | <> 9 | 18 | 19 | ); 20 | } 21 | } 22 | 23 | describe('Canvas', () => { 24 | it('Fragment Function', async () => { 25 | const renderer = new Renderer(); 26 | 27 | const { props } = ( 28 | 29 | 30 | 31 | ); 32 | 33 | const canvas = new Canvas(props); 34 | canvas.render(); 35 | 36 | await delay(100); 37 | expect(context).toMatchImageSnapshot(); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animate-false-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animate-false-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animation-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animation-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animation-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animation-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animation-3-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animation-3-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animation-4-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-animation-4-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-clip-animation-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-clip-animation-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-component-animation-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-component-animation-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-component-update-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-component-update-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-duration-empty-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-duration-empty-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-property-empty-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/animation-test-tsx-动画-property-empty-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/diff-test-tsx-canvas-渲染顺序-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/diff-test-tsx-canvas-渲染顺序-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/diff-test-tsx-canvas-渲染顺序-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/diff-test-tsx-canvas-渲染顺序-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/frag-function-test-tsx-canvas-fragment-function-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/frag-function-test-tsx-canvas-fragment-function-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/index-test-tsx-canvas-g-render-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/index-test-tsx-canvas-g-render-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-component-layout-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-component-layout-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-layout-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-layout-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-layout-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-layout-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-line-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-line-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-marker-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-marker-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-text-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-text-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-text-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/layout-test-tsx-canvas-text-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/resize-test-tsx-canvas-resize-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/resize-test-tsx-canvas-resize-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/resize-test-tsx-canvas-resize-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/resize-test-tsx-canvas-resize-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/__image_snapshots__/resize-test-tsx-canvas-resize-context-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/__image_snapshots__/resize-test-tsx-canvas-resize-context-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/diff.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | const context = createContext(); 4 | 5 | class Circle extends Component { 6 | render() { 7 | return ( 8 | 16 | ); 17 | } 18 | } 19 | 20 | function Rect() { 21 | return ( 22 | 31 | ); 32 | } 33 | 34 | describe('Canvas', () => { 35 | it('渲染顺序', async () => { 36 | const { props } = ( 37 | 38 | 39 | {null} 40 | 41 | 42 | ); 43 | 44 | const canvas = new Canvas(props); 45 | await canvas.render(); 46 | await delay(100); 47 | 48 | expect(context).toMatchImageSnapshot(); 49 | 50 | const update = ( 51 | 52 | {null} 53 | 54 | 55 | 56 | ); 57 | 58 | await canvas.update(update.props); 59 | 60 | await delay(100); 61 | 62 | expect(context).toMatchImageSnapshot(); 63 | }); 64 | }); 65 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/render/__image_snapshots__/compute-layout-test-tsx-compute-layout-布局计算-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/render/__image_snapshots__/compute-layout-test-tsx-compute-layout-布局计算-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/render/__image_snapshots__/create-animation-test-tsx-图形绘制顺序-图形绘制顺序-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/render/__image_snapshots__/create-animation-test-tsx-图形绘制顺序-图形绘制顺序-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/render/__image_snapshots__/create-animation-test-tsx-图形绘制顺序-图形绘制顺序-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/canvas/render/__image_snapshots__/create-animation-test-tsx-图形绘制顺序-图形绘制顺序-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/render/computeLayout.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component, computeLayout } from '../../../src'; 2 | import { createContext, delay } from '../../util'; 3 | 4 | const getElementsByClassNameFn = jest.fn(); 5 | 6 | class View extends Component { 7 | private maxWidth: number; 8 | 9 | willMount(): void { 10 | const node = computeLayout(this, this.render()); 11 | 12 | getElementsByClassNameFn(node.getElementsByClassName('text')); 13 | 14 | const { children } = node; 15 | let maxWidth = 0; 16 | children.forEach((child: any) => { 17 | const { layout } = child; 18 | const { width } = layout; 19 | maxWidth = Math.max(maxWidth, width); 20 | }); 21 | this.maxWidth = maxWidth; 22 | } 23 | render() { 24 | const { maxWidth } = this; 25 | return ( 26 | 33 | 41 | 48 | 49 | ); 50 | } 51 | } 52 | 53 | describe('computeLayout', () => { 54 | it('布局计算', async () => { 55 | const context = createContext(); 56 | const { props } = ( 57 | 58 | 59 | 60 | ); 61 | 62 | const canvas = new Canvas(props); 63 | await canvas.render(); 64 | 65 | await delay(100); 66 | 67 | expect(context).toMatchImageSnapshot(); 68 | expect(getElementsByClassNameFn.mock.calls[0][0].length).toEqual(2); 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/render/createAnimation.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component, computeLayout } from '../../../src'; 2 | import { createContext, delay } from '../../util'; 3 | 4 | class Rect extends Component { 5 | render() { 6 | const { color } = this.props; 7 | return ( 8 | 17 | ); 18 | } 19 | } 20 | 21 | class Circle extends Component { 22 | render() { 23 | const { color } = this.props; 24 | return ( 25 | 33 | ); 34 | } 35 | } 36 | 37 | class Circle1 extends Component { 38 | render() { 39 | const { color } = this.props; 40 | return ( 41 | 49 | ); 50 | } 51 | } 52 | 53 | describe('图形绘制顺序', () => { 54 | it('图形绘制顺序', async () => { 55 | const context = createContext(); 56 | const { props } = ( 57 | 58 | 59 | 60 | 61 | ); 62 | 63 | const canvas = new Canvas(props); 64 | await canvas.render(); 65 | 66 | await delay(500); 67 | expect(context).toMatchImageSnapshot(); 68 | 69 | const update = ( 70 | 71 | 72 | 73 | 74 | ); 75 | await delay(500); 76 | await canvas.update(update.props); 77 | expect(context).toMatchImageSnapshot(); 78 | }); 79 | }); 80 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/render/vnodeUpdate.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component, createRef } from '../../../src'; 2 | import { createContext, delay } from '../../util'; 3 | 4 | class Rect extends Component { 5 | render() { 6 | const { color } = this.props; 7 | return ( 8 | 17 | ); 18 | } 19 | } 20 | 21 | describe('vnode 更新', () => { 22 | it('vnode 更新', async () => { 23 | const ref = createRef(); 24 | 25 | const context = createContext(); 26 | const { props } = ( 27 | 28 | 29 | 30 | ); 31 | 32 | const canvas = new Canvas(props); 33 | await canvas.render(); 34 | 35 | const update = ( 36 | 37 | 38 | 39 | ); 40 | await delay(500); 41 | await canvas.update(update.props); 42 | 43 | expect(ref.current._vNode.props.update).toBe(true); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/resize.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component, JSX } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | const context = createContext(); 4 | import { Renderer } from '@antv/g-mobile-canvas'; 5 | const Background = (props, context) => { 6 | const { layout, color } = props; 7 | return ( 8 | 9 | 18 | 19 | ); 20 | }; 21 | 22 | describe('Canvas', () => { 23 | it('resize', async () => { 24 | const renderer = new Renderer(); 25 | 26 | const { props } = ( 27 | 28 | 36 | 42 | 48 | 49 | 50 | ); 51 | 52 | const canvas = new Canvas(props); 53 | await canvas.render(); 54 | 55 | await delay(200); 56 | expect(context).toMatchImageSnapshot(); 57 | 58 | await canvas.resize(100, 50); 59 | await delay(200); 60 | 61 | expect(context).toMatchImageSnapshot(); 62 | }); 63 | 64 | it('resize context', async () => { 65 | const renderer = new Renderer(); 66 | 67 | const { props } = ( 68 | 69 | 70 | 71 | ); 72 | 73 | const canvas = new Canvas(props); 74 | await canvas.render(); 75 | 76 | await delay(200); 77 | 78 | await canvas.resize(200, 100); 79 | await delay(200); 80 | 81 | expect(context).toMatchImageSnapshot(); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/svg/svg.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas } from '../../../src'; 2 | import { Renderer } from '@antv/g-mobile-svg'; 3 | 4 | const container = document.createElement('div'); 5 | container.style.width = '300px'; 6 | container.style.height = '200px'; 7 | document.body.appendChild(container); 8 | 9 | describe('svg', () => { 10 | it('svg renderer', async () => { 11 | const renderer = new Renderer(); 12 | const { props } = ( 13 | 14 | 21 | 22 | ); 23 | 24 | const canvas = new Canvas(props); 25 | await canvas.render(); 26 | 27 | const dataURL = await canvas.toDataURL(); 28 | expect(dataURL).toBe( 29 | 'data:image/svg+xml;charset=utf8,%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20color-interpolation-filters%3D%22sRGB%22%20style%3D%22background%3A%20transparent%3B%22%3E%3Cdefs%2F%3E%3Cg%20id%3D%22g-svg-camera%22%20transform%3D%22matrix(1%2C0%2C0%2C1%2C0%2C0)%22%3E%3Cg%20id%3D%22g-root%22%20fill%3D%22none%22%20stroke%3D%22none%22%20visibility%3D%22visible%22%20font-size%3D%2212px%22%20font-family%3D%22%26quot%3BHelvetica%20Neue%26quot%3B%2C%20Helvetica%2C%20%26quot%3BPingFang%20SC%26quot%3B%2C%20%26quot%3BHiragino%20Sans%20GB%26quot%3B%2C%20%26quot%3BMicrosoft%20YaHei%26quot%3B%2C%20Arial%2C%20sans-serif%22%20font-style%3D%22normal%22%20font-weight%3D%22normal%22%20font-variant%3D%22normal%22%20text-anchor%3D%22left%22%20stroke-dashoffset%3D%220px%22%20transform%3D%22matrix(1%2C0%2C0%2C1%2C0%2C0)%22%3E%3Cg%20transform%3D%22matrix(1%2C0%2C0%2C1%2C0%2C0)%22%3E%3Cpath%20id%3D%22g-svg-1%22%20fill%3D%22rgba(255%2C0%2C0%2C1)%22%20d%3D%22M%200%2C0%20l%20100%2C0%20l%200%2C100%20l-100%200%20z%22%20stroke%3D%22none%22%20width%3D%22100px%22%20height%3D%22100px%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E', 30 | ); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/theme.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | const context = createContext(); 4 | 5 | class Text extends Component { 6 | width: number; 7 | 8 | constructor(props, context) { 9 | super(props, context); 10 | const { width } = this.context.measureText('0.123', {}); 11 | this.width = width; 12 | } 13 | } 14 | 15 | describe('Theme', () => { 16 | describe('字体主题设置', () => { 17 | it('默认主题', async () => { 18 | const textRef = { current: null }; 19 | const { props } = ( 20 | 21 | 22 | 23 | ); 24 | 25 | const canvas = new Canvas(props); 26 | canvas.render(); 27 | await delay(0); 28 | 29 | expect(textRef.current.width).toBeCloseTo(31.02); 30 | }); 31 | 32 | it('自定义设置', async () => { 33 | const textRef = { current: null }; 34 | const { props } = ( 35 | 42 | 43 | 44 | ); 45 | 46 | const canvas = new Canvas(props); 47 | canvas.render(); 48 | await delay(0); 49 | 50 | expect(textRef.current.width).toBeCloseTo(30.916); 51 | }); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/util/px2hd.test.ts: -------------------------------------------------------------------------------- 1 | import { px2hd } from '../../../src/canvas/util'; 2 | 3 | describe('px2hd', () => { 4 | it('px2hd', () => { 5 | expect(px2hd('')).toBe(''); 6 | expect(px2hd('0')).toBe('0'); 7 | expect(px2hd(0)).toBe(0); 8 | expect(px2hd(1)).toBe(1); 9 | expect(px2hd('10px')).toBe(5); 10 | expect(px2hd('10.0px')).toBe(5); 11 | expect(px2hd('10.00px')).toBe(5); 12 | expect(px2hd('10.px')).toBe('10.px'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/f-engine/test/canvas/webgl/webgl.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas } from '../../../src'; 2 | import { Renderer } from '@antv/g-mobile-webgl'; 3 | 4 | const canvasEl = document.createElement('canvas'); 5 | canvasEl.style.display = 'block'; 6 | canvasEl.style.width = '300px'; 7 | canvasEl.style.height = '200px'; 8 | document.body.appendChild(canvasEl); 9 | 10 | const context = canvasEl.getContext('webgl'); 11 | 12 | describe('webgl', () => { 13 | it('webgl renderer', async () => { 14 | const renderer = new Renderer(); 15 | const { props } = ( 16 | 17 | 24 | 25 | ); 26 | 27 | const canvas = new Canvas(props); 28 | await canvas.render(); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /packages/f-engine/test/component/component.test.tsx: -------------------------------------------------------------------------------- 1 | import { Canvas, Component, jsx } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | 4 | describe('base/component', () => { 5 | it('子组件的 View props 更新后,则重新渲染', async () => { 6 | const context = createContext('组件props更新后重绘'); 7 | const mockCallback = jest.fn(); 8 | 9 | class StatedComponent extends Component { 10 | didMount() { 11 | this.setState({ active: true }); 12 | } 13 | render() { 14 | const { state } = this; 15 | const { active } = state; 16 | mockCallback(active); 17 | return ( 18 | 25 | ); 26 | } 27 | } 28 | 29 | const { props } = ( 30 | 31 | 32 | 33 | ); 34 | 35 | const canvas = new Canvas(props); 36 | canvas.render(); 37 | 38 | await delay(50); 39 | 40 | expect(mockCallback.mock.calls).toEqual([[undefined], [true]]); 41 | }); 42 | 43 | it('destroy 组件不再更新', async () => { 44 | const context = createContext('组件销毁后不再更新'); 45 | const mockCallback = jest.fn(); 46 | 47 | class StatedComponent extends Component { 48 | didMount() { 49 | this.setState({ active: true }, mockCallback); 50 | } 51 | render() { 52 | const { state } = this; 53 | const { active } = state; 54 | return ( 55 | 62 | ); 63 | } 64 | } 65 | 66 | const { props } = ( 67 | 68 | 69 | 70 | 71 | ); 72 | 73 | const canvas = new Canvas(props); 74 | await canvas.render(); 75 | 76 | const newChildren = ; 77 | await canvas.update({ children: newChildren }); 78 | 79 | await delay(500); 80 | expect(mockCallback.mock.calls.length).toBe(1); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /packages/f-engine/test/component/equal.test.tsx: -------------------------------------------------------------------------------- 1 | import equal from '../../src/canvas/equal'; 2 | 3 | describe('equal', () => { 4 | it('equal', () => { 5 | const fn = () => {}; 6 | 7 | expect(equal(0, 0)).toBe(true); 8 | expect(equal(0, 2)).toBe(false); 9 | expect(equal(NaN, NaN)).toBe(true); 10 | 11 | expect(equal(null, null)).toBe(true); 12 | expect(equal(null, undefined)).toBe(false); 13 | expect(equal(undefined, undefined)).toBe(true); 14 | 15 | expect(equal(fn, fn)).toBe(true); 16 | expect( 17 | equal( 18 | () => {}, 19 | () => { 20 | console.log(1); 21 | }, 22 | ), 23 | ).toBe(false); 24 | 25 | expect(equal([1, 2], [1, 2])).toBe(true); 26 | expect(equal([1, 2], [1, 3])).toBe(false); 27 | 28 | expect(equal({ a: 1 }, { a: 1 })).toBe(true); 29 | expect(equal({ a: 1 }, { a: 1, b: 2 })).toBe(false); 30 | expect(equal({ a: 1, b: 2 }, { a: 1, b: NaN })).toBe(false); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/f-engine/test/g.test.tsx: -------------------------------------------------------------------------------- 1 | import { Canvas, CanvasEvent, Circle, convertToPath, Path, Rect } from '@antv/g-lite'; 2 | import { Renderer as CanvasRenderer } from '@antv/g-mobile-canvas'; 3 | import '@antv/g-web-animations-api'; 4 | import { createContext, delay } from './util'; 5 | const context = createContext(); 6 | 7 | const canvasRenderer = new CanvasRenderer(); 8 | 9 | const canvas = new Canvas({ 10 | canvas: context.canvas, 11 | width: 600, 12 | height: 500, 13 | renderer: canvasRenderer, 14 | }); 15 | 16 | describe('G 的测试使用', () => { 17 | it('test', async () => { 18 | await canvas.ready; 19 | 20 | await delay(1000); 21 | 22 | /** 23 | * Path -> Circle 24 | */ 25 | const circle = new Circle({ 26 | style: { 27 | cx: 50, 28 | cy: 50, 29 | r: 20, 30 | fill: 'red', 31 | }, 32 | }); 33 | const circlePathStr = convertToPath(circle); 34 | 35 | /** 36 | * Rect -> Circle 37 | */ 38 | const rect = new Rect({ 39 | style: { 40 | x: 10, 41 | y: 10, 42 | width: 60, 43 | height: 50, 44 | fill: 'red', 45 | }, 46 | }); 47 | 48 | canvas.appendChild(rect); 49 | const rectPathStr = convertToPath(rect); 50 | 51 | const path = new Path({ 52 | style: { 53 | fill: 'red', 54 | }, 55 | }); 56 | rect.replaceWith(path); 57 | 58 | path.style.fill = 'red'; 59 | path.style.path = rectPathStr; 60 | 61 | // canvas.appendChild(pathF); 62 | 63 | path.animate([{ path: rectPathStr }, { path: circlePathStr }], { 64 | duration: 2500, 65 | easing: 'ease', 66 | // iterations: Infinity, 67 | // direction: 'alternate', 68 | fill: 'both', 69 | }); 70 | 71 | await delay(1000); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /packages/f-engine/test/index.test.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from '../src'; 2 | 3 | describe('Index', () => { 4 | it('Index', () => { 5 | expect(Component).not.toBe(null); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/f-engine/test/jsx/jsx-automatic.test.tsx: -------------------------------------------------------------------------------- 1 | /** @jsxRuntime automatic */ 2 | /** @jsxImportSource ../../src/jsx */ 3 | 4 | import { JSX } from '../../src/jsx/jsx-namespace'; 5 | 6 | describe('jsx automatic 模式', () => { 7 | it('tagName one children', () => { 8 | const ref = {}; 9 | const group = ( 10 | 11 | 12 | 13 | ); 14 | 15 | expect(group.type).toBe('group'); 16 | expect(group.ref === ref).toBe(true); 17 | expect(group.props.a).toBe(1); 18 | expect(group.props.children.type).toBe('text'); 19 | }); 20 | 21 | it('one children map', () => { 22 | const group = ( 23 | 24 | {[1, 2].map((item) => { 25 | return ; 26 | })} 27 | 28 | ); 29 | 30 | expect(group.props.children.length).toBe(2); 31 | expect(group.props.children[0].type).toBe('text'); 32 | }); 33 | 34 | it('tagName multiple children', () => { 35 | const ref = {}; 36 | const group = ( 37 | 38 | 39 | 40 | {true ? null : } 41 | {[1, 2].map((item) => { 42 | return ; 43 | })} 44 | 45 | ); 46 | 47 | expect(group.type).toBe('group'); 48 | expect(group.ref === ref).toBe(true); 49 | expect(group.props.a).toBe(1); 50 | expect(group.props.children.length).toBe(4); 51 | expect(group.props.children[2]).toBe(null); 52 | expect(group.props.children[3].length).toBe(2); 53 | expect(group.props.children[3][0].type).toBe('text'); 54 | }); 55 | 56 | it('fragment', () => { 57 | const fragment = ( 58 | <> 59 | 60 | 61 | ); 62 | expect(typeof fragment.type).toBe('function'); 63 | expect(fragment.props.children.type).toBe('text'); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /packages/f-engine/test/jsx/jsx-classic.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Fragment } from '../../src/jsx'; 2 | 3 | describe('jsx classic 模式', () => { 4 | it('tagName one children', () => { 5 | const ref = {}; 6 | const group = ( 7 | 8 | 9 | 10 | ); 11 | 12 | expect(group.type).toBe('group'); 13 | expect(group.ref === ref).toBe(true); 14 | expect(group.props.a).toBe(1); 15 | expect(group.props.children.type).toBe('text'); 16 | }); 17 | 18 | it('one children map', () => { 19 | const group = ( 20 | 21 | {[1, 2].map((item) => { 22 | return ; 23 | })} 24 | 25 | ); 26 | 27 | expect(group.props.children.length).toBe(2); 28 | expect(group.props.children[0].type).toBe('text'); 29 | }); 30 | 31 | it('tagName multiple children', () => { 32 | const ref = {}; 33 | const group = ( 34 | 35 | 36 | 37 | {true ? null : } 38 | {[1, 2].map((item) => { 39 | return ; 40 | })} 41 | 42 | ); 43 | 44 | expect(group.type).toBe('group'); 45 | expect(group.ref === ref).toBe(true); 46 | expect(group.props.a).toBe(1); 47 | expect(group.props.children.length).toBe(4); 48 | expect(group.props.children[2]).toBe(null); 49 | expect(group.props.children[3].length).toBe(2); 50 | expect(group.props.children[3][0].type).toBe('text'); 51 | }); 52 | 53 | it('fragment', () => { 54 | const fragment = ( 55 | <> 56 | 57 | 58 | ); 59 | expect(typeof fragment.type).toBe('function'); 60 | expect(fragment.props.children.type).toBe('text'); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-clip-animation-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-clip-animation-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-custom-shape-animation-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-custom-shape-animation-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-line-offset-path-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-line-offset-path-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-offset-path-为-ref-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-offset-path-为-ref-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-text-number-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-text-number-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-text-number-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/animation-test-tsx-canvas-text-number-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-cx-cy-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-cx-cy-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-大角-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-大角-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-大角-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-大角-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-弧度-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-弧度-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-整圆-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-整圆-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-逆时针-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-逆时针-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-默认-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-arc-默认-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-角度从非-0-到-0-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-角度从非-0-到-0-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-角度从非-0-到-0-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/arc-test-tsx-arc-角度从非-0-到-0-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/clip-test-tsx-clip-animation-clip-function-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/clip-test-tsx-clip-animation-clip-function-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/clip-test-tsx-clip-clip-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/clip-test-tsx-clip-clip-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/clip-test-tsx-clip-clip-function-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/clip-test-tsx-clip-clip-function-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/index-test-tsx-canvas-arc-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/index-test-tsx-canvas-arc-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/index-test-tsx-canvas-arrow-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/index-test-tsx-canvas-arrow-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/polyline-test-tsx-polyline-polyline-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/polyline-test-tsx-polyline-polyline-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/polyline-test-tsx-polyline-step-end-polyline-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/polyline-test-tsx-polyline-step-end-polyline-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/polyline-test-tsx-polyline-step-middle-polyline-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/polyline-test-tsx-polyline-step-middle-polyline-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/polyline-test-tsx-polyline-step-start-polyline-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/polyline-test-tsx-polyline-step-start-polyline-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/register-tag-test-tsx-自定义标签-使用自定义标签-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/register-tag-test-tsx-自定义标签-使用自定义标签-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-clockwise-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-clockwise-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-radius-不同-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-radius-不同-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-sector-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-sector-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-sector-clip-clip-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-sector-clip-clip-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-临界数值-0-angle-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-临界数值-0-angle-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-内角合并-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-内角合并-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-整圆-逆时针-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-整圆-逆时针-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-整圆-顺时针-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-整圆-顺时针-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-极小角度扇形区域-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-极小角度扇形区域-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-角度从非-0-到-0-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-角度从非-0-到-0-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-角度从非-0-到-0-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-角度从非-0-到-0-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-逆时针绘制-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/sector-test-tsx-sector-逆时针绘制-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/__image_snapshots__/z-index-test-tsx-z-index-z-index-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/shape/__image_snapshots__/z-index-test-tsx-z-index-z-index-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/shape/registerTag.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, registerTag } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | const context = createContext(); 4 | import { Renderer } from '@antv/g-mobile-canvas'; 5 | import { Path } from '@antv/g-lite'; 6 | 7 | class CustomTag extends Path {} 8 | 9 | registerTag('customTag', CustomTag); 10 | 11 | describe('自定义标签', () => { 12 | it('使用自定义标签', async () => { 13 | const renderer = new Renderer(); 14 | 15 | const { props } = ( 16 | 17 | 27 | 28 | ); 29 | 30 | const canvas = new Canvas(props); 31 | canvas.render(); 32 | await delay(200); 33 | expect(context).toMatchImageSnapshot(); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/f-engine/test/shape/zIndex.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | const context = createContext(); 4 | import { Renderer } from '@antv/g-mobile-canvas'; 5 | 6 | class Rect extends Component { 7 | render() { 8 | const { fill } = this.props; 9 | return ( 10 | 19 | ); 20 | } 21 | } 22 | 23 | describe('zIndex', () => { 24 | it('zIndex', async () => { 25 | const renderer = new Renderer(); 26 | 27 | const { props } = ( 28 | 29 | 30 | 31 | 32 | ); 33 | 34 | const canvas = new Canvas(props); 35 | canvas.render(); 36 | await delay(200); 37 | expect(context).toMatchImageSnapshot(); 38 | 39 | const update = ( 40 | 41 | 42 | 43 | 44 | ); 45 | canvas.update(update.props); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/component-test-tsx-测试组件变化-tranform-ref-嵌套-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/component-test-tsx-测试组件变化-tranform-ref-嵌套-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/component-test-tsx-测试组件变化-指定-tranform-ref-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/component-test-tsx-测试组件变化-指定-tranform-ref-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/component-test-tsx-测试组件变化-组件切换-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/component-test-tsx-测试组件变化-组件切换-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-finish-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-finish-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-key-frames-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-key-frames-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-key-frames-连续变化-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-key-frames-连续变化-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-leave-动画-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-leave-动画-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-pause-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-pause-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-props-未变-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-props-未变-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-props-未变-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-props-未变-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-子组件-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-子组件-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-播放中finish-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-播放中finish-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-暂停完播放-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/key-frames-test-tsx-player-暂停完播放-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/morph-test-tsx-形变动画-circle-到-group-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/morph-test-tsx-形变动画-circle-到-group-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/morph-test-tsx-形变动画-group-到-circle-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/morph-test-tsx-形变动画-group-到-circle-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-ref-func-test-tsx-player-go-to等于总时长时-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-ref-func-test-tsx-player-go-to等于总时长时-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-clip-animation-clip-增加-delete-after-complete-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-clip-animation-clip-增加-delete-after-complete-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-clip-animation-暂停-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-clip-animation-暂停-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-clip-animation-结束后播放-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-clip-animation-结束后播放-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-clip-animation-跳转超出总时长-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-clip-animation-跳转超出总时长-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-player-go-to-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-player-go-to-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-player-go-to-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-player-go-to-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-player-go-to-3-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-player-go-to-3-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-player-多组动画回跳-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/player-test-tsx-player-多组动画回跳-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/timeline-test-tsx-timeline-timeline-播放-1-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/timeline-test-tsx-timeline-timeline-播放-1-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/__image_snapshots__/timeline-test-tsx-timeline-timeline-播放-2-snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-engine/test/timeline/__image_snapshots__/timeline-test-tsx-timeline-timeline-播放-2-snap.png -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/component.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component, Timeline, Fragment } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | 4 | class Component1 extends Component { 5 | render() { 6 | return ( 7 | 22 | ); 23 | } 24 | } 25 | 26 | class Component2 extends Component { 27 | render() { 28 | return ( 29 | 43 | ); 44 | } 45 | } 46 | 47 | class Wrapper extends Component { 48 | render() { 49 | return ; 50 | } 51 | } 52 | 53 | describe('测试组件变化', () => { 54 | it('组件切换', async () => { 55 | const context = createContext(); 56 | const { props } = ( 57 | 58 | 59 | 60 | 61 | 62 | 63 | ); 64 | 65 | const canvas = new Canvas(props); 66 | await delay(100); 67 | await canvas.render(); 68 | await delay(1000); 69 | 70 | expect(context).toMatchImageSnapshot(); 71 | }); 72 | 73 | it('指定 tranformRef', async () => { 74 | const context = createContext(); 75 | const ref = {}; 76 | const { props } = ( 77 | 78 | 79 | <> 80 | 81 | 82 | 83 | 84 | 85 | ); 86 | 87 | const canvas = new Canvas(props); 88 | await delay(100); 89 | await canvas.render(); 90 | await delay(1000); 91 | 92 | expect(context).toMatchImageSnapshot(); 93 | }); 94 | 95 | it('tranformRef 嵌套', async () => { 96 | const context = createContext(); 97 | const ref = {}; 98 | const { props } = ( 99 | 100 | 101 | 102 | 103 | 104 | 105 | ); 106 | 107 | const canvas = new Canvas(props); 108 | await delay(100); 109 | await canvas.render(); 110 | await delay(1000); 111 | 112 | expect(context).toMatchImageSnapshot(); 113 | }); 114 | }); 115 | -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/morph.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component, Timeline, Fragment } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | 4 | class Group extends Component { 5 | render() { 6 | return ( 7 | 8 | 23 | 24 | 39 | 40 | ); 41 | } 42 | } 43 | 44 | class Circle extends Component { 45 | render() { 46 | return ( 47 | 61 | ); 62 | } 63 | } 64 | 65 | describe('形变动画', () => { 66 | it('group 到 circle', async () => { 67 | const context = createContext(); 68 | const { props } = ( 69 | 70 | 71 | 72 | 73 | 74 | 75 | ); 76 | 77 | const canvas = new Canvas(props); 78 | await delay(100); 79 | await canvas.render(); 80 | await delay(1000); 81 | 82 | expect(context).toMatchImageSnapshot(); 83 | }); 84 | 85 | it('circle 到 group', async () => { 86 | const context = createContext(); 87 | const { props } = ( 88 | 89 | 90 | 91 | 92 | 93 | 94 | ); 95 | 96 | const canvas = new Canvas(props); 97 | await delay(100); 98 | await canvas.render(); 99 | await delay(1000); 100 | 101 | expect(context).toMatchImageSnapshot(); 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /packages/f-engine/test/timeline/playerRefFunc.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component, Player, Timeline } from '../../src'; 2 | import { createContext, delay } from '../util'; 3 | 4 | describe('player', () => { 5 | class View extends Component { 6 | render() { 7 | const { 8 | width = '80px', 9 | height = '80px', 10 | opacity = 1, 11 | fill = 'red', 12 | visible = false, 13 | } = this.props; 14 | if (!visible) return; 15 | return ( 16 | 39 | ); 40 | } 41 | } 42 | 43 | it('goTo等于总时长时', async () => { 44 | const context = createContext('跳转至某时间'); 45 | const ref = { current: null }; 46 | const { props } = ( 47 | 48 | 75 | 76 | 77 | 78 | 79 | 80 | ); 81 | 82 | const canvas = new Canvas(props); 83 | await canvas.render(); 84 | await delay(10); 85 | 86 | ref.current.goTo(2000); 87 | await delay(200); 88 | expect(context).toMatchImageSnapshot(); 89 | }); 90 | }); 91 | -------------------------------------------------------------------------------- /packages/f-engine/test/types.test.tsx: -------------------------------------------------------------------------------- 1 | import { jsx, Canvas, Component, createRef } from '../src'; 2 | import { createContext } from './util'; 3 | 4 | const context = createContext(); 5 | 6 | interface TestProps { 7 | fill?: string; 8 | } 9 | 10 | class Test extends Component { 11 | render() { 12 | return null; 13 | } 14 | } 15 | 16 | describe('types', () => { 17 | it('key & ref', () => { 18 | const ref = createRef(); 19 | const { props } = ( 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/f-engine/test/util.ts: -------------------------------------------------------------------------------- 1 | export * from '@antv/f-test-utils'; 2 | -------------------------------------------------------------------------------- /packages/f-engine/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/f-engine/typings.d.ts: -------------------------------------------------------------------------------- 1 | import '../../typings'; 2 | -------------------------------------------------------------------------------- /packages/f-lottie/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | .DS_Store 64 | 65 | # npmignore - content above this line is automatically generated and modifications may be omitted 66 | # see npmjs.com/npmignore for more details. 67 | test 68 | 69 | *.sw* 70 | *.un~ 71 | .idea 72 | bin 73 | demos 74 | docs 75 | temp 76 | webpack-dev.config.js 77 | webpack.config.js 78 | examples 79 | site 80 | gatsby-browser.js 81 | gatsby-config.js 82 | .cache 83 | public 84 | -------------------------------------------------------------------------------- /packages/f-lottie/LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /packages/f-lottie/README.md: -------------------------------------------------------------------------------- 1 | FEngine 的 [Lottie](https://airbnb.design/lottie/) 播放组件 2 | 3 | See our GitHub [https://github.com/antvis/FEngine](https://github.com/antvis/FEngine) for more information 4 | 5 | ## Install 6 | 7 | Using npm: 8 | 9 | ```sh 10 | npm install --save @antv/f-lottie 11 | ``` 12 | 13 | or using yarn: 14 | 15 | ```sh 16 | yarn add @antv/f-lottie 17 | ``` 18 | 19 | ## License 20 | 21 | [MIT license](./LICENSE). 22 | -------------------------------------------------------------------------------- /packages/f-lottie/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antv/f-lottie", 3 | "version": "1.5.0", 4 | "description": "FEngine for Lottie", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "types": "es/index.d.ts", 8 | "keywords": [ 9 | "antv", 10 | "f2", 11 | "chart", 12 | "charts", 13 | "mobile", 14 | "visualization", 15 | "lottie" 16 | ], 17 | "dependencies": { 18 | "@antv/f-engine": "1.5.0", 19 | "@antv/g-lottie-player": "~0.2.0", 20 | "@babel/runtime": "^7.12.5", 21 | "tslib": "^2.3.1" 22 | }, 23 | "devDependencies": { 24 | "@antv/f-test-utils": "1.0.9" 25 | }, 26 | "homepage": "https://f2.antv.vision", 27 | "author": "https://github.com/orgs/antvis/people", 28 | "license": "MIT", 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/antvis/f2" 32 | }, 33 | "bugs": { 34 | "url": "https://github.com/antvis/f2/issues" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/f-lottie/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { Component, createRef, jsx, Ref, AnimationProps } from '@antv/f-engine'; 2 | import { loadAnimation } from '@antv/g-lottie-player'; 3 | 4 | interface LottieProps { 5 | // Lottie Json 6 | data: any; 7 | options?: { 8 | // 是否循环播放 次数 | 无限 9 | loop?: number | boolean; 10 | // 是否自动播放 11 | autoplay?: boolean; 12 | }; 13 | style?: { 14 | width?: number; 15 | height?: number; 16 | x?: number; 17 | y?: number; 18 | }; 19 | play?: { 20 | speed?: number; 21 | // 开始帧 22 | start?: number; 23 | // 结束帧 24 | end?: number; 25 | }; 26 | animation?: AnimationProps; 27 | } 28 | 29 | class Lottie extends Component { 30 | size: { width: number; height: number }; 31 | ref: Ref; 32 | animation: any; 33 | 34 | constructor(props) { 35 | super(props); 36 | this.ref = createRef(); 37 | } 38 | 39 | didMount() { 40 | this.addLottie(); 41 | } 42 | 43 | willUpdate() { 44 | this.addLottie(); 45 | } 46 | 47 | addLottie = () => { 48 | const { props, context } = this; 49 | const { data, options, play } = props; 50 | const { canvas } = context; 51 | 52 | if (!data) return; 53 | 54 | // 文档流后挂载lottie 55 | canvas.ready.then(() => { 56 | this.animation = this.animation ? this.animation : loadAnimation(data, options); 57 | this.animation.render(this.ref.current); 58 | 59 | this.size = this.animation.size(); 60 | this.updateSize(); 61 | 62 | // 播放控制 63 | if (play) { 64 | const { speed = 1, start = 0, end = this.animation.getDuration(true) } = play; 65 | this.animation.setSpeed(speed); 66 | this.animation.playSegments([start, end]); 67 | } 68 | }); 69 | }; 70 | 71 | updateSize = () => { 72 | const { width: currentWidth, height: currentHeight } = this.size; 73 | const { style } = this.props; 74 | if (!style) return; 75 | 76 | const { width = currentWidth, height = currentHeight } = style; 77 | 78 | this.ref.current.scale(width / currentWidth, height / currentHeight); 79 | this.size = { 80 | width, 81 | height, 82 | }; 83 | }; 84 | 85 | render() { 86 | const { style, animation } = this.props; 87 | return ; 88 | } 89 | } 90 | 91 | export default Lottie; 92 | -------------------------------------------------------------------------------- /packages/f-lottie/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/f-lottie/typings.d.ts: -------------------------------------------------------------------------------- 1 | import '../../typings'; 2 | -------------------------------------------------------------------------------- /packages/f-my/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['../../.eslintrc.js'], 3 | globals: { 4 | my: 'readonly', 5 | App: 'readonly', 6 | Page: 'readonly', 7 | Component: 'readonly', 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /packages/f-my/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | .DS_Store 64 | 65 | # npmignore - content above this line is automatically generated and modifications may be omitted 66 | # see npmjs.com/npmignore for more details. 67 | test 68 | 69 | *.sw* 70 | *.un~ 71 | .idea 72 | bin 73 | demos 74 | docs 75 | temp 76 | webpack-dev.config.js 77 | webpack.config.js 78 | examples 79 | site 80 | gatsby-browser.js 81 | gatsby-config.js 82 | .cache 83 | public 84 | -------------------------------------------------------------------------------- /packages/f-my/LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /packages/f-my/README.md: -------------------------------------------------------------------------------- 1 | 支付宝小程序组件 2 | 3 | See our GitHub [https://github.com/antvis/FEngine](https://github.com/antvis/FEngine) for more information 4 | 5 | ## Install 6 | 7 | Using npm: 8 | 9 | ```sh 10 | npm install --save @antv/f-my 11 | ``` 12 | 13 | or using yarn: 14 | 15 | ```sh 16 | yarn add @antv/f-my 17 | ``` 18 | 19 | ## 使用方式 20 | 21 | 使用方式请参考 [F2 官网](https://f2.antv.vision) 文档: [https://f2.antv.vision/zh/docs/tutorial/miniprogram](https://f2.antv.vision/zh/docs/tutorial/miniprogram) 22 | 23 | ## License 24 | 25 | [MIT license](./LICENSE). 26 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/.mini-ide/project-ide.json: -------------------------------------------------------------------------------- 1 | { 2 | "enableLegacyRemoteDebug": false 3 | } -------------------------------------------------------------------------------- /packages/f-my/examples/test/app.acss: -------------------------------------------------------------------------------- 1 | page { 2 | background: #f7f7f7; 3 | } 4 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/app.js: -------------------------------------------------------------------------------- 1 | App({ 2 | onLaunch(_options) { 3 | // 第一次打开 4 | // options.query == {number:1} 5 | console.info('App onLaunch'); 6 | }, 7 | onShow(_options) { 8 | // 从后台被 scheme 重新打开 9 | // options.query == {number:1} 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index" 4 | ], 5 | "window": { 6 | "defaultTitle": "My App" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | [ 4 | "@babel/plugin-transform-react-jsx", 5 | { 6 | "runtime": "automatic", 7 | "importSource": "@antv/f-engine" 8 | } 9 | ] 10 | ] 11 | } -------------------------------------------------------------------------------- /packages/f-my/examples/test/mini.project.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": 2, 3 | "compileOptions": { 4 | "component2": true, 5 | "enableNodeModuleBabelTransform": true 6 | }, 7 | "scripts": { 8 | "beforeCompile": "npm run beforeCompile" 9 | } 10 | } -------------------------------------------------------------------------------- /packages/f-my/examples/test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "beforeCompile": "babel pages --out-dir pages --only **/*.jsx" 4 | }, 5 | "dependencies": { 6 | "@antv/f-engine": "*", 7 | "@antv/f-my": "*", 8 | "@babel/cli": "^7.16.0", 9 | "@babel/core": "^7.16.0", 10 | "@babel/plugin-transform-react-jsx": "^7.16.0" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/pages/index/index.acss: -------------------------------------------------------------------------------- 1 | /* required by usingComponents */ 2 | .container { 3 | width: 100%; 4 | height: 600rpx; 5 | } 6 | 7 | .web-container { 8 | width: 350rpx; 9 | height: 480rpx; 10 | } 11 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/pages/index/index.axml: -------------------------------------------------------------------------------- 1 | 2 | native 3 | 4 | web 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/pages/index/index.js: -------------------------------------------------------------------------------- 1 | import Rect from './rect'; 2 | import { jsx as _jsx } from "@antv/f-engine/jsx-runtime"; 3 | Page({ 4 | data: { 5 | data: {} 6 | }, 7 | onReady() { 8 | this.setData({ 9 | data: { 10 | index: 1, 11 | width: 100 12 | } 13 | }); 14 | // 模拟数据更新 15 | setTimeout(() => { 16 | this.setData({ 17 | data: { 18 | index: 2, 19 | width: 200 20 | } 21 | }); 22 | }, 2000); 23 | }, 24 | onRenderChart(props) { 25 | const { 26 | data 27 | } = props; 28 | return _jsx(Rect, { 29 | ...data 30 | }); 31 | 32 | // 如果不使用 jsx, 用下面代码效果也是一样的 33 | // return createElement(Chart, { 34 | // data: data, 35 | // }); 36 | } 37 | }); -------------------------------------------------------------------------------- /packages/f-my/examples/test/pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": { 3 | "f-canvas": "@antv/f-my", 4 | "f-canvas-web": "@antv/f-my/lib/web" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/pages/index/index.jsx: -------------------------------------------------------------------------------- 1 | import Rect from './rect'; 2 | 3 | Page({ 4 | data: { 5 | data: {}, 6 | }, 7 | onReady() { 8 | this.setData({ 9 | data: { 10 | index: 1, 11 | width: 100, 12 | }, 13 | }); 14 | // 模拟数据更新 15 | setTimeout(() => { 16 | this.setData({ 17 | data: { 18 | index: 2, 19 | width: 200, 20 | }, 21 | }); 22 | }, 2000); 23 | }, 24 | onRenderChart(props) { 25 | const { data } = props; 26 | 27 | return ; 28 | 29 | // 如果不使用 jsx, 用下面代码效果也是一样的 30 | // return createElement(Chart, { 31 | // data: data, 32 | // }); 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/pages/index/rect.js: -------------------------------------------------------------------------------- 1 | import { Component } from '@antv/f-engine'; 2 | import { jsx as _jsx, jsxs as _jsxs } from "@antv/f-engine/jsx-runtime"; 3 | class Rect extends Component { 4 | render() { 5 | const { 6 | index, 7 | width = 0 8 | } = this.props; 9 | return _jsxs("group", { 10 | style: { 11 | display: 'flex' 12 | }, 13 | children: [_jsx("text", { 14 | style: { 15 | text: `${index}`, 16 | fill: '#000', 17 | fontSize: '30px' 18 | } 19 | }), _jsx("rect", { 20 | style: { 21 | fill: 'red', 22 | width, 23 | height: '40px' 24 | }, 25 | animation: { 26 | appear: { 27 | easing: 'linear', 28 | duration: 300, 29 | property: ['width'], 30 | start: { 31 | width: 0 32 | }, 33 | end: {} 34 | }, 35 | update: { 36 | easing: 'linear', 37 | duration: 300, 38 | property: ['width'] 39 | } 40 | }, 41 | onClick: e => { 42 | console.log('click', e); 43 | }, 44 | onTouchStart: e => { 45 | console.log('onTouchStart', e); 46 | }, 47 | onTouchMove: e => { 48 | console.log('onTouchMove', e); 49 | }, 50 | onTouchEnd: e => { 51 | console.log('onTouchEnd', e); 52 | } 53 | }), _jsx("image", { 54 | style: { 55 | width: 32, 56 | height: 32, 57 | src: 'https://f2.antv.antgroup.com/favicon-32x32.png' 58 | } 59 | })] 60 | }); 61 | } 62 | } 63 | export default Rect; -------------------------------------------------------------------------------- /packages/f-my/examples/test/pages/index/rect.jsx: -------------------------------------------------------------------------------- 1 | import { Component } from '@antv/f-engine'; 2 | 3 | class Rect extends Component { 4 | render() { 5 | const { index, width = 0 } = this.props; 6 | return ( 7 | 8 | 15 | { 38 | console.log('click', e); 39 | }} 40 | onTouchStart={(e) => { 41 | console.log('onTouchStart', e); 42 | }} 43 | onTouchMove={(e) => { 44 | console.log('onTouchMove', e); 45 | }} 46 | onTouchEnd={(e) => { 47 | console.log('onTouchEnd', e); 48 | }} 49 | /> 50 | 55 | 56 | ); 57 | } 58 | } 59 | 60 | export default Rect; 61 | -------------------------------------------------------------------------------- /packages/f-my/examples/test/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-my/examples/test/snapshot.png -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/.fatherrc.js: -------------------------------------------------------------------------------- 1 | export default { 2 | esm: { 3 | type: 'babel', 4 | }, 5 | runtimeHelpers: true, 6 | }; 7 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/.mini-ide/project-ide.json: -------------------------------------------------------------------------------- 1 | { 2 | "enableLegacyRemoteDebug": false 3 | } -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/app.acss: -------------------------------------------------------------------------------- 1 | page { 2 | background: #f7f7f7; 3 | } 4 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/app.js: -------------------------------------------------------------------------------- 1 | App({ 2 | onLaunch(_options) { 3 | // 第一次打开 4 | // options.query == {number:1} 5 | console.info('App onLaunch'); 6 | }, 7 | onShow(_options) { 8 | // 从后台被 scheme 重新打开 9 | // options.query == {number:1} 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "es/index/index" 4 | ], 5 | "window": { 6 | "defaultTitle": "My App" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/mini.project.json: -------------------------------------------------------------------------------- 1 | { 2 | "component2": true, 3 | "enableAppxNg": true 4 | } 5 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "build": "father build" 4 | }, 5 | "dependencies": { 6 | "@antv/f-engine": "*", 7 | "@antv/f-my": "*", 8 | "@babel/cli": "^7.16.0", 9 | "@babel/core": "^7.16.0", 10 | "@babel/plugin-transform-react-jsx": "^7.16.0", 11 | "@babel/runtime": "^7.12.5" 12 | }, 13 | "devDependencies": { 14 | "father": "^2.30.0", 15 | "mini-types": "^0.1.7", 16 | "typescript": "^4.5.4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-my/examples/typescript/snapshot.png -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/src/index/index.acss: -------------------------------------------------------------------------------- 1 | /* required by usingComponents */ 2 | .container { 3 | width: 100%; 4 | height: 600rpx; 5 | } 6 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/src/index/index.axml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/src/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": { 3 | "f-canvas": "@antv/f-my" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/src/index/index.tsx: -------------------------------------------------------------------------------- 1 | import Rect from './rect'; 2 | 3 | Page({ 4 | data: {}, 5 | onRenderChart() { 6 | return ; 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/src/index/rect.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from '@antv/f-engine'; 2 | 3 | class Rect extends Component { 4 | render() { 5 | const { index, width = 0 } = this.props; 6 | return ( 7 | 8 | 15 | { 38 | console.log('click', e); 39 | }} 40 | onTouchStart={(e) => { 41 | console.log('onTouchStart', e); 42 | }} 43 | onTouchMove={(e) => { 44 | console.log('onTouchMove', e); 45 | }} 46 | onTouchEnd={(e) => { 47 | console.log('onTouchEnd', e); 48 | }} 49 | /> 50 | 51 | ); 52 | } 53 | } 54 | 55 | export default Rect; 56 | -------------------------------------------------------------------------------- /packages/f-my/examples/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "jsx": "react-jsx", 5 | "jsxImportSource": "@antv/f-engine", 6 | "moduleResolution": "node", 7 | "types": ["mini-types"], 8 | "allowSyntheticDefaultImports": true 9 | }, 10 | "exclude": [ 11 | "node_modules" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /packages/f-my/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antv/f-my", 3 | "version": "1.7.0", 4 | "description": "FEngine for alipay mini-program", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "types": "es/index.d.ts", 8 | "keywords": [ 9 | "antv", 10 | "f2", 11 | "chart", 12 | "charts", 13 | "mobile", 14 | "visualization", 15 | "miniprogram", 16 | "my", 17 | "alipay" 18 | ], 19 | "dependencies": { 20 | "@antv/f-engine": "1.5.0", 21 | "@babel/runtime": "^7.12.5", 22 | "tslib": "^2.3.1" 23 | }, 24 | "devDependencies": { 25 | "mini-types": "^0.1.7" 26 | }, 27 | "homepage": "https://f2.antv.vision/zh/docs/tutorial/miniprogram", 28 | "author": "https://github.com/orgs/antvis/people", 29 | "license": "MIT", 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/antvis/f2" 33 | }, 34 | "bugs": { 35 | "url": "https://github.com/antvis/f2/issues" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/f-my/src/index.acss: -------------------------------------------------------------------------------- 1 | .f-canvas { 2 | width: 100%; 3 | height: 100%; 4 | } -------------------------------------------------------------------------------- /packages/f-my/src/index.axml: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /packages/f-my/src/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true 3 | } -------------------------------------------------------------------------------- /packages/f-my/src/web.acss: -------------------------------------------------------------------------------- 1 | .f-web-canvas { 2 | width: 100%; 3 | height: 100%; 4 | } -------------------------------------------------------------------------------- /packages/f-my/src/web.axml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/f-my/src/web.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true 3 | } -------------------------------------------------------------------------------- /packages/f-my/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "lib": ["es2015", "dom"], 5 | "types": ["mini-types"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/f-my/typings.d.ts: -------------------------------------------------------------------------------- 1 | import '../../typings'; 2 | -------------------------------------------------------------------------------- /packages/f-react/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | .DS_Store 64 | 65 | # npmignore - content above this line is automatically generated and modifications may be omitted 66 | # see npmjs.com/npmignore for more details. 67 | test 68 | 69 | *.sw* 70 | *.un~ 71 | .idea 72 | bin 73 | demos 74 | docs 75 | temp 76 | webpack-dev.config.js 77 | webpack.config.js 78 | examples 79 | site 80 | gatsby-browser.js 81 | gatsby-config.js 82 | .cache 83 | public 84 | -------------------------------------------------------------------------------- /packages/f-react/LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /packages/f-react/README.md: -------------------------------------------------------------------------------- 1 | FEngine React 组件 2 | 3 | See our GitHub [https://github.com/antvis/FEngine](https://github.com/antvis/FEngine) for more information 4 | 5 | ## Install 6 | 7 | Using npm: 8 | 9 | ```sh 10 | npm install --save @antv/f-react 11 | ``` 12 | 13 | or using yarn: 14 | 15 | ```sh 16 | yarn add @antv/f-react 17 | ``` 18 | 19 | ## 使用方式 20 | 21 | 使用方式请参考 [F2 官网](https://f2.antv.vision) 文档: [https://f2.antv.vision/zh/docs/tutorial/react](https://f2.antv.vision/zh/docs/tutorial/react) 22 | 23 | ## License 24 | 25 | [MIT license](./LICENSE). 26 | -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.14.1", 7 | "@testing-library/react": "^13.0.0", 8 | "@testing-library/user-event": "^13.2.1", 9 | "@antv/f-engine": "*", 10 | "@antv/f-react": "*", 11 | "react": "^18.2.0", 12 | "react-dom": "^18.2.0", 13 | "react-scripts": "5.0.1", 14 | "web-vitals": "^2.1.0" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "browserslist": { 23 | "production": [ 24 | ">0.2%", 25 | "not dead", 26 | "not op_mini all" 27 | ], 28 | "development": [ 29 | "last 1 chrome version", 30 | "last 1 firefox version", 31 | "last 1 safari version" 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-react/examples/my-app/public/favicon.ico -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |

32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-react/examples/my-app/public/logo192.png -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/packages/f-react/examples/my-app/public/logo512.png -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/src/App.js: -------------------------------------------------------------------------------- 1 | import Canvas from '@antv/f-react'; 2 | import { Component, Timeline } from '@antv/f-engine'; 3 | 4 | class Rect extends Component { 5 | render() { 6 | const { index, width = 0 } = this.props; 7 | return ( 8 | 9 | 34 | 43 | 44 | ); 45 | } 46 | } 47 | 48 | function App() { 49 | return ( 50 |
51 | 52 | 53 | {[10, 100].map((v, index) => { 54 | return ; 55 | })} 56 | 57 | 58 |
59 | ); 60 | } 61 | 62 | export default App; 63 | -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './App'; 4 | 5 | const root = ReactDOM.createRoot(document.getElementById('root')); 6 | root.render( 7 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /packages/f-react/examples/my-app/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /packages/f-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antv/f-react", 3 | "version": "1.5.0", 4 | "description": "FEngine for React", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "types": "es/index.d.ts", 8 | "sideEffects": false, 9 | "keywords": [ 10 | "antv", 11 | "f2", 12 | "chart", 13 | "charts", 14 | "mobile", 15 | "visualization", 16 | "react" 17 | ], 18 | "dependencies": { 19 | "@antv/f-engine": "1.5.0", 20 | "@babel/runtime": "^7.12.5", 21 | "tslib": "^2.3.1" 22 | }, 23 | "devDependencies": { 24 | "@types/react": "^16.9.35", 25 | "@types/react-dom": "^16.9.8", 26 | "enzyme": "^3.11.0", 27 | "enzyme-adapter-react-16": "^1.15.6", 28 | "react": "16.8.6", 29 | "react-dom": "16.8.6" 30 | }, 31 | "peerDependencies": { 32 | "react": ">=16.8.6", 33 | "react-dom": ">=16.8.6" 34 | }, 35 | "homepage": "https://f2.antv.vision/zh/docs/tutorial/react", 36 | "author": "https://github.com/orgs/antvis/people", 37 | "license": "MIT", 38 | "repository": { 39 | "type": "git", 40 | "url": "https://github.com/antvis/f2" 41 | }, 42 | "bugs": { 43 | "url": "https://github.com/antvis/f2/issues" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/f-react/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { Canvas } from '@antv/f-engine'; 2 | import { createCanvas, CanvasProps } from './createCanvas'; 3 | 4 | export { createCanvas, CanvasProps }; 5 | // 通过工厂模式创建时为了让 f2-react 依赖 f2 的 canvas 而不是 f-engine 6 | export default createCanvas(Canvas); 7 | -------------------------------------------------------------------------------- /packages/f-react/test/index.test.tsx: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | /* @jsx React.createElement */ 3 | import { Canvas, Component } from '@antv/f-engine'; 4 | import Enzyme, { mount } from 'enzyme'; 5 | import Adapter from 'enzyme-adapter-react-16'; 6 | import React from 'react'; 7 | import ReactCanvas from '../src'; 8 | 9 | // @ts-ignore 10 | Enzyme.configure({ adapter: new Adapter() }); 11 | 12 | function delay(time) { 13 | return new Promise((resolve) => { 14 | setTimeout(resolve, time); 15 | }); 16 | } 17 | 18 | function App(props: any) { 19 | const { canvasRef } = props; 20 | return ( 21 | 22 | 28 | 29 | ); 30 | } 31 | 32 | describe('', () => { 33 | it('render', () => { 34 | const canvasRef = React.createRef(); 35 | 36 | const wrapper = mount(); 37 | expect(wrapper.html()).toBe( 38 | '' 39 | ); 40 | 41 | const reactCanvas = canvasRef.current; 42 | // 断言实例生成和ref正确性 43 | expect(reactCanvas.canvas).toBeInstanceOf(Canvas); 44 | 45 | wrapper.unmount(); 46 | }); 47 | 48 | it('Canvas render with Error', async () => { 49 | const spyOnError = jest.spyOn(window, 'onerror').mockImplementation(() => {}); 50 | const spyOnConsoleError = jest.spyOn(console, 'error').mockImplementation(() => {}); 51 | class Test extends Component { 52 | render() { 53 | throw new Error('Render Error'); 54 | } 55 | } 56 | 57 | const onError = jest.fn(); 58 | 59 | const wrapper = mount( 60 | Chart Fallback} onError={onError}> 61 | 62 | 63 | ); 64 | 65 | await delay(500); 66 | wrapper.update(); 67 | // 断言 fallback 触发 68 | expect(wrapper.html()).toBe('
Chart Fallback
'); 69 | 70 | // 断言 onError 触发 71 | expect(onError.mock.calls.length).toBe(1); 72 | expect(spyOnError).toHaveBeenCalled(); 73 | 74 | spyOnError.mockRestore(); 75 | spyOnConsoleError.mockRestore(); 76 | 77 | wrapper.unmount(); 78 | }); 79 | }); 80 | -------------------------------------------------------------------------------- /packages/f-react/test/react.test.tsx: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | /* @jsx React.createElement */ 3 | import React from 'react'; 4 | import ReactDOM from 'react-dom'; 5 | import ReactCanvas from '../src'; 6 | 7 | const container = document.createElement('div'); 8 | document.body.appendChild(container); 9 | 10 | const App = () => { 11 | return ( 12 | 13 | 28 | 29 | ); 30 | }; 31 | 32 | ReactDOM.render(, container); 33 | 34 | describe('', () => { 35 | it('Canvas', () => { 36 | expect(true).toBe(true); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/f-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react", 5 | "jsxFactory": "React.createElement", 6 | "jsxFragmentFactory": "React.Fragment" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/f-react/typings.d.ts: -------------------------------------------------------------------------------- 1 | import '../../typings'; 2 | -------------------------------------------------------------------------------- /packages/f-test-utils/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | .DS_Store 64 | 65 | # npmignore - content above this line is automatically generated and modifications may be omitted 66 | # see npmjs.com/npmignore for more details. 67 | test 68 | 69 | *.sw* 70 | *.un~ 71 | .idea 72 | bin 73 | demos 74 | docs 75 | temp 76 | webpack-dev.config.js 77 | webpack.config.js 78 | examples 79 | site 80 | gatsby-browser.js 81 | gatsby-config.js 82 | .cache 83 | public 84 | -------------------------------------------------------------------------------- /packages/f-test-utils/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## 1.0.9 (2023-09-11) 7 | 8 | **Note:** Version bump only for package @antv/f-test-utils 9 | 10 | 11 | 12 | 13 | 14 | ## 1.0.8 (2023-09-10) 15 | 16 | **Note:** Version bump only for package @antv/f-test-utils 17 | 18 | 19 | 20 | 21 | 22 | ## 1.0.5 (2023-08-29) 23 | 24 | **Note:** Version bump only for package @antv/f-test-utils 25 | 26 | 27 | 28 | 29 | 30 | ## 1.0.4 (2023-08-25) 31 | 32 | **Note:** Version bump only for package @antv/f-test-utils 33 | 34 | 35 | 36 | 37 | 38 | ## 1.0.3 (2023-07-18) 39 | 40 | **Note:** Version bump only for package @antv/f-test-utils 41 | 42 | 43 | 44 | 45 | 46 | ## 1.0.2 (2023-07-18) 47 | 48 | **Note:** Version bump only for package @antv/f-test-utils 49 | 50 | 51 | 52 | 53 | 54 | ## 1.0.1 (2023-06-27) 55 | 56 | **Note:** Version bump only for package @antv/f-test-utils 57 | -------------------------------------------------------------------------------- /packages/f-test-utils/LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /packages/f-test-utils/README.md: -------------------------------------------------------------------------------- 1 | F 系列单测的 util 方法 2 | -------------------------------------------------------------------------------- /packages/f-test-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antv/f-test-utils", 3 | "version": "1.0.9", 4 | "description": "FEngine for Test", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "types": "es/index.d.ts", 8 | "keywords": [ 9 | "antv", 10 | "f2", 11 | "chart", 12 | "charts", 13 | "mobile", 14 | "visualization", 15 | "lottie" 16 | ], 17 | "dependencies": { 18 | "@babel/runtime": "^7.12.5", 19 | "tslib": "^2.3.1" 20 | }, 21 | "homepage": "https://f2.antv.vision", 22 | "author": "https://github.com/orgs/antvis/people", 23 | "license": "MIT", 24 | "repository": { 25 | "type": "git", 26 | "url": "https://github.com/antvis/f2" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/antvis/f2/issues" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/f-test-utils/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/f-test-utils/typings.d.ts: -------------------------------------------------------------------------------- 1 | import '../../typings'; 2 | -------------------------------------------------------------------------------- /packages/f-vue/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | .DS_Store 64 | 65 | # npmignore - content above this line is automatically generated and modifications may be omitted 66 | # see npmjs.com/npmignore for more details. 67 | test 68 | 69 | *.sw* 70 | *.un~ 71 | .idea 72 | bin 73 | demos 74 | docs 75 | temp 76 | webpack-dev.config.js 77 | webpack.config.js 78 | examples 79 | site 80 | gatsby-browser.js 81 | gatsby-config.js 82 | .cache 83 | public 84 | -------------------------------------------------------------------------------- /packages/f-vue/LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /packages/f-vue/README.md: -------------------------------------------------------------------------------- 1 | FEngine 的 Vue.js 组件 2 | 3 | See our GitHub [https://github.com/antvis/FEngine](https://github.com/antvis/FEngine) for more information 4 | 5 | ## Install 6 | 7 | Using npm: 8 | 9 | ```sh 10 | npm install --save @antv/f-vue 11 | ``` 12 | 13 | or using yarn: 14 | 15 | ```sh 16 | yarn add @antv/f-vue 17 | ``` 18 | 19 | ## 使用方式 20 | 21 | 使用方式请参考 [F2 官网](https://f2.antv.vision) 文档: [https://f2.antv.vision/zh/docs/tutorial/vue](https://f2.antv.vision/zh/docs/tutorial/vue) 22 | 23 | ## License 24 | 25 | [MIT license](./LICENSE). 26 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vite/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vite/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + Vite 2 | 3 | This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@antv/f-engine": "1.x", 12 | "@antv/f-vue": "1.x", 13 | "vue": "^3.2.25" 14 | }, 15 | "devDependencies": { 16 | "@babel/plugin-transform-react-jsx": "^7.17.3", 17 | "@rollup/plugin-babel": "^5.3.1", 18 | "@vitejs/plugin-vue": "^2.3.2", 19 | "@vitejs/plugin-vue-jsx": "^1.3.10", 20 | "vite": "^2.9.7" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vite/src/App.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 39 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vite/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import App from './App.vue'; 3 | 4 | createApp(App).mount('#app'); 5 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vite/src/rect.jsx: -------------------------------------------------------------------------------- 1 | import { Component } from '@antv/f-engine'; 2 | 3 | class Rect extends Component { 4 | render() { 5 | const { index, width = 0 } = this.props; 6 | return ( 7 | 8 | 15 | { 38 | console.log('click', e); 39 | }} 40 | onTouchStart={(e) => { 41 | console.log('onTouchStart', e); 42 | }} 43 | onTouchMove={(e) => { 44 | console.log('onTouchMove', e); 45 | }} 46 | onTouchEnd={(e) => { 47 | console.log('onTouchEnd', e); 48 | }} 49 | /> 50 | 51 | ); 52 | } 53 | } 54 | 55 | export default Rect; 56 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vite/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import vue from '@vitejs/plugin-vue'; 3 | import vueJsx from '@vitejs/plugin-vue-jsx'; 4 | import { babel } from '@rollup/plugin-babel'; 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | babel({ 10 | plugins: [ 11 | [ 12 | '@babel/plugin-transform-react-jsx', 13 | { 14 | runtime: 'automatic', 15 | importSource: '@antv/f-engine', 16 | }, 17 | ], 18 | ], 19 | }), 20 | vue(), 21 | vueJsx(), 22 | ], 23 | }); 24 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vue3/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@vue/cli-plugin-babel/preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vue3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-3", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "@antv/f-engine": "1.x", 12 | "@antv/f-vue": "1.x", 13 | "vue": "^3.2.25" 14 | }, 15 | "devDependencies": { 16 | "@babel/plugin-transform-react-jsx": "~7.17.3", 17 | "@vue/cli-plugin-babel": "~4.5.0", 18 | "@vue/cli-service": "~4.5.0", 19 | "@vue/compiler-sfc": "^3.0.0-0" 20 | }, 21 | "browserslist": [ 22 | "> 1%", 23 | "last 2 versions", 24 | "not dead" 25 | ], 26 | "keywords": [], 27 | "description": "" 28 | } 29 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vue3/src/App.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 41 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vue3/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import App from './App.vue'; 3 | 4 | createApp(App).mount('#app'); 5 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vue3/src/rect.jsx: -------------------------------------------------------------------------------- 1 | import { Component } from '@antv/f-engine'; 2 | 3 | class Rect extends Component { 4 | render() { 5 | const { index, width = 0 } = this.props; 6 | return ( 7 | 8 | 15 | { 38 | console.log('click', e); 39 | }} 40 | onTouchStart={(e) => { 41 | console.log('onTouchStart', e); 42 | }} 43 | onTouchMove={(e) => { 44 | console.log('onTouchMove', e); 45 | }} 46 | onTouchEnd={(e) => { 47 | console.log('onTouchEnd', e); 48 | }} 49 | /> 50 | 51 | ); 52 | } 53 | } 54 | 55 | export default Rect; 56 | -------------------------------------------------------------------------------- /packages/f-vue/examples/vue3/vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | chainWebpack: (config) => { 3 | config.module 4 | .rule('FEngine') 5 | .test((path) => { 6 | // Only transform FEngine JSX in .jsx files. 7 | return /\.jsx$/.test(path) && !/\.vue\.jsx$/.test(path); 8 | }) 9 | .use('babel') 10 | .loader('babel-loader') 11 | .options({ 12 | plugins: [ 13 | [ 14 | '@babel/plugin-transform-react-jsx', 15 | { 16 | runtime: 'automatic', 17 | importSource: '@antv/f-engine', 18 | }, 19 | ], 20 | ], 21 | }) 22 | .end(); 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /packages/f-vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antv/f-vue", 3 | "version": "1.5.0", 4 | "description": "FEngine for Vue.js", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "types": "es/index.d.ts", 8 | "sideEffects": false, 9 | "keywords": [ 10 | "antv", 11 | "f2", 12 | "chart", 13 | "charts", 14 | "mobile", 15 | "visualization", 16 | "vue" 17 | ], 18 | "dependencies": { 19 | "@antv/f-engine": "1.5.0", 20 | "@babel/runtime": "^7.12.5", 21 | "tslib": "^2.3.1" 22 | }, 23 | "devDependencies": { 24 | "@testing-library/vue": "~6.5.1", 25 | "vue": "~3.2.33" 26 | }, 27 | "peerDependencies": { 28 | "vue": ">=3.2.33" 29 | }, 30 | "homepage": "https://f2.antv.vision/zh/docs/tutorial/vue", 31 | "author": "https://github.com/orgs/antvis/people", 32 | "license": "MIT", 33 | "repository": { 34 | "type": "git", 35 | "url": "https://github.com/antvis/f2" 36 | }, 37 | "bugs": { 38 | "url": "https://github.com/antvis/f2/issues" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/f-vue/src/index.ts: -------------------------------------------------------------------------------- 1 | import { h, toRaw, isVNode } from 'vue'; 2 | import { Canvas, Children } from '@antv/f-engine'; 3 | 4 | const toRawChildren = (slots) => { 5 | return Children.map(slots, (slot) => { 6 | if (!slot) return slot; 7 | const element = toRaw(slot); 8 | 9 | // vnode 10 | if (isVNode(element)) { 11 | const { key, ref, type, props, children } = element; 12 | if (children) { 13 | props.children = toRawChildren(children); 14 | } 15 | return { 16 | key, 17 | ref, 18 | type, 19 | props, 20 | }; 21 | } 22 | 23 | // slot 24 | if (element.default) { 25 | const children = element.default(); 26 | return toRawChildren(children); 27 | } 28 | 29 | return null; 30 | }); 31 | }; 32 | 33 | export default { 34 | props: { 35 | className: { 36 | type: String, 37 | required: false, 38 | }, 39 | pixelRatio: { 40 | type: Number, 41 | default: 1, 42 | required: false, 43 | }, 44 | width: { 45 | type: [Number, String], 46 | required: false, 47 | }, 48 | height: { 49 | type: [Number, String], 50 | required: false, 51 | }, 52 | padding: { 53 | type: [Number, String, Array], 54 | required: false, 55 | }, 56 | animate: { 57 | type: [Boolean], 58 | default: true, 59 | required: false, 60 | }, 61 | px2hd: { 62 | type: [Function], 63 | required: false, 64 | }, 65 | }, 66 | methods: { 67 | getProps() { 68 | const { $props, $slots } = this; 69 | const props = toRaw($props); 70 | const canvasEl = this.$el; 71 | const context = canvasEl.getContext('2d'); 72 | return { 73 | ...props, 74 | // context 内部创建,不能被覆盖 75 | context, 76 | children: toRawChildren($slots), 77 | }; 78 | }, 79 | }, 80 | async mounted() { 81 | const props = this.getProps(); 82 | const canvas = new Canvas(props); 83 | await canvas.render(); 84 | this.canvas = canvas; 85 | }, 86 | async updated() { 87 | const props = this.getProps(); 88 | const { canvas } = this; 89 | await canvas.update(props); 90 | }, 91 | render() { 92 | return h('canvas', { 93 | className: `f-chart ${this.className || ''}`, 94 | style: { 95 | width: '100%', 96 | height: '100%', 97 | display: 'block', 98 | padding: 0, 99 | margin: 0, 100 | }, 101 | }); 102 | }, 103 | beforeUnmount() { 104 | const { canvas } = this; 105 | canvas.destroy(); 106 | }, 107 | }; 108 | -------------------------------------------------------------------------------- /packages/f-vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/f-vue/typings.d.ts: -------------------------------------------------------------------------------- 1 | import '../../typings'; 2 | -------------------------------------------------------------------------------- /packages/f-wx/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['../../.eslintrc.js'], 3 | globals: { 4 | wx: 'readonly', 5 | App: 'readonly', 6 | Page: 'readonly', 7 | Component: 'readonly', 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /packages/f-wx/.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # Yarn Integrity file 58 | .yarn-integrity 59 | 60 | # dotenv environment variables file 61 | .env 62 | 63 | .DS_Store 64 | 65 | # npmignore - content above this line is automatically generated and modifications may be omitted 66 | # see npmjs.com/npmignore for more details. 67 | test 68 | 69 | *.sw* 70 | *.un~ 71 | .idea 72 | bin 73 | demos 74 | docs 75 | temp 76 | webpack-dev.config.js 77 | webpack.config.js 78 | examples 79 | site 80 | gatsby-browser.js 81 | gatsby-config.js 82 | .cache 83 | public 84 | -------------------------------------------------------------------------------- /packages/f-wx/LICENSE: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2015-present Alipay.com, https://www.alipay.com/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /packages/f-wx/README.md: -------------------------------------------------------------------------------- 1 | FEngine 的微信小程序组件 2 | 3 | See our GitHub [https://github.com/antvis/FEngine](https://github.com/antvis/FEngine) for more information 4 | 5 | ## Install 6 | 7 | Using npm: 8 | 9 | ```sh 10 | npm install --save @antv/f-wx 11 | ``` 12 | 13 | or using yarn: 14 | 15 | ```sh 16 | yarn add @antv/f-wx 17 | ``` 18 | 19 | ## 使用方式 20 | 21 | 使用方式请参考 [F2 官网](https://f2.antv.vision) 文档: [https://f2.antv.vision/zh/docs/tutorial/miniprogram](https://f2.antv.vision/zh/docs/tutorial/miniprogram) 22 | 23 | ## License 24 | 25 | [MIT license](./LICENSE). 26 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/app.js: -------------------------------------------------------------------------------- 1 | // app.js 2 | App({ 3 | onLaunch() { 4 | // 展示本地存储能力 5 | const logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | 9 | // 登录 10 | wx.login({ 11 | success: () => { 12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId 13 | } 14 | }) 15 | }, 16 | globalData: { 17 | userInfo: null 18 | } 19 | }) 20 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/index/index" 4 | ], 5 | "window":{ 6 | "backgroundTextStyle":"light", 7 | "navigationBarBackgroundColor": "#fff", 8 | "navigationBarTitleText": "Weixin", 9 | "navigationBarTextStyle":"black" 10 | }, 11 | "style": "v2", 12 | "sitemapLocation": "sitemap.json" 13 | } 14 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | [ 4 | "@babel/plugin-transform-react-jsx", 5 | { 6 | "runtime": "automatic", 7 | "importSource": "@antv/f-engine" 8 | } 9 | ] 10 | ] 11 | } -------------------------------------------------------------------------------- /packages/f-wx/examples/test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "beforeCompile": "babel pages --out-dir pages --only **/*.jsx" 4 | }, 5 | "dependencies": { 6 | "@antv/f-engine": "*", 7 | "@antv/f-wx": "*" 8 | }, 9 | "devDependencies": { 10 | "@babel/cli": "^7.16.0", 11 | "@babel/core": "^7.16.0", 12 | "@babel/plugin-transform-react-jsx": "^7.16.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/pages/index/index.js: -------------------------------------------------------------------------------- 1 | import Rect from './rect'; 2 | import { jsx as _jsx } from "@antv/f-engine/jsx-runtime"; 3 | Page({ 4 | data: { 5 | onRenderCanvas: () => {} 6 | }, 7 | onReady() { 8 | this.setData({ 9 | onRenderCanvas: () => { 10 | return this.renderCanvas({ 11 | width: 100, 12 | index: 1 13 | }); 14 | } 15 | }); 16 | 17 | // 模拟数据更新 18 | setTimeout(() => { 19 | this.setData({ 20 | onRenderCanvas: () => { 21 | return this.renderCanvas({ 22 | width: 200, 23 | index: 2 24 | }); 25 | } 26 | }); 27 | }, 2000); 28 | }, 29 | renderCanvas({ 30 | width, 31 | index 32 | }) { 33 | return _jsx(Rect, { 34 | width: width, 35 | index: index 36 | }); 37 | // 如果不使用 jsx, 用下面代码效果也是一样的 38 | // return createElement(Chart, { 39 | // data: data, 40 | // }); 41 | } 42 | }); -------------------------------------------------------------------------------- /packages/f-wx/examples/test/pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": { 3 | "f-canvas": "@antv/f-wx" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/pages/index/index.jsx: -------------------------------------------------------------------------------- 1 | 2 | import Rect from './rect'; 3 | 4 | Page({ 5 | data: { 6 | onRenderCanvas: () => {}, 7 | }, 8 | onReady() { 9 | this.setData({ 10 | onRenderCanvas: () => { 11 | return this.renderCanvas({ width: 100, index: 1 }); 12 | }, 13 | }); 14 | 15 | // 模拟数据更新 16 | setTimeout(() => { 17 | this.setData({ 18 | onRenderCanvas: () => { 19 | return this.renderCanvas({ width: 200, index: 2 }); 20 | }, 21 | }); 22 | }, 2000); 23 | }, 24 | renderCanvas({ width, index }) { 25 | return ; 26 | // 如果不使用 jsx, 用下面代码效果也是一样的 27 | // return createElement(Chart, { 28 | // data: data, 29 | // }); 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /* required by usingComponents */ 2 | .container { 3 | width: 100%; 4 | height: 600rpx; 5 | } 6 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/pages/index/rect.js: -------------------------------------------------------------------------------- 1 | import { Component } from '@antv/f-engine'; 2 | import { jsx as _jsx } from "@antv/f-engine/jsx-runtime"; 3 | import { jsxs as _jsxs } from "@antv/f-engine/jsx-runtime"; 4 | class Rect extends Component { 5 | render() { 6 | const { 7 | index, 8 | width = 0 9 | } = this.props; 10 | return _jsxs("group", { 11 | style: { 12 | display: 'flex' 13 | }, 14 | children: [_jsx("text", { 15 | style: { 16 | text: `${index}`, 17 | fill: '#000', 18 | fontSize: '30px' 19 | } 20 | }), _jsx("rect", { 21 | style: { 22 | fill: 'red', 23 | width, 24 | height: '40px' 25 | }, 26 | animation: { 27 | appear: { 28 | easing: 'linear', 29 | duration: 300, 30 | property: ['width'], 31 | start: { 32 | width: 0 33 | }, 34 | end: {} 35 | }, 36 | update: { 37 | easing: 'linear', 38 | duration: 300, 39 | property: ['width'] 40 | } 41 | }, 42 | onClick: e => { 43 | console.log('click', e); 44 | }, 45 | onTouchStart: e => { 46 | console.log('onTouchStart', e); 47 | }, 48 | onTouchMove: e => { 49 | console.log('onTouchMove', e); 50 | }, 51 | onTouchEnd: e => { 52 | console.log('onTouchEnd', e); 53 | } 54 | }), _jsx("image", { 55 | style: { 56 | width: 32, 57 | height: 32, 58 | src: 'https://f2.antv.antgroup.com/favicon-32x32.png' 59 | } 60 | })] 61 | }); 62 | } 63 | } 64 | export default Rect; -------------------------------------------------------------------------------- /packages/f-wx/examples/test/pages/index/rect.jsx: -------------------------------------------------------------------------------- 1 | import { Component } from '@antv/f-engine'; 2 | 3 | class Rect extends Component { 4 | render() { 5 | const { index, width = 0 } = this.props; 6 | return ( 7 | 8 | 15 | { 38 | console.log('click', e); 39 | }} 40 | onTouchStart={(e) => { 41 | console.log('onTouchStart', e); 42 | }} 43 | onTouchMove={(e) => { 44 | console.log('onTouchMove', e); 45 | }} 46 | onTouchEnd={(e) => { 47 | console.log('onTouchEnd', e); 48 | }} 49 | /> 50 | 55 | 56 | ); 57 | } 58 | } 59 | 60 | export default Rect; 61 | -------------------------------------------------------------------------------- /packages/f-wx/examples/test/project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [ 5 | { 6 | "value": ".eslintrc.js", 7 | "type": "file" 8 | } 9 | ], 10 | "include": [] 11 | }, 12 | "setting": { 13 | "urlCheck": true, 14 | "es6": true, 15 | "enhance": true, 16 | "postcss": true, 17 | "preloadBackgroundData": false, 18 | "minified": true, 19 | "newFeature": false, 20 | "coverView": true, 21 | "nodeModules": true, 22 | "autoAudits": false, 23 | "showShadowRootInWxmlPanel": true, 24 | "scopeDataCheck": false, 25 | "uglifyFileName": false, 26 | "checkInvalidKey": true, 27 | "checkSiteMap": true, 28 | "uploadWithSourceMap": true, 29 | "compileHotReLoad": false, 30 | "lazyloadPlaceholderEnable": false, 31 | "useMultiFrameRuntime": true, 32 | "useApiHook": true, 33 | "useApiHostProcess": true, 34 | "babelSetting": { 35 | "ignore": [], 36 | "disablePlugins": [], 37 | "outputPath": "" 38 | }, 39 | "useIsolateContext": false, 40 | "userConfirmedBundleSwitch": false, 41 | "packNpmManually": false, 42 | "packNpmRelationList": [], 43 | "minifyWXSS": true, 44 | "disableUseStrict": false, 45 | "minifyWXML": true, 46 | "showES6CompileOption": false, 47 | "useCompilerPlugins": false, 48 | "ignoreUploadUnusedFiles": true 49 | }, 50 | "compileType": "miniprogram", 51 | "libVersion": "2.19.4", 52 | "appid": "wxb472d05b2693b44a", 53 | "projectname": "test", 54 | "condition": {}, 55 | "editorSetting": { 56 | "tabIndent": "insertSpaces", 57 | "tabSize": 4 58 | } 59 | } -------------------------------------------------------------------------------- /packages/f-wx/examples/test/sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", 3 | "rules": [{ 4 | "action": "allow", 5 | "page": "*" 6 | }] 7 | } -------------------------------------------------------------------------------- /packages/f-wx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@antv/f-wx", 3 | "version": "1.6.0", 4 | "description": "FEngine for weixin mini-program", 5 | "main": "lib/index.js", 6 | "module": "es/index.js", 7 | "types": "es/index.d.ts", 8 | "miniprogram": "es", 9 | "keywords": [ 10 | "antv", 11 | "f2", 12 | "chart", 13 | "charts", 14 | "mobile", 15 | "visualization", 16 | "miniprogram", 17 | "wx", 18 | "weixin" 19 | ], 20 | "dependencies": { 21 | "@antv/f-engine": "1.5.0", 22 | "@babel/runtime": "^7.12.5", 23 | "tslib": "^2.3.1" 24 | }, 25 | "devDependencies": { 26 | "miniprogram-api-typings": "^3.4.4" 27 | }, 28 | "homepage": "https://f2.antv.vision/zh/docs/tutorial/miniprogram", 29 | "author": "https://github.com/orgs/antvis/people", 30 | "license": "MIT", 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/antvis/f2" 34 | }, 35 | "bugs": { 36 | "url": "https://github.com/antvis/f2/issues" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/f-wx/src/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /packages/f-wx/src/index.wxml: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /packages/f-wx/src/index.wxss: -------------------------------------------------------------------------------- 1 | .f-canvas { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | -------------------------------------------------------------------------------- /packages/f-wx/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["miniprogram-api-typings"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/f-wx/typings.d.ts: -------------------------------------------------------------------------------- 1 | import '../../typings'; 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "esModuleInterop": true, 5 | "target": "es5", 6 | "importHelpers": true, 7 | "declaration": true, 8 | "jsx": "react", 9 | "jsxFactory": "jsx", 10 | "jsxFragmentFactory": "Fragment", 11 | "moduleResolution": "node", 12 | "useDefineForClassFields": false, 13 | "resolveJsonModule": true, 14 | "skipLibCheck": true 15 | }, 16 | "exclude": [ 17 | "scripts", 18 | "node_modules" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /typings.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antvis/FEngine/7cac015af8512cb60fad8dc2f0906466ad295013/typings.d.ts --------------------------------------------------------------------------------