From d811c2cb3f58f71fc6f2a3ed5a2a41d87a6ae61e Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 17:41:56 +0800 Subject: [PATCH 01/69] update hooks --- .editorconfig | 17 +- .eslintrc.js | 19 + .fatherrc.js | 10 + .github/workflows/main.yml | 113 +++ .gitignore | 28 +- .jshintignore | 1 - .jshintrc | 10 - .npmignore | 29 + .prettierignore | 7 + .travis.yml | 37 - .umirc.ts | 15 + README.md | 214 +----- assets/index.less | 8 +- docs/changeLog.md | 52 ++ docs/demo/animParam.md | 8 + docs/demo/attr.md | 8 + docs/demo/blurFilter.md | 10 + docs/demo/component.md | 8 + docs/demo/control.md | 8 + docs/demo/easingPath.md | 10 + docs/demo/followMouse.md | 8 + docs/demo/group.md | 151 ++++ docs/demo/plugin:number-dance.md | 8 + docs/demo/plugin:path-motion.md | 8 + docs/demo/plugin:svg-draw.md | 8 + docs/demo/plugin:svg-morph.md | 8 + docs/demo/scrollAnim.md | 8 + docs/demo/simple.md | 8 + docs/demo/type.md | 8 + docs/examples/animParam.tsx | 133 ++++ docs/examples/attr.tsx | 23 + docs/examples/blurFilter.tsx | 24 + docs/examples/component.tsx | 94 +++ docs/examples/control.tsx | 70 ++ .../examples/easingPath.tsx | 30 +- docs/examples/followMouse.tsx | 18 + docs/examples/group.tsx | 34 + .../examples/numberDance.tsx | 37 +- docs/examples/pathMotion.tsx | 58 ++ .../examples/scrollAnim.tsx | 23 +- docs/examples/simple.tsx | 17 + docs/examples/svg.tsx | 41 + docs/examples/svgDraw.tsx | 89 +++ docs/examples/type.tsx | 64 ++ docs/index.md | 225 ++++++ eslintrc.js | 39 - examples/bezier.html | 1 - examples/bezier.js | 49 -- examples/blur.html | 1 - examples/blur.js | 24 - examples/children.html | 1 - examples/childrenNullChange.html | 1 - examples/childrenNullChange.js | 38 - examples/childrenUpdate.html | 1 - examples/childrenUpdate.js | 42 -- examples/color.html | 1 - examples/color.js | 18 - examples/control.html | 1 - examples/control.js | 89 --- examples/delay.html | 1 - examples/delay.js | 14 - examples/easingPath.html | 1 - examples/followMouse.html | 1 - examples/followMouse.js | 34 - examples/from.html | 1 - examples/from.js | 19 - examples/fromDelay.html | 1 - examples/fromDelay.js | 20 - examples/group.html | 1 - examples/group.js | 96 --- examples/groupAbsolute.html | 1 - examples/groupAbsolute.js | 39 - examples/groupInStrict.html | 1 - examples/groupInStrict.js | 42 -- examples/gsapWritten.html | 1 - examples/gsapWritten.js | 15 - examples/momentJump.html | 1 - examples/momentJump.js | 35 - examples/path.html | 1 - examples/path.js | 48 -- examples/repeat.html | 1 - examples/repeat.js | 21 - examples/scrollAnim.html | 1 - examples/scrollAnimChildrenUpdateStyle.html | 1 - examples/scrollAnimChildrenUpdateStyle.js | 29 - examples/shadow.html | 1 - examples/shadow.js | 18 - examples/shadowInset.html | 1 - examples/shadowInset.js | 15 - examples/simple.html | 1 - examples/simple.js | 21 - examples/svg.html | 1 - examples/svg.js | 26 - examples/svgDraw.html | 1 - examples/svgDraw.js | 47 -- examples/svgDrawShape.html | 1 - examples/svgDrawShape.js | 72 -- examples/svgPoints.html | 1 - examples/svgPoints.js | 23 - examples/timeline.html | 1 - examples/timeline.js | 36 - examples/timelineRepeat.html | 1 - examples/timelineRepeat.js | 45 -- examples/translate3d.html | 1 - examples/translate3d.js | 20 - examples/update.html | 1 - examples/update.js | 73 -- examples/updateStyle.html | 1 - examples/updateStyle.js | 27 - examples/yoyo.html | 1 - examples/yoyo.js | 19 - import.d.ts | 13 + index.d.ts | 24 + index.js | 1 + now.json | 11 + package.json | 105 ++- src/Tween.js | 487 ------------ src/TweenOne.jsx | 363 --------- src/TweenOne.tsx | 144 ++++ src/TweenOneGroup.jsx | 276 ------- src/TweenOneGroup.tsx | 223 ++++++ src/easing.js | 29 - src/index.js | 25 - src/index.tsx | 12 + src/plugin/BezierPlugin.jsx | 531 ------------- src/plugin/ChildrenPlugin.jsx | 61 -- src/plugin/ChildrenPlugin.ts | 85 +++ src/plugin/PathMotionPlugin.ts | 3 + src/plugin/PathPlugin.jsx | 53 -- src/plugin/StylePlugin.jsx | 318 -------- src/plugin/SvgDrawPlugin.jsx | 112 --- src/plugin/SvgDrawPlugin.ts | 3 + src/plugin/SvgMorphPlugin.jsx | 68 -- src/plugin/SvgMorphPlugin.ts | 3 + src/plugin/snapsvglite.js | 483 ------------ src/plugins.jsx | 8 - src/ticker.js | 116 --- src/type.ts | 68 ++ src/util.js | 289 -------- src/utils/group.ts | 98 +++ src/utils/index.ts | 72 ++ tests/index.js | 5 - tests/index.tsx | 44 -- tests/tweenOne.spec.jsx | 700 ------------------ tests/tweenOne.test.jsx | 504 +++++++++++++ tests/tweenOneGroup.spec.jsx | 124 ---- tests/tweenOneGroup.test.jsx | 102 +++ tsconfig.json | 41 +- tslint.json | 11 - typings/AnimObject.d.ts | 130 ---- typings/Tween.d.ts | 10 - typings/TweenOneGroup.d.ts | 19 - typings/index.d.ts | 50 -- 153 files changed, 2918 insertions(+), 5900 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .fatherrc.js create mode 100644 .github/workflows/main.yml delete mode 100644 .jshintignore delete mode 100644 .jshintrc create mode 100644 .npmignore create mode 100644 .prettierignore delete mode 100644 .travis.yml create mode 100644 .umirc.ts create mode 100644 docs/changeLog.md create mode 100644 docs/demo/animParam.md create mode 100644 docs/demo/attr.md create mode 100644 docs/demo/blurFilter.md create mode 100644 docs/demo/component.md create mode 100644 docs/demo/control.md create mode 100644 docs/demo/easingPath.md create mode 100644 docs/demo/followMouse.md create mode 100644 docs/demo/group.md create mode 100644 docs/demo/plugin:number-dance.md create mode 100644 docs/demo/plugin:path-motion.md create mode 100644 docs/demo/plugin:svg-draw.md create mode 100644 docs/demo/plugin:svg-morph.md create mode 100644 docs/demo/scrollAnim.md create mode 100644 docs/demo/simple.md create mode 100644 docs/demo/type.md create mode 100644 docs/examples/animParam.tsx create mode 100644 docs/examples/attr.tsx create mode 100644 docs/examples/blurFilter.tsx create mode 100644 docs/examples/component.tsx create mode 100644 docs/examples/control.tsx rename examples/easingPath.js => docs/examples/easingPath.tsx (64%) create mode 100644 docs/examples/followMouse.tsx create mode 100644 docs/examples/group.tsx rename examples/children.js => docs/examples/numberDance.tsx (63%) create mode 100644 docs/examples/pathMotion.tsx rename examples/scrollAnim.js => docs/examples/scrollAnim.tsx (61%) create mode 100644 docs/examples/simple.tsx create mode 100644 docs/examples/svg.tsx create mode 100644 docs/examples/svgDraw.tsx create mode 100644 docs/examples/type.tsx create mode 100644 docs/index.md delete mode 100644 eslintrc.js delete mode 100644 examples/bezier.html delete mode 100644 examples/bezier.js delete mode 100644 examples/blur.html delete mode 100644 examples/blur.js delete mode 100644 examples/children.html delete mode 100644 examples/childrenNullChange.html delete mode 100644 examples/childrenNullChange.js delete mode 100644 examples/childrenUpdate.html delete mode 100644 examples/childrenUpdate.js delete mode 100644 examples/color.html delete mode 100644 examples/color.js delete mode 100644 examples/control.html delete mode 100644 examples/control.js delete mode 100644 examples/delay.html delete mode 100644 examples/delay.js delete mode 100644 examples/easingPath.html delete mode 100644 examples/followMouse.html delete mode 100644 examples/followMouse.js delete mode 100644 examples/from.html delete mode 100644 examples/from.js delete mode 100644 examples/fromDelay.html delete mode 100644 examples/fromDelay.js delete mode 100644 examples/group.html delete mode 100644 examples/group.js delete mode 100644 examples/groupAbsolute.html delete mode 100644 examples/groupAbsolute.js delete mode 100644 examples/groupInStrict.html delete mode 100644 examples/groupInStrict.js delete mode 100644 examples/gsapWritten.html delete mode 100644 examples/gsapWritten.js delete mode 100644 examples/momentJump.html delete mode 100644 examples/momentJump.js delete mode 100644 examples/path.html delete mode 100644 examples/path.js delete mode 100644 examples/repeat.html delete mode 100644 examples/repeat.js delete mode 100644 examples/scrollAnim.html delete mode 100644 examples/scrollAnimChildrenUpdateStyle.html delete mode 100644 examples/scrollAnimChildrenUpdateStyle.js delete mode 100644 examples/shadow.html delete mode 100644 examples/shadow.js delete mode 100644 examples/shadowInset.html delete mode 100644 examples/shadowInset.js delete mode 100644 examples/simple.html delete mode 100644 examples/simple.js delete mode 100644 examples/svg.html delete mode 100644 examples/svg.js delete mode 100644 examples/svgDraw.html delete mode 100644 examples/svgDraw.js delete mode 100644 examples/svgDrawShape.html delete mode 100644 examples/svgDrawShape.js delete mode 100644 examples/svgPoints.html delete mode 100644 examples/svgPoints.js delete mode 100644 examples/timeline.html delete mode 100644 examples/timeline.js delete mode 100644 examples/timelineRepeat.html delete mode 100644 examples/timelineRepeat.js delete mode 100644 examples/translate3d.html delete mode 100644 examples/translate3d.js delete mode 100644 examples/update.html delete mode 100644 examples/update.js delete mode 100644 examples/updateStyle.html delete mode 100644 examples/updateStyle.js delete mode 100644 examples/yoyo.html delete mode 100644 examples/yoyo.js create mode 100644 import.d.ts create mode 100644 index.d.ts create mode 100644 index.js create mode 100644 now.json delete mode 100644 src/Tween.js delete mode 100644 src/TweenOne.jsx create mode 100644 src/TweenOne.tsx delete mode 100644 src/TweenOneGroup.jsx create mode 100644 src/TweenOneGroup.tsx delete mode 100644 src/easing.js delete mode 100644 src/index.js create mode 100644 src/index.tsx delete mode 100644 src/plugin/BezierPlugin.jsx delete mode 100644 src/plugin/ChildrenPlugin.jsx create mode 100644 src/plugin/ChildrenPlugin.ts create mode 100644 src/plugin/PathMotionPlugin.ts delete mode 100644 src/plugin/PathPlugin.jsx delete mode 100644 src/plugin/StylePlugin.jsx delete mode 100644 src/plugin/SvgDrawPlugin.jsx create mode 100644 src/plugin/SvgDrawPlugin.ts delete mode 100644 src/plugin/SvgMorphPlugin.jsx create mode 100644 src/plugin/SvgMorphPlugin.ts delete mode 100644 src/plugin/snapsvglite.js delete mode 100644 src/plugins.jsx delete mode 100644 src/ticker.js create mode 100644 src/type.ts delete mode 100644 src/util.js create mode 100644 src/utils/group.ts create mode 100644 src/utils/index.ts delete mode 100755 tests/index.js delete mode 100644 tests/index.tsx delete mode 100644 tests/tweenOne.spec.jsx create mode 100644 tests/tweenOne.test.jsx delete mode 100644 tests/tweenOneGroup.spec.jsx create mode 100644 tests/tweenOneGroup.test.jsx delete mode 100644 tslint.json delete mode 100644 typings/AnimObject.d.ts delete mode 100644 typings/Tween.d.ts delete mode 100644 typings/TweenOneGroup.d.ts delete mode 100644 typings/index.d.ts diff --git a/.editorconfig b/.editorconfig index 604c94ef..3331d704 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,16 @@ -# top-most EditorConfig file +# http://editorconfig.org root = true -# Unix-style newlines with a newline ending every file -[*.{js,css}] -end_of_line = lf -insert_final_newline = true +[*] indent_style = space indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..ff35abf2 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,19 @@ +const base = require('@umijs/fabric/dist/eslint'); + +module.exports = { + ...base, + rules: { + ...base.rules, + 'import/no-extraneous-dependencies': 0, + 'import/no-named-as-default': 0, + 'no-template-curly-in-string': 0, + 'prefer-promise-reject-errors': 0, + 'react/no-array-index-key': 0, + 'react/require-default-props': 0, + 'react/sort-comp': 0, + 'react/no-find-dom-node': 1, + '@typescript-eslint/no-explicit-any': 0, + 'jsx-a11y/label-has-associated-control': 0, + 'jsx-a11y/label-has-for': 0, + }, +}; \ No newline at end of file diff --git a/.fatherrc.js b/.fatherrc.js new file mode 100644 index 00000000..e062744f --- /dev/null +++ b/.fatherrc.js @@ -0,0 +1,10 @@ + +export default { + cjs: 'babel', + esm: { type: 'babel', importLibToEs: true }, + runtimeHelpers: true, + preCommit: { + eslint: true, + prettier: true, + }, +}; \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..5e426ee2 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,113 @@ +name: CI + +on: + push: + branches: [master, 3.0] + pull_request: + branches: [master] + +jobs: + setup: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@master + + - uses: actions/setup-node@v1 + with: + node-version: '12' + + - name: cache package-lock.json + uses: actions/cache@v2 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: create package-lock.json + run: npm i --package-lock-only + + - name: hack for singe file + run: | + if [ ! -d "package-temp-dir" ]; then + mkdir package-temp-dir + fi + cp package-lock.json package-temp-dir + - name: cache node_modules + id: node_modules_cache_id + uses: actions/cache@v2 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: install + if: steps.node_modules_cache_id.outputs.cache-hit != 'true' + run: npm ci + + lint: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@master + + - name: restore cache from package-lock.json + uses: actions/cache@v2 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: restore cache from node_modules + uses: actions/cache@v2 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: lint + run: npm run lint + + needs: setup + + compile: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@master + + - name: restore cache from package-lock.json + uses: actions/cache@v2 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: restore cache from node_modules + uses: actions/cache@v2 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: compile + run: npm run compile + + needs: setup + + coverage: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@master + + - name: restore cache from package-lock.json + uses: actions/cache@v2 + with: + path: package-temp-dir + key: lock-${{ github.sha }} + + - name: restore cache from node_modules + uses: actions/cache@v2 + with: + path: node_modules + key: node_modules-${{ hashFiles('**/package-temp-dir/package-lock.json') }} + + - name: coverage + run: npm test -- --coverage && bash <(curl -s https://codecov.io/bash) + + needs: setup diff --git a/.gitignore b/.gitignore index b500ba82..cc16e2a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ +.storybook *.iml *.log -.idea +.idea/ .ipr .iws *~ @@ -12,16 +13,33 @@ Thumbs.db .project .*proj -.svn +.svn/ *.swp *.swo *.pyc *.pyo +.build node_modules .cache -*.css +dist +assets/**/*.css build lib +es coverage -dist -es \ No newline at end of file +yarn.lock +package-lock.json +.vscode +.doc +# production +/dist +/docs-dist + +# misc +.DS_Store +# umi +.umi +.umi-production +.umi-test +.env.local +src/.umi diff --git a/.jshintignore b/.jshintignore deleted file mode 100644 index 3c3629e6..00000000 --- a/.jshintignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 997b3f7d..00000000 --- a/.jshintrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "node": true, - - "curly": true, - "latedef": true, - "quotmark": true, - "undef": true, - "unused": true, - "trailing": true -} diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..8db6ebd6 --- /dev/null +++ b/.npmignore @@ -0,0 +1,29 @@ +build/ +*.cfg +nohup.out +*.iml +.idea/ +.ipr +.iws +*~ +~* +*.diff +*.log +*.patch +*.bak +.DS_Store +Thumbs.db +.project +.*proj +.svn/ +*.swp +out/ +.build +node_modules +.cache +examples +tests +src +/index.js +.* +assets/**/*.less \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..b785a086 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +**/*.svg +**/*.ejs +**/*.html +package.json +.umi +.umi-production +.umi-test \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6bcf409f..00000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: node_js - -sudo: false - -notifications: - email: - - 155259966@qq.com - -node_js: -- 8.1.0 - -before_install: -- | - if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.md$)|(^(docs|examples))/' - then - echo "Only docs were updated, stopping build process." - exit - fi - npm install npm@3.x -g - phantomjs --version -script: -- | - if [ "$TEST_TYPE" = test ]; then - npm test - else - npm run $TEST_TYPE - fi -env: - matrix: - - TEST_TYPE=lint - - TEST_TYPE=test - - TEST_TYPE=coverage - - -matrix: - allow_failures: - - env: "TEST_TYPE=saucelabs" \ No newline at end of file diff --git a/.umirc.ts b/.umirc.ts new file mode 100644 index 00000000..fe9937d3 --- /dev/null +++ b/.umirc.ts @@ -0,0 +1,15 @@ +// more config: https://d.umijs.org/config +import { defineConfig } from 'dumi'; +const path = require('path'); + +export default defineConfig({ + title: 'rc-tween-one', + favicon: + 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', + logo: + 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', + outputPath: '.doc', + alias: { + 'rc-tween-one/src': path.join(__dirname, 'src'), + }, +}); \ No newline at end of file diff --git a/README.md b/README.md index 0752b233..e8923303 100644 --- a/README.md +++ b/README.md @@ -1,213 +1 @@ -# rc-tween-one ---- - -React TweenOne Component - - -[![NPM version][npm-image]][npm-url] -[![build status][travis-image]][travis-url] -[![Test coverage][coveralls-image]][coveralls-url] -[![node version][node-image]][node-url] -[![npm download][download-image]][download-url] - -[npm-image]: http://img.shields.io/npm/v/rc-tween-one.svg?style=flat-square -[npm-url]: http://npmjs.org/package/rc-tween-one -[travis-image]: https://img.shields.io/travis/react-component/tween-one.svg?style=flat-square -[travis-url]: https://travis-ci.org/react-component/tween-one -[coveralls-image]: https://img.shields.io/coveralls/react-component/tween-one.svg?style=flat-square -[coveralls-url]: https://coveralls.io/r/react-component/tween-one?branch=master -[node-image]: https://img.shields.io/badge/node.js-%3E=_0.10-green.svg?style=flat-square -[node-url]: http://nodejs.org/download/ -[download-image]: https://img.shields.io/npm/dm/rc-tween-one.svg?style=flat-square -[download-url]: https://npmjs.org/package/rc-tween-one - - -## Browser Support - -|![IE](https://github.com/alrra/browser-logos/blob/master/src/edge/edge_48x48.png?raw=true) | ![Chrome](https://github.com/alrra/browser-logos/blob/master/src/chrome/chrome_48x48.png?raw=true) | ![Firefox](https://github.com/alrra/browser-logos/blob/master/src/firefox/firefox_48x48.png?raw=true) | ![Opera](https://github.com/alrra/browser-logos/blob/master/src/opera/opera_48x48.png?raw=true) | ![Safari](https://github.com/alrra/browser-logos/blob/master/src/safari/safari_48x48.png?raw=true)| -| --- | --- | --- | --- | --- | -| IE 10+ ✔ | Chrome 31.0+ ✔ | Firefox 31.0+ ✔ | Opera 30.0+ ✔ | Safari 7.0+ ✔ | - -## Development - -``` -npm install -npm start -``` - -## Example - -http://localhost:8100/examples/ - -http://react-component.github.io/tween-one/ - - -## install - - -[![rc-tween-one](https://nodei.co/npm/rc-tween-one.png)](https://npmjs.org/package/rc-tween-one) - - -## Usage - -```jsx -var TweenOne = require('rc-tween-one'); -var React = require('react'); -React.render( - demo -, container); -``` - -### Plugin - -```jsx -var TweenOne = require('rc-tween-one'); -var React = require('react'); -var SvgDrawPlugin = require('rc-tween-one/lib/plugin/SvgDrawPlugin'); -TweenOne.plugins.push(SvgDrawPlugin); -React.render( - -, container); -``` - -### TweenOneGroup -```jsx -var TweenOne = require('rc-tween-one'); -var React = require('react'); -var TweenOneGroup = TweenOne.TweenOneGroup; -React.render( -
demo
-
demo
-
, container); -``` - -## API - -中文文档 - -### props - -> 2.5.x add currentRef, ` { c.currentRef === }} />` - -| name | type | default | description | -|------------|----------------|---------|----------------| -| animation | object / array | null | animate configure parameters | -| paused | boolean | false | animate pause | -| reverse | boolean | false | animate revers | -| reverseDelay | number | 0 | animate revers start delay | -| repeat | number | 0 | `animation` all data repeat, To repeat indefinitely, use -1 | -| yoyo | boolean | false | `animation` all data alternating backward and forward on each repeat. | -| onChange | func | null | when the animation change called, callback({ moment, target, index, mode, timelineMode }) | -| moment | number | null | set the current frame | -| attr | string | `style` | `style` or `attr`, `attr` is tag attribute. when morph SVG must be `attr`. | -| resetStyle | boolean | false | update animation data, reset init style | -| component | string / React.Element | `div` | component tag | -| componentProps | object | null | component is React.Element, component tag props, not add `style` | - - -### animation = { } - -> Basic animation param. please view [animation terms](https://motion.ant.design/language/animate-term) - -| name | type | default | description | -|------------|----------------|---------|----------------| -| type | string | `to` | play type: `to` `from`| -| duration | number | 450 | animate duration | -| delay | number | 0 | animate delay | -| repeat | number | 0 | animate repeat, To repeat indefinitely, use -1 | -| repeatDelay| number | 0 | repeat start delay | -| appearTo | number | null | Add to the specified time | -| yoyo | boolean | false | `true`: alternating backward and forward on each repeat. | -| ease | string / func | `easeInOutQuad` | animate ease. [refer](http://easings.net/en) | -| bezier | object | null | bezier curve animate | -| onStart | func | null | A function that should be called when the tween begins, callback(e), e: { index, target } | -| onUpdate | func | null | A function that should be called every time the animate updates, callback(e), e: { index, target, ratio } | -| onComplete | func | null | A function that should be called when the animate has completed, callback(e), e: { index, target } | -| onRepeat | func | null | A function that should be called each time the animate repeats, callback(e), e: { index, target } | - -> Cannot be used at the same time `reverse` and `repeat: -1`. - -### animation =[ ] is timeline - -### ease: function - -path easing; - -| name | type | default | description | -|------------|----------------|---------|----------------| -| path | string | null | svg path | -| param | object | `{ rect: 100, lengthPixel: 200 }` | rect is block size, default: 100 * 100; lengthPixel default: curve is divided into 200 sections | - -```js -const path = 'M0,100 C30,60 0,20 50,50 C70,70 60,0 100,0'; -const ease = Tween.easing.path(path, param = { rect: 100, lengthPixel: 200 }); -React.render( - demo -, container); -``` - -### BezierPlugin - -bezier = { } - -| name | type | default | description | -|------------|----------------|---------|----------------| -| type | string | `soft` | `thru`, `soft`, `quadratic`, `cubic` | -| autoRotate | boolean | false | to automatically rotate the target according to its position on the Bezier path | -| vars | array | null | bezier point data,as: `{x:100,y:100}` | - -> bezier API refer to [gsap BezierPlugin](http://greensock.com/docs/#/HTML5/GSAP/Plugins/BezierPlugin/) - -### SvgDrawPlugin - -SVGDraw = string or number; - -{ SVGDraw: 30 } or { SVGDraw: 'start end' } start and end values can be `%`; - -### SvgMorphPlugin - -svg polygon or path values: polygon is points, path is d; [demo](http://react-component.github.io/tween-one/examples/svg.html) - -### PathPlugin - -path = string or object; - -string: `animation={{ path: 'M0,100 C30,60 0,20 50,50 C70,70 60,0 100,0' }}`, default: x, y, rotate; - -object: `animation={{ path: { x: path, y: path, rotate: path } }}`, can be controlled from their own needs. - -### ChildrenPlugin - -#### Children = { value:, floatLength, formatMoney }; - -| name | type | default | description | -|---|---|---|---| -| value | number | null | children number to value. | -| floatLength | number | null | float precision length | -| formatMoney | boolean or { thousand, decimal } | false | format number to money. | - -#### formatMoney = { thousand, decimal } - -| name | type | default | description | -|---|---|---|---| -| thousand | string | `,` | no explanation. | -| decimal | string | `.` | no explanation. | - -## TweenOneGroup - -| name | type | default | description | -|------------|----------------|---------|----------------| -| appear | boolean | true | whether support appear anim | -| enter | object / array / func | `{ x: 30, opacity: 0, type: 'from' }` | enter anim twee-one data. when array is tween-one timeline, func refer to queue-anim | -| leave | object / array / func | `{ x: 30, opacity: 0 }` | leave anim twee-one data. when array is tween-one timeline, func refer to queue-anim | -| onEnd | func | - | one animation end callback | -| animatingClassName | array | `['tween-one-entering', 'tween-one-leaving']` | className to every element of animating | -| resetStyle | boolean | true | TweenOne resetStyle, reset the initial style when changing animation. | -| exclusive | boolean | false | Whether to allow a new animate to execute immediately when switching. `enter => leave`: execute immediately leave | -| component | React.Element/String | div | component tag | -| componentProps | object | - | component tag props | +docs/index.md \ No newline at end of file diff --git a/assets/index.less b/assets/index.less index 13c1788f..baa8c775 100644 --- a/assets/index.less +++ b/assets/index.less @@ -1,7 +1 @@ -@zero: 0; - -.tween-one-leaving{ - position: absolute; - top: 0; - left: 0; -} \ No newline at end of file +@zero: 0; \ No newline at end of file diff --git a/docs/changeLog.md b/docs/changeLog.md new file mode 100644 index 00000000..103e7e7d --- /dev/null +++ b/docs/changeLog.md @@ -0,0 +1,52 @@ +--- +title: changelog +order: 2 +--- + +# History + +--- + +## 3.0.0-beta.0 + +- hooks 重构 rc-tween-one; +- 拆离动画库与组件, 动画库 https://docs.antfin-inc.com/tween-one-js-update_1/ + +#### API 变更 + +- 删除 `currentRef`, hooks 如果 component 是组件,ref 返回为组件的 ref; +- 删除 `reverseDelay`; +- 增加 `repeatDelay`; +- `attr` 改为 `boolean` 类型; +- 更新 `onChange` 回调,cb: { moment, targets, index, mode, ratio, vars, index, repeat } +- 新增 `onChangeTimeline`, cb: { mode, targets, vars, moment, totalTime, repeat } +- 删除 `BezierPlugin`; +- `PathMotionPlugin` 更改用法,使用 `PathMotion: { path, center, x, y, rotate }`, 详细参考 pathMotion demo; +- `SvgMorph` 依赖更改为使用 `flubber`; +- 滤境使用,改成 `import { Plugins } from 'rc-tween-one'; Plugins.push()`, 保留 `TweenOne.plugins.push()`; +- 删除 `TweenOne.easing.path(path)` 使用,直接用 `ease: 'M0,0L100,100'`; + +--- + +## 2.2.0 + +1. resetStyleBool 改名成 resetStyle; +2. TweenOne 删除 updateReStart, 现在默认是。 +3. Group 重构动画逻辑,以队列形式切换,如果在动画时做切换,需将动画完成后再执切换动画。 +4. Group 增加 exclusive, 在队列动画时强行执行切换动画。 + +## 2.0.0 + +add repeat and yoyo to tag; + +## 1.8.0 + +add children plugin. + +## 0.4 + +1. filter 拆分为 'grayScale', 'sepia', 'hueRotate', 'invert', 'brightness', 'contrast', 'blur', 与 transform 一致; + +2. 忧化时间轴 + +3. 忧化 yoyo 在数组最后个卡顿的问题。 diff --git a/docs/demo/animParam.md b/docs/demo/animParam.md new file mode 100644 index 00000000..1e322ae9 --- /dev/null +++ b/docs/demo/animParam.md @@ -0,0 +1,8 @@ +--- +title: anim-params +order: 2 +--- + +## anim-params + + diff --git a/docs/demo/attr.md b/docs/demo/attr.md new file mode 100644 index 00000000..c928736b --- /dev/null +++ b/docs/demo/attr.md @@ -0,0 +1,8 @@ +--- +title: api:attr +order: 4 +--- + +## attr + + diff --git a/docs/demo/blurFilter.md b/docs/demo/blurFilter.md new file mode 100644 index 00000000..8a43f661 --- /dev/null +++ b/docs/demo/blurFilter.md @@ -0,0 +1,10 @@ +--- +title: filter +order: 3 +--- + +## css filter + +css filter animate + + diff --git a/docs/demo/component.md b/docs/demo/component.md new file mode 100644 index 00000000..6f7fdaf2 --- /dev/null +++ b/docs/demo/component.md @@ -0,0 +1,8 @@ +--- +title: api:component +order: 4 +--- + +## component + + diff --git a/docs/demo/control.md b/docs/demo/control.md new file mode 100644 index 00000000..fb823b72 --- /dev/null +++ b/docs/demo/control.md @@ -0,0 +1,8 @@ +--- +title: control +order: 1 +--- + +## control + + diff --git a/docs/demo/easingPath.md b/docs/demo/easingPath.md new file mode 100644 index 00000000..26e99ff1 --- /dev/null +++ b/docs/demo/easingPath.md @@ -0,0 +1,10 @@ +--- +title: api:easing-path +order: 4 +--- + +## easingPath + +ease path + + diff --git a/docs/demo/followMouse.md b/docs/demo/followMouse.md new file mode 100644 index 00000000..2633a693 --- /dev/null +++ b/docs/demo/followMouse.md @@ -0,0 +1,8 @@ +--- +title: follow-mouse +order: 5 +--- + +## follow mouse + + diff --git a/docs/demo/group.md b/docs/demo/group.md new file mode 100644 index 00000000..d79f3afc --- /dev/null +++ b/docs/demo/group.md @@ -0,0 +1,151 @@ +--- +title: TweenOneGroup +order: 8 +--- + +### appear = false + +```jsx +import TweenOneGroup from 'rc-tween-one/src/TweenOneGroup'; +import React from 'react'; +import { Button } from 'antd'; +import 'antd/dist/antd.css'; + +const imgArray = [ + 'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg', + 'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg', +]; +export default () => { + const [int, setInt] = React.useState(0); + return ( +
+ + +
+ img +
+
+
+ ); +}; +``` + +## basic + + + +### exclusive = true + +```jsx +import TweenOneGroup from 'rc-tween-one/src/TweenOneGroup'; +import React from 'react'; +import { Button } from 'antd'; +import 'antd/dist/antd.css'; + +const imgArray = [ + 'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg', + 'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg', +]; +export default () => { + const [int, setInt] = React.useState(0); + return ( +
+ + +
+ img +
+
+
+ ); +}; +``` + +### children change + +```jsx +import TweenOneGroup from 'rc-tween-one/src/TweenOneGroup'; +import React from 'react'; +import { Button } from 'antd'; +import 'antd/dist/antd.css'; + +const imgArray = [ + 'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg', + 'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg', +]; +export default () => { + const [children, setChildren] = React.useState( + [
+ img +
] + ) + return ( +
+ + + + {children} + +
+ ); +}; +``` + +出场交叉样式 + +```css +.demo-group.tween-one-leaving { + position: absolute; + top: 0; + left: 0; +} +```` + + diff --git a/docs/demo/plugin:number-dance.md b/docs/demo/plugin:number-dance.md new file mode 100644 index 00000000..9a9d4a66 --- /dev/null +++ b/docs/demo/plugin:number-dance.md @@ -0,0 +1,8 @@ +--- +title: plugin:number-dance +order: 7 +--- + +## number-dance + + diff --git a/docs/demo/plugin:path-motion.md b/docs/demo/plugin:path-motion.md new file mode 100644 index 00000000..7723a1fa --- /dev/null +++ b/docs/demo/plugin:path-motion.md @@ -0,0 +1,8 @@ +--- +title: plugin:path-motion +order: 7 +--- + +## path-motion + + diff --git a/docs/demo/plugin:svg-draw.md b/docs/demo/plugin:svg-draw.md new file mode 100644 index 00000000..6e43013b --- /dev/null +++ b/docs/demo/plugin:svg-draw.md @@ -0,0 +1,8 @@ +--- +title: plugin:svg-draw +order: 7 +--- + +## svg-draw + + diff --git a/docs/demo/plugin:svg-morph.md b/docs/demo/plugin:svg-morph.md new file mode 100644 index 00000000..410f1ec7 --- /dev/null +++ b/docs/demo/plugin:svg-morph.md @@ -0,0 +1,8 @@ +--- +title: plugin:svg-morph +order: 7 +--- + +## svg-morph + + diff --git a/docs/demo/scrollAnim.md b/docs/demo/scrollAnim.md new file mode 100644 index 00000000..3c96a899 --- /dev/null +++ b/docs/demo/scrollAnim.md @@ -0,0 +1,8 @@ +--- +title: in rc-scroll-anim +order: 6 +--- + +## in rc-scroll-anim + + diff --git a/docs/demo/simple.md b/docs/demo/simple.md new file mode 100644 index 00000000..983f4cb7 --- /dev/null +++ b/docs/demo/simple.md @@ -0,0 +1,8 @@ +--- +title: simple +order: 0 +--- + +## basic + + diff --git a/docs/demo/type.md b/docs/demo/type.md new file mode 100644 index 00000000..62e4f0f1 --- /dev/null +++ b/docs/demo/type.md @@ -0,0 +1,8 @@ +--- +title: api:type +order: 4 +--- + +## type use + + diff --git a/docs/examples/animParam.tsx b/docs/examples/animParam.tsx new file mode 100644 index 00000000..665baee7 --- /dev/null +++ b/docs/examples/animParam.tsx @@ -0,0 +1,133 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; +import { Form, InputNumber, Input, Button, Checkbox, Select, AutoComplete } from 'antd'; +import 'antd/dist/antd.css'; + +const { Option } = Select; + +const ValueComp = props => { + const { value, onChange } = props; + const [name, setName] = React.useState(value.name || 'x'); + const [param, setParam] = React.useState(parseFloat(value.value) || 300); + const [uint, setUint] = React.useState(value.uint || 'px'); + + const onNameChange = e => { + setName(e); + const v: any = { + name: e, + }; + switch (e) { + case 'x': + case 'y': + case 'margin': + case 'left': + setParam(300); + setUint('px'); + v.value = '300px'; + break; + case 'color': + v.value = '#fff000'; + setParam(v.value); + setUint(null); + break; + case 'textShadow': + v.value = '5px 5px 5px rgba(0,0,0,0.3)'; + setParam(v.value); + setUint(null); + break; + default: + break; + } + onChange(v); + }; + const onValueChange = e => { + setParam(e); + onChange({ ...value, value: e }); + }; + const onUintChange = e => { + setUint(e); + onChange({ ...value, uint: e }); + }; + return ( + + + + {uint && ( + + )} + + ); +}; + +export default () => { + const [anim, setAnim] = React.useState(); + const [paused, setPaused] = React.useState(true); + + const onFinish = values => { + console.log('Received values from form: ', values); + setPaused(false); + const { value, ...v } = values; + setAnim({ + [value.name]: `${value.value}${value.uint || ''}`, + ...v, + }); + }; + + return ( +
+ +
执行动效
+
+
+ + + + + + + + yoyo + + + + +
+
+ 注: +
+ 1. 更多动画参数请参考{' '} + + ant motion 动画参数 + +
+ 2. 动画值可以为 '+=300' 或 '-=300',表示当前值增加或减少。 +
+ 3. repeat 为 n + 1 次,如 2 则播放 3 次动画, -1 时为无限循环 +
+ 4. 参数不变,开始动画无效,请保证每次动画的参数 +
+
+ ); +}; diff --git a/docs/examples/attr.tsx b/docs/examples/attr.tsx new file mode 100644 index 00000000..a3a0d642 --- /dev/null +++ b/docs/examples/attr.tsx @@ -0,0 +1,23 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; + +export default () => { + return ( + + { + console.log(e.vars); + }} + attr + component="circle" + cx="300" + cy="55" + r="50" + style={{ fill: '#fff000', strokeWidth: 5, stroke: '#000fff' }} + > +
执行动效
+ + + ); +}; diff --git a/docs/examples/blurFilter.tsx b/docs/examples/blurFilter.tsx new file mode 100644 index 00000000..cbd6bb33 --- /dev/null +++ b/docs/examples/blurFilter.tsx @@ -0,0 +1,24 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; + +export default function Demo() { + return ( +
+

+ filter 里的滤镜,'grayScale', 'sepia', + 'hueRotate', 'invert', 'brightness', + 'contrast', 'blur' +

+ + img + +
+ ); +} diff --git a/docs/examples/component.tsx b/docs/examples/component.tsx new file mode 100644 index 00000000..7398556e --- /dev/null +++ b/docs/examples/component.tsx @@ -0,0 +1,94 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +import { Menu } from 'antd'; +import { + PieChartOutlined, + DesktopOutlined, + ContainerOutlined, + MailOutlined, +} from '@ant-design/icons'; +import 'antd/dist/antd.css'; + +const { SubMenu, Item } = Menu; + +const T = React.forwardRef((_, ref: any) =>
Function Component
); +class C extends React.Component { + render() { + return
Class Component
; + } +} + +const anim = { x: 300 }; + +export default () => { + const dom = React.useRef(); + + React.useEffect(() => { + console.log('useRef:', dom); + }); + + return ( +
+ { + // It can also be used React.useRef(); + console.log('function component HTMLElement:', c); + }} + component={T} + animation={anim} + /> + + { + // It can also be used React.useRef(); + console.log('class component:', c, ReactDOM.findDOMNode(c)); + }} + component={C} + animation={anim} + /> + + UseRef Component is string + +

ant design menu

+
+ + } + > + Option 1 + + }> + Option 2 + + }> + Option 3 + + } + title="Navigation One" + > + Option 5 + Option 6 + Option 7 + Option 8 + + +
+
+ ); +}; diff --git a/docs/examples/control.tsx b/docs/examples/control.tsx new file mode 100644 index 00000000..7d927d19 --- /dev/null +++ b/docs/examples/control.tsx @@ -0,0 +1,70 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; +import { Button, Space } from 'antd'; +import 'antd/dist/antd.css'; + +const animation = [{ translateX: '500px', duration: 1000 }, { y: 100 }]; +export default () => { + const [paused, setPaused] = React.useState(true); + const [reverse, setReverse] = React.useState(false); + const [moment, setMoment] = React.useState(0); + + return ( +
+
+ { console.log(e)}} + style={{ opacity: 1, width: 100, transform: 'translate(50px,30px)' }} + > +
执行动效
+
+
+ + + + + + + +
+ ); +}; diff --git a/examples/easingPath.js b/docs/examples/easingPath.tsx similarity index 64% rename from examples/easingPath.js rename to docs/examples/easingPath.tsx index 18413b48..53c2f75d 100644 --- a/examples/easingPath.js +++ b/docs/examples/easingPath.tsx @@ -1,11 +1,10 @@ import Tween from 'rc-tween-one'; import React from 'react'; -import ReactDom from 'react-dom'; const p1 = 'M0,100 L25,100 C34,20 40,0 100,0'; -const p = 'M0,100 C5,120 25,130 25,100 C30,60 40,75 58,90 C69,98.5 83,99.5 100,100'; -const t = Tween.easing.path(p); -const t1 = Tween.easing.path(p1); +const p = + 'M0,100 C5,120 25,130 25,100 C30,60 40,75 58,90 C69,98.5 83,99.5 100,100'; + const anim = [ { repeatDelay: 1000, @@ -14,7 +13,7 @@ const anim = [ scaleY: 2, repeat: -1, yoyo: true, - ease: t, + ease: p, }, { repeatDelay: 1000, @@ -23,12 +22,12 @@ const anim = [ appearTo: 0, repeat: -1, yoyo: true, - ease: t1, + ease: p1, }, ]; -function Demo() { +export default () => { return ( -
+
-
+
-
); -} -ReactDom.render(, document.getElementById('__react-content')); +
+ ); +}; diff --git a/docs/examples/followMouse.tsx b/docs/examples/followMouse.tsx new file mode 100644 index 00000000..6a7679b7 --- /dev/null +++ b/docs/examples/followMouse.tsx @@ -0,0 +1,18 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; + +export default () => { + const [animation, setAnim] = React.useState(); + const mouseMove = e => { + const x = e.clientX; + setAnim({ x, duration: 1000, ease: 'easeOutQuad' }); + }; + React.useEffect(() => { + window.addEventListener('mousemove', mouseMove); + }, []) + return ( + + 执行动效 + + ); +}; diff --git a/docs/examples/group.tsx b/docs/examples/group.tsx new file mode 100644 index 00000000..f11fe1ef --- /dev/null +++ b/docs/examples/group.tsx @@ -0,0 +1,34 @@ +import TweenOneGroup from 'rc-tween-one/src/TweenOneGroup'; +import React from 'react'; +import { Button } from 'antd'; +import 'antd/dist/antd.css'; +import '../../assets/index.less'; + +const imgArray = [ + 'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg', + 'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg', +]; +export default () => { + const [int, setInt] = React.useState(0); + return ( +
+ + +
+ img +
+
+
+ ); +}; diff --git a/examples/children.js b/docs/examples/numberDance.tsx similarity index 63% rename from examples/children.js rename to docs/examples/numberDance.tsx index 095dd79c..f3330e4f 100644 --- a/examples/children.js +++ b/docs/examples/numberDance.tsx @@ -1,47 +1,37 @@ import Tween from 'rc-tween-one'; import React from 'react'; -import ReactDom from 'react-dom'; -import ChildrenPlugin from '../src/plugin/ChildrenPlugin'; +import ChildrenPlugin from 'rc-tween-one/src/plugin/ChildrenPlugin'; -import '../assets/index.less'; Tween.plugins.push(ChildrenPlugin); -function Demo() { +export default function Demo() { return ( -
+

子级的数值变化的动画 - children plugin

基本数字: - +
设置开始数字: - - 9990 - + 9990
只取整数: - +
基本数字, 小数后取两位, float length 2: - +
格式化钱符:
¥ 20,000.12 @@ -62,11 +52,10 @@ function Demo() { }} component="span" > - 20.000,12 + 20.000,12
-
); +
+ ); } - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/docs/examples/pathMotion.tsx b/docs/examples/pathMotion.tsx new file mode 100644 index 00000000..5d38fed5 --- /dev/null +++ b/docs/examples/pathMotion.tsx @@ -0,0 +1,58 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; +import PathPlugin from 'rc-tween-one/src/plugin/PathMotionPlugin'; + +Tween.plugins.push(PathPlugin); + +export default function Demo() { + const p = `M50.952,85.619C31.729,84.841,23.557,73.62,24.095,42.952 + c0.381-21.714,6.667-33.714,30.286-34.476 + c36.572-1.18,59.81,77.714,102.667,76.381c30.108-0.937,34.268-32.381,34.095-41.714 + C190.762,22.571,180.493,6.786,159.524,6C113.81,4.286,98,87.524,50.952,85.619z`; + + const p2 = 'M0,0,L100, 0L100, 100L0, 100Z'; + return ( +
+
+ + a + + + a + + + + + +
+
+ ); +} diff --git a/examples/scrollAnim.js b/docs/examples/scrollAnim.tsx similarity index 61% rename from examples/scrollAnim.js rename to docs/examples/scrollAnim.tsx index 2a664f54..7041ea76 100644 --- a/examples/scrollAnim.js +++ b/docs/examples/scrollAnim.tsx @@ -1,19 +1,15 @@ import Tween from 'rc-tween-one'; import React from 'react'; -import ReactDom from 'react-dom'; import ScrollOverPack from 'rc-scroll-anim/lib/ScrollOverPack'; -function Demo() { +export default function Demo() { return (
往下滚动
- + 执行动画 @@ -21,14 +17,19 @@ function Demo() { 执行动画 -
); +
+ ); } - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/docs/examples/simple.tsx b/docs/examples/simple.tsx new file mode 100644 index 00000000..4ef7a616 --- /dev/null +++ b/docs/examples/simple.tsx @@ -0,0 +1,17 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; + +export default () => { + const bbb = (e: any) => { + console.log(e); // eslint-disable-line no-console + }; + return ( + +
执行动效
+
+ ); +}; diff --git a/docs/examples/svg.tsx b/docs/examples/svg.tsx new file mode 100644 index 00000000..e174b3d0 --- /dev/null +++ b/docs/examples/svg.tsx @@ -0,0 +1,41 @@ +import Tween, { Plugins } from 'rc-tween-one'; +import React from 'react'; +import SvgMorphPlugin from 'rc-tween-one/src/plugin/SvgMorphPlugin'; + +// Tween.plugins.push(SvgMorphPlugin); +Plugins.push(SvgMorphPlugin); + +export default function Demo() { + return ( +
+ + + + + + + + +
+ ); +} diff --git a/docs/examples/svgDraw.tsx b/docs/examples/svgDraw.tsx new file mode 100644 index 00000000..05d0cd7d --- /dev/null +++ b/docs/examples/svgDraw.tsx @@ -0,0 +1,89 @@ +import Tween, { Plugins } from 'rc-tween-one'; +import React from 'react'; +import SvgDrawPlugin from 'rc-tween-one/src/plugin/SvgDrawPlugin'; + +Plugins.push(SvgDrawPlugin); + +const dataStartArr = ['100%', '30 450', '50% 50%', '30% 400', '50 30%', 0]; +let i = 0; + +export default () => { + const [tweenData, setTweenData] = React.useState('50 30%'); + const onClick = () => { + setTweenData(dataStartArr[i]); + i++; + i = i >= dataStartArr.length ? 0 : i; + }; + return ( +
+ +

当前参数:{tweenData}

+ + + + + + + + + + +
+ ); +}; diff --git a/docs/examples/type.tsx b/docs/examples/type.tsx new file mode 100644 index 00000000..5d838c6d --- /dev/null +++ b/docs/examples/type.tsx @@ -0,0 +1,64 @@ +import Tween from 'rc-tween-one'; +import React from 'react'; +import { Button, Space } from 'antd'; +import 'antd/dist/antd.css'; + +export default () => { + const [anim, setAnim] = React.useState({ + x: 500, + duration: 1000, + }); + const [paused, setPaused] = React.useState(true); + + return ( +
+
+ { console.log(e)}} + style={{ opacity: 1, width: 100, transform: 'translate(50px,30px)' }} + > +
执行动效
+
+
+
播放类型(type):
+ + + + + +
+ ); +}; diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..a16ba9ef --- /dev/null +++ b/docs/index.md @@ -0,0 +1,225 @@ +--- +title: rc-tween-one +order: 0 +--- + +# rc-tween-one +--- + +React TweenOne Component + + +[![NPM version][npm-image]][npm-url] +[![build status][github-actions-image]][github-actions-url] +[![Codecov][codecov-image]][codecov-url] +[![node version][node-image]][node-url] +[![npm download][download-image]][download-url] + +[npm-image]: http://img.shields.io/npm/v/rc-tween-one.svg?style=flat-square +[npm-url]: http://npmjs.org/package/rc-tween-one +[github-actions-image]: https://github.com/react-component/tween-one/workflows/CI/badge.svg +[github-actions-url]: https://github.com/react-component/tween-one/actions +[codecov-image]: https://img.shields.io/codecov/c/github/react-component/tween-one/master.svg?style=flat-square +[codecov-url]: https://codecov.io/gh/react-component/tween-one/branch/master +[node-image]: https://img.shields.io/badge/node.js-%3E=_0.10-green.svg?style=flat-square +[node-url]: http://nodejs.org/download/ +[download-image]: https://img.shields.io/npm/dm/rc-tween-one.svg?style=flat-square +[download-url]: https://npmjs.org/package/rc-tween-one + + +## Browser Support + +|![IE](https://github.com/alrra/browser-logos/blob/master/src/edge/edge_48x48.png?raw=true) | ![Chrome](https://github.com/alrra/browser-logos/blob/master/src/chrome/chrome_48x48.png?raw=true) | ![Firefox](https://github.com/alrra/browser-logos/blob/master/src/firefox/firefox_48x48.png?raw=true) | ![Opera](https://github.com/alrra/browser-logos/blob/master/src/opera/opera_48x48.png?raw=true) | ![Safari](https://github.com/alrra/browser-logos/blob/master/src/safari/safari_48x48.png?raw=true)| +| --- | --- | --- | --- | --- | +| IE 10+ ✔ | Chrome 31.0+ ✔ | Firefox 31.0+ ✔ | Opera 30.0+ ✔ | Safari 7.0+ ✔ | + +## Development + +``` +npm install +npm start +``` + +## Example + +http://localhost:8100/examples/ + +http://react-component.github.io/tween-one/ + + +## install + + +[![rc-tween-one](https://nodei.co/npm/rc-tween-one.png)](https://npmjs.org/package/rc-tween-one) + + +## Usage + +```js | pure +var TweenOne = require('rc-tween-one'); +var React = require('react'); +React.render( + demo +, container); +``` + +### Plugin + +```js | pure +var TweenOne = require('rc-tween-one'); +var React = require('react'); +var SvgDrawPlugin = require('rc-tween-one/lib/plugin/SvgDrawPlugin'); +TweenOne.plugins.push(SvgDrawPlugin); +React.render( + +, container); +``` + +### TweenOneGroup +```js | pure +var TweenOne = require('rc-tween-one'); +var React = require('react'); +var TweenOneGroup = TweenOne.TweenOneGroup; +React.render( +
demo
+
demo
+
, container); +``` + +## API + +中文文档 + +### props + +| name | type | default | description | +|------------|----------------|---------|----------------| +| animation | object / array | null | animate configure parameters | +| paused | boolean | false | animate pause | +| reverse | boolean | false | animate revers | +| repeat | number | 0 | `animation` all data repeat, To repeat indefinitely, use -1 | +| repeatDelay | number | 0 | animate repeat delay | +| yoyo | boolean | false | `animation` all data alternating backward and forward on each repeat. | +| onChange | func | null | when the animation change called, callback({ moment, targets, index, mode, ratio, vars, index, repeat }) | +| onChangeTimeline | func | null | when the animation change called, callback({ mode, targets, vars, moment, totalTime, repeat }) | +| moment | number | null | set the current frame | +| attr | boolean | false | attribute animation is `true`, when morph SVG must be `true`. | +| resetStyle | boolean | false | update animation data, reset init style | +| component | string / React.Element | `div` | component tag | +| componentProps | object | null | component is React.Element, component tag props, not add `style` | + + +### animation = { } + +> Basic animation param. please view [animation terms](https://motion.ant.design/language/animate-term) + +| name | type | default | description | +|------------|----------------|---------|----------------| +| type | string | `to` | play type: `to` `from` `set`| +| duration | number | 450 | animate duration | +| delay | number | 0 | animate delay | +| repeat | number | 0 | animate repeat, To repeat indefinitely, use -1 | +| repeatDelay| number | 0 | repeat start delay | +| appearTo | number | null | Add to the specified time | +| yoyo | boolean | false | `true`: alternating backward and forward on each repeat. | +| ease | string | `easeInOutQuad` | animate ease [refer](http://easings.net/en) or svg path `M0,100 C30,60 0,20 50,50 C70,70 60,0 100,0` | +| bezier | object | null | bezier curve animate | +| onStart | func | null | A function that should be called when the tween begins, callback(e), e: { index, target } | +| onUpdate | func | null | A function that should be called every time the animate updates, callback(e), e: { index, target, ratio } | +| onComplete | func | null | A function that should be called when the animate has completed, callback(e), e: { index, target } | +| onRepeat | func | null | A function that should be called each time the animate repeats, callback(e), e: { index, target } | + +> Cannot be used at the same time `reverse` and `repeat: -1`. + +### animation =[ ] is timeline +```js | pure + +``` +## Plugins +### SvgDrawPlugin + +```js | pure +import { Plugins } from 'rc-tween-one'; +import SvgDrawPlugin from 'rc-tween-one/src/plugin/SvgDrawPlugin'; +Plugins.push(SvgDrawPlugin); + + +``` + +SVGDraw = string or number; + +{ SVGDraw: 30 } or { SVGDraw: 'start end' } start and end values can be `%`; + +### SvgMorphPlugin + +```js | pure +import { Plugins } from 'rc-tween-one'; +import SvgMorphPlugin from 'rc-tween-one/src/plugin/SvgMorphPlugin'; +Plugins.push(SvgMorphPlugin); + + +``` +#### SvgMorphPlugin API + +| name | type | default | description | +|------------------|--------|---------|----------------| +| path | string | null | svg path, ref: `M0,0L100,0`;| +| attr | string | null | Svg tag attributes, example: `polygon` is ` points`, `path` is `d`. | +| maxSegmentLength | number | 0.5 | 该值越小,生成的动画将越平滑,但会牺牲性能;| + + +### PathPlugin + +```js | pure +import { Plugins } from 'rc-tween-one'; +import PathMotionPlugin from 'rc-tween-one/src/plugin/PathMotionPlugin'; +Plugins.push(PathMotionPlugin); + + +``` +#### PathMotion API + +| name | type | default | description | +| ------ | ------------------- | --------------- | ----------------------------- | +| path | string | null | svg path, ref: `M0,0L100,0`; | +| center | `number \ string[]` | `['50%','50%']` | center point, ref: `[50px, 50px]`; | +| x | boolean | true | x follow the path. | +| y | boolean | true | y follow the path. | +| rotate | boolean | true | rotate follow the path. | + + +### ChildrenPlugin + +#### Children = { value:, floatLength, formatMoney }; + +| name | type | default | description | +|---|---|---|---| +| value | number | null | children number to value. | +| floatLength | number | null | float precision length | +| formatMoney | `true` \ { thousand, decimal } | null | format number to money. | + +#### formatMoney = { thousand, decimal } + +| name | type | default | description | +|---|---|---|---| +| thousand | string | `,` | no explanation. | +| decimal | string | `.` | no explanation. | + +## TweenOneGroup + +| name | type | default | description | +|------------|----------------|---------|----------------| +| appear | boolean | true | whether support appear anim | +| enter | object / array / func | `{ x: 30, opacity: 0, type: 'from' }` | enter anim twee-one data. when array is tween-one timeline, func refer to queue-anim | +| leave | object / array / func | `{ x: 30, opacity: 0 }` | leave anim twee-one data. when array is tween-one timeline, func refer to queue-anim | +| onEnd | func | - | one animation end callback | +| animatingClassName | array | `['tween-one-entering', 'tween-one-leaving']` | className to every element of animating | +| resetStyle | boolean | true | TweenOne resetStyle, reset the initial style when changing animation. | +| exclusive | boolean | false | Whether to allow a new animate to execute immediately when switching. `enter => leave`: execute immediately leave | +| component | React.Element/String | div | component tag | +| componentProps | object | - | component tag props | diff --git a/eslintrc.js b/eslintrc.js deleted file mode 100644 index 297edd9e..00000000 --- a/eslintrc.js +++ /dev/null @@ -1,39 +0,0 @@ -module.exports = { - extends: ['airbnb', 'prettier', 'prettier/react'], - parser: 'babel-eslint', - rules: { - strict: 0, - 'no-param-reassign': 0, - 'arrow-body-style': 0, - 'id-length': 0, - 'import/no-extraneous-dependencies': 0, - 'import/no-unresolved': 0, - 'import/extensions': 0, - 'no-underscore-dangle': 0, - 'react/jsx-filename-extension': 0, - 'react/require-default-props': 0, - 'react/forbid-prop-types': 0, - 'react/no-unused-prop-types': 0, - 'no-plusplus': 0, - 'no-bitwise': [2, { allow: ['~'] }], - 'jsx-a11y/no-static-element-interactions': 0, - 'jsx-a11y/anchor-has-content': 0, - 'jsx-a11y/click-events-have-key-events': 0, - 'jsx-a11y/anchor-is-valid': 0, - 'jsx-a11y/label-has-for': 0, - 'prefer-destructuring': 0, - 'no-class-assign': 0, - 'react/no-array-index-key': 0, - 'react/no-find-dom-node': 0, - }, - globals: { - expect: true, - document: true, - window: true, - }, - env: { - jest: true, - node: true, - mocha: true, - }, -}; diff --git a/examples/bezier.html b/examples/bezier.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/bezier.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/bezier.js b/examples/bezier.js deleted file mode 100644 index d5585a1c..00000000 --- a/examples/bezier.js +++ /dev/null @@ -1,49 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import BezierPlugin from '../src/plugin/BezierPlugin'; - -Tween.plugins.push(BezierPlugin); -function Demo() { - return ( -
- -
执行动效
-
-
-
-
-
-
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/blur.html b/examples/blur.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/blur.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/blur.js b/examples/blur.js deleted file mode 100644 index ccfcee94..00000000 --- a/examples/blur.js +++ /dev/null @@ -1,24 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( -
-
- filter 里的滤镜,'grayScale', 'sepia', 'hueRotate', - 'invert', 'brightness', 'contrast', 'blur' -
- - img - -
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/children.html b/examples/children.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/children.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/childrenNullChange.html b/examples/childrenNullChange.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/childrenNullChange.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/childrenNullChange.js b/examples/childrenNullChange.js deleted file mode 100644 index 80f5e0b9..00000000 --- a/examples/childrenNullChange.js +++ /dev/null @@ -1,38 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import PropTypes from 'prop-types'; -import '../assets/index.less'; - -function Div({ show, children }) { - return show ?
{children}
: null; -} - -Div.propTypes = { - show: PropTypes.bool, - children: PropTypes.any, -} - -class Demo extends React.Component { - state = { - show: false, - } - componentDidMount() { - setTimeout(() => { - this.setState({ - show: true, - }); - }, 1000); - } - render() { - return ( - - test - ); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/childrenUpdate.html b/examples/childrenUpdate.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/childrenUpdate.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/childrenUpdate.js b/examples/childrenUpdate.js deleted file mode 100644 index 1da70645..00000000 --- a/examples/childrenUpdate.js +++ /dev/null @@ -1,42 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - tweenData: { translateX: '100px', duration: 3000 }, - childTweenData: { translateY: 200, duration: 1000 }, - }; - } - - componentDidMount() { - setTimeout(() => { - this.setState({ - tweenData: { opacity: 0.5, marginTop: 100, duration: 1000 }, - }); - }, 1000); - setTimeout(() => { - this.setState({ - childTweenData: [ - { translateY: 100 }, - { rotateY: 180, duration: 1000 }, - { rotateY: 0, duration: 1000 }, - { delay: -800, translateY: 0 }, - ], - }); - }, 2000); - } - - render() { - return ( - -
大面包
- 小馒头 -
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/color.html b/examples/color.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/color.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/color.js b/examples/color.js deleted file mode 100644 index e695fab0..00000000 --- a/examples/color.js +++ /dev/null @@ -1,18 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( - -
执行动效
-
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/control.html b/examples/control.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/control.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/control.js b/examples/control.js deleted file mode 100644 index cd2c95b6..00000000 --- a/examples/control.js +++ /dev/null @@ -1,89 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - paused: true, - reverse: false, - reverseDelay: 0, - }; - } - - onPlay = () => { - this.setState({ - paused: false, - reverse: false, - moment: null, - }); - } - - onPause = () => { - this.setState({ - paused: true, - moment: null, - }); - } - - onReverse = () => { - this.setState({ - reverse: true, - reverseDelay: 0, - paused: false, - moment: null, - }); - } - - onReverseDelay = () => { - this.setState({ - reverse: true, - reverseDelay: 1000, - paused: false, - moment: null, - }); - } - - onRestart = () => { - this.setState({ - moment: 0, - paused: false, - reverse: false, - }); - } - - onMoment = () => { - this.setState({ - moment: 500, - }, () => { - this.setState({ - moment: null, - }); - }); - } - - render() { - return ( -
-
- -
执行动效
-
-
- - - - - - -
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/delay.html b/examples/delay.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/delay.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/delay.js b/examples/delay.js deleted file mode 100644 index 8f95ce4a..00000000 --- a/examples/delay.js +++ /dev/null @@ -1,14 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( - -
执行动效
-
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/easingPath.html b/examples/easingPath.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/easingPath.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/followMouse.html b/examples/followMouse.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/followMouse.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/followMouse.js b/examples/followMouse.js deleted file mode 100644 index 9b8deac4..00000000 --- a/examples/followMouse.js +++ /dev/null @@ -1,34 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - animation: {}, - }; - } - - componentDidMount() { - window.addEventListener('mousemove', this.mouseMove); - } - - mouseMove = (e) => { - const x = e.clientX; - this.setState({ - animation: { x, duration: 1000, ease: 'easeOutQuad' }, - }); - } - - render() { - return ( - -
执行动效
-
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/from.html b/examples/from.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/from.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/from.js b/examples/from.js deleted file mode 100644 index 16862ee0..00000000 --- a/examples/from.js +++ /dev/null @@ -1,19 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( -
- -
执行动效
-
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/fromDelay.html b/examples/fromDelay.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/fromDelay.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/fromDelay.js b/examples/fromDelay.js deleted file mode 100644 index ee2ac1b4..00000000 --- a/examples/fromDelay.js +++ /dev/null @@ -1,20 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( -
- -
执行动效
-
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/group.html b/examples/group.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/group.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/group.js b/examples/group.js deleted file mode 100644 index d1b2732f..00000000 --- a/examples/group.js +++ /dev/null @@ -1,96 +0,0 @@ -import { TweenOneGroup } from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import QueueAnim from 'rc-queue-anim'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - children: [ - -
执行动效
-
执行动效
-
, -
-
执行动效
-
, - ], - }; - } - - onClick = () => { - const children = !this.state.children ? [ - ( -
执行动效
-
执行动效
-
), (
-
执行动效
-
)] : null; - this.setState({ - children, - }); - } - - onEnd = (e) => { - console.log(e);// eslint-disable-line no-console - } - - enterType = (e) => { - if (e.key === 'a') { - return { x: 100, opacity: 0, type: 'from' }; - } - return { y: 80, opacity: 0, type: 'from' }; - } - - render() { - return ( -
- - - {this.state.children} - -
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/groupAbsolute.html b/examples/groupAbsolute.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/groupAbsolute.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/groupAbsolute.js b/examples/groupAbsolute.js deleted file mode 100644 index c1da186a..00000000 --- a/examples/groupAbsolute.js +++ /dev/null @@ -1,39 +0,0 @@ -import { TweenOneGroup } from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import '../assets/index.less'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.imgArray = [ - 'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg', - 'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg', - ]; - this.state = { - int: 0, - }; - } - - onClick = () => { - let int = this.state.int; - int++; - if (int >= this.imgArray.length) { - int = 0; - } - this.setState({ int }); - } - - render() { - return ( -
- - -
- img -
-
-
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/groupInStrict.html b/examples/groupInStrict.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/groupInStrict.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/groupInStrict.js b/examples/groupInStrict.js deleted file mode 100644 index 36872f56..00000000 --- a/examples/groupInStrict.js +++ /dev/null @@ -1,42 +0,0 @@ -import { TweenOneGroup } from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import '../assets/index.less'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.imgArray = [ - 'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg', - 'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg', - ]; - this.state = { - int: 0, - }; - } - - onClick = () => { - let int = this.state.int; - int++; - if (int >= this.imgArray.length) { - int = 0; - } - this.setState({ int }); - } - - render() { - return ( - -
- - -
- img -
-
-
-
- ); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/gsapWritten.html b/examples/gsapWritten.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/gsapWritten.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/gsapWritten.js b/examples/gsapWritten.js deleted file mode 100644 index 88fdb005..00000000 --- a/examples/gsapWritten.js +++ /dev/null @@ -1,15 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( - -
执行动效
-
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/momentJump.html b/examples/momentJump.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/momentJump.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/momentJump.js b/examples/momentJump.js deleted file mode 100644 index 1c146c94..00000000 --- a/examples/momentJump.js +++ /dev/null @@ -1,35 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - moment: 2500, // 初始值 - }; - } - - componentDidMount() { - setTimeout(() => { - this.setState({ - moment: 200, - }); - }, 1000); - } - - render() { - return ( -
-
moment初始为2500,所以第一个时间已过,而且第二个已播了1000
- -
执行动效
-
-
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/path.html b/examples/path.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/path.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/path.js b/examples/path.js deleted file mode 100644 index e937ba13..00000000 --- a/examples/path.js +++ /dev/null @@ -1,48 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import PathPlugin from '../src/plugin/PathPlugin'; - -Tween.plugins.push(PathPlugin); - -function Demo() { - const p = `M50.952,85.619C31.729,84.841,23.557,73.62,24.095,42.952 - c0.381-21.714,6.667-33.714,30.286-34.476 - c36.572-1.18,59.81,77.714,102.667,76.381c30.108-0.937,34.268-32.381,34.095-41.714 - C190.762,22.571,180.493,6.786,159.524,6C113.81,4.286,98,87.524,50.952,85.619z`; - - const p2 = "M0,0,L100, 0L100, 100L0, 100Z"; - return ( -
- - - - - - -
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/repeat.html b/examples/repeat.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/repeat.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/repeat.js b/examples/repeat.js deleted file mode 100644 index 23641550..00000000 --- a/examples/repeat.js +++ /dev/null @@ -1,21 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( - -
执行动效
-
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/scrollAnim.html b/examples/scrollAnim.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/scrollAnim.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/scrollAnimChildrenUpdateStyle.html b/examples/scrollAnimChildrenUpdateStyle.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/scrollAnimChildrenUpdateStyle.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/scrollAnimChildrenUpdateStyle.js b/examples/scrollAnimChildrenUpdateStyle.js deleted file mode 100644 index 58bc894b..00000000 --- a/examples/scrollAnimChildrenUpdateStyle.js +++ /dev/null @@ -1,29 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import ScrollOverPack from 'rc-scroll-anim/lib/ScrollOverPack'; -import { Row, Col } from 'antd'; - -function Demo() { - return ( -
-
往下滚动
- - - 执行动画 - - -
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/shadow.html b/examples/shadow.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/shadow.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/shadow.js b/examples/shadow.js deleted file mode 100644 index 55b6ce6e..00000000 --- a/examples/shadow.js +++ /dev/null @@ -1,18 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( - -
执行动效
-
); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/shadowInset.html b/examples/shadowInset.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/shadowInset.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/shadowInset.js b/examples/shadowInset.js deleted file mode 100644 index 448d456b..00000000 --- a/examples/shadowInset.js +++ /dev/null @@ -1,15 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( - -
执行动效
-
- ); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/simple.html b/examples/simple.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/simple.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/simple.js b/examples/simple.js deleted file mode 100644 index b5abffbc..00000000 --- a/examples/simple.js +++ /dev/null @@ -1,21 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import '../assets/index.less'; - -function Demo() { - const bbb = (e) => { - console.log(e);// eslint-disable-line no-console - } - - return ( - -
执行动效
-
- ); -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/svg.html b/examples/svg.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/svg.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/svg.js b/examples/svg.js deleted file mode 100644 index f523462e..00000000 --- a/examples/svg.js +++ /dev/null @@ -1,26 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import SvgMorphPlugin from '../src/plugin/SvgMorphPlugin'; - -Tween.plugins.push(SvgMorphPlugin); - -function Demo() { - return ( - - - - ); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/svgDraw.html b/examples/svgDraw.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/svgDraw.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/svgDraw.js b/examples/svgDraw.js deleted file mode 100644 index 41508171..00000000 --- a/examples/svgDraw.js +++ /dev/null @@ -1,47 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import SvgDrawPlugin from '../src/plugin/SvgDrawPlugin'; - -Tween.plugins.push(SvgDrawPlugin); - -const dataStartArr = ['100%', '30 450', '50% 50%', '30% 400', '50 30%', 0]; -let i = 0; -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - tweenData: '50 30%', - }; - } - - onClick = () => { - const tweenData = dataStartArr[i]; - this.setState({ - tweenData, - }); - i++; - i = i >= dataStartArr.length ? 0 : i; - } - - render() { - return ( -
- -

当前参数:{this.state.tweenData}

- - - -
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/svgDrawShape.html b/examples/svgDrawShape.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/svgDrawShape.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/svgDrawShape.js b/examples/svgDrawShape.js deleted file mode 100644 index da5835df..00000000 --- a/examples/svgDrawShape.js +++ /dev/null @@ -1,72 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import SvgDrawPlugin from '../src/plugin/SvgDrawPlugin'; - -Tween.plugins.push(SvgDrawPlugin); - -const dataStartArr = ['100%', '30 450', '50% 50%', '30% 400', '50 30%', 0]; -let i = 0; -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - tweenData: '50 30%', - }; - } - - onClick = () => { - const tweenData = dataStartArr[i]; - this.setState({ - tweenData, - }); - i++; - i = i >= dataStartArr.length ? 0 : i; - } - - render() { - return ( -
- -

当前参数:{this.state.tweenData}

- - - - - - - -
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/svgPoints.html b/examples/svgPoints.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/svgPoints.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/svgPoints.js b/examples/svgPoints.js deleted file mode 100644 index cb637bb7..00000000 --- a/examples/svgPoints.js +++ /dev/null @@ -1,23 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; -import SvgMorphPlugin from '../src/plugin/SvgMorphPlugin'; - -Tween.plugins.push(SvgMorphPlugin); - -function Demo() { - return ( - - - ); -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/timeline.html b/examples/timeline.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/timeline.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/timeline.js b/examples/timeline.js deleted file mode 100644 index af65b162..00000000 --- a/examples/timeline.js +++ /dev/null @@ -1,36 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - children: [
依次进入
,
依次进入
], - }; - } - - componentDidMount() { - setTimeout(() => { - this.setState({ - children: [
121221
,
1122121
], - }); - }, 1000); - } - - render() { - return ( - {this.state.children} - ); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/timelineRepeat.html b/examples/timelineRepeat.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/timelineRepeat.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/timelineRepeat.js b/examples/timelineRepeat.js deleted file mode 100644 index da949a27..00000000 --- a/examples/timelineRepeat.js +++ /dev/null @@ -1,45 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - children: [
依次进入
,
依次进入
], - }; - } - - componentDidMount() { - setTimeout(() => { - this.setState({ - children: [
121221
,
1122121
], - }); - }, 1000); - } - - onChange = (e) => { - console.log(e.timelineMode);// eslint-disable-line no-console - } - - render() { - return ( - - {this.state.children} - - ); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/translate3d.html b/examples/translate3d.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/translate3d.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/translate3d.js b/examples/translate3d.js deleted file mode 100644 index 3e70d1ea..00000000 --- a/examples/translate3d.js +++ /dev/null @@ -1,20 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( - -
执行动效
-
); -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/update.html b/examples/update.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/update.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/update.js b/examples/update.js deleted file mode 100644 index 1f50e1e9..00000000 --- a/examples/update.js +++ /dev/null @@ -1,73 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.testText = '刚开始的样式:'; - this.state = { - style: { opacity: 1, height: 200, marginLeft: 0, transform: 'translateY(0px)' }, - test: '', - animation: { translateY: 200, marginLeft: 500, duration: 5000 }, - }; - } - - componentDidMount() { - setTimeout(() => { - this.setState({ - style: { opacity: 1, height: 250, transform: 'translateY(100px)', marginLeft: 100 }, - }); - this.bool = false; - }, 1000); - } - - onChange = (e) => { - if (!this.bool) { - let text = (
当前时间 moment: {e.moment}
); - if (this.state.test) { - text = (
{this.state.test} -

当前时间 moment: {e.moment}

-
); - } - this.setState({ - test: text, - }); - this.bool = true; - } - } - - onClick = () =>{ - this.setState({ - style: { transform: 'translateY(10px)', marginLeft: 30, height: 300 }, - animation: { translateY: 100, marginLeft: 100, duration: 1000 }, - }); - this.bool = false; - } - - onClick2 = () => { - this.setState({ - style: { transform: 'translateY(0px)', marginLeft: 130, height: 300 }, - animation: { translateY: 200, marginLeft: 500, duration: 1000 }, - }); - this.bool = false; - } - - render() { - return (
-

在动画时, 变化 style, 将重新计算为 start

-
- - -
- -
变化的样式
-
-
{this.state.test}
-
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/updateStyle.html b/examples/updateStyle.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/updateStyle.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/updateStyle.js b/examples/updateStyle.js deleted file mode 100644 index 24b0b5b5..00000000 --- a/examples/updateStyle.js +++ /dev/null @@ -1,27 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -class Demo extends React.Component { - constructor(props) { - super(props); - this.state = { - tweenData: { translateX: '100px', duration: 2000 }, - }; - } - - componentDidMount() { - setTimeout(() => { - this.setState({ - style: { transform: 'translateX(500px)', marginTop: 300 }, - }); - }, 1100); - } - - render() { - return ( -
执行动效
-
); - } -} -ReactDom.render(, document.getElementById('__react-content')); diff --git a/examples/yoyo.html b/examples/yoyo.html deleted file mode 100644 index b3a42524..00000000 --- a/examples/yoyo.html +++ /dev/null @@ -1 +0,0 @@ -placeholder \ No newline at end of file diff --git a/examples/yoyo.js b/examples/yoyo.js deleted file mode 100644 index ef9b4a94..00000000 --- a/examples/yoyo.js +++ /dev/null @@ -1,19 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ReactDom from 'react-dom'; - -function Demo() { - return ( - -
执行动效
-
- ); -} - -ReactDom.render(, document.getElementById('__react-content')); diff --git a/import.d.ts b/import.d.ts new file mode 100644 index 00000000..912a0106 --- /dev/null +++ b/import.d.ts @@ -0,0 +1,13 @@ +import * as CSS from 'csstype'; +import * as TweenOne from 'tween-one'; + +declare module 'csstype' { + interface Properties { + [key: string]: any; + } +} +declare module 'TweenOne' { + interface Ticker { + [key: string]: any; + } +} diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 00000000..3417d388 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,24 @@ + +declare module '*.css'; +declare module '*.less'; +declare module 'style-utils'; +declare module 'tween-functions'; + +declare module 'rc-tween-one'; +declare module 'rc-tween-one/src/plugin/ChildrenPlugin'; +declare module 'rc-tween-one/src/plugin/PathMotionPlugin'; +declare module 'rc-tween-one/src/plugin/SvgDrawPlugin'; +declare module 'rc-tween-one/src/plugin/SvgMorphPlugin'; +declare module 'rc-tween-one/src/TweenOneGroup'; + + +interface IObject { + [key: string]: any +} +interface Element { + _tweenOneVars: any; +} + +interface Ticker { + [key: string]: any; +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 00000000..fd4d7e5c --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +module.exports = require('./src/'); diff --git a/now.json b/now.json new file mode 100644 index 00000000..196bc225 --- /dev/null +++ b/now.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "name": "rc-tween-one", + "builds": [ + { + "src": "package.json", + "use": "@now/static-build", + "config": { "distDir": ".doc" } + } + ] +} diff --git a/package.json b/package.json index 6af98685..2bea8f3d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,12 @@ { "name": "rc-tween-one", - "version": "2.7.3", + "version": "3.0.0-beta.0", "description": "tween-one anim component for react", + "typings": "es/index.d.ts", + "type": "module", + "engines": { + "node": ">=8.x" + }, "keywords": [ "react", "react-component", @@ -21,7 +26,7 @@ "ant-motion" ], "homepage": "https://github.com/react-component/tween-one", - "author": "", + "author": "155259966@qq.com", "repository": { "type": "git", "url": "https://github.com/react-component/tween-one.git" @@ -30,67 +35,59 @@ "url": "https://github.com/react-component/tween-one/issues" }, "files": [ + "es", "lib", "assets/*.css", - "dist", - "es", - "typings" + "assets/*.less" ], "licenses": "MIT", "main": "./lib/index", "module": "./es/index", - "sideEffects": false, - "config": { - "port": 8100, - "entry": { - "rc-tween-one": [ - "./assets/index.less", - "./src/index.js" - ] - } - }, "scripts": { - "dist": "rc-tools run dist", - "build": "rc-tools run build", - "gh-pages": "rc-tools run gh-pages", - "start": "rc-tools run server", - "compile": "rc-tools run compile --babel-runtime", - "pub": "rc-tools run pub --babel-runtime", - "lint": "rc-tools run lint --fix", - "karma": "rc-test run karma", - "saucelabs": "rc-test run saucelabs", - "test": "rc-test run test", - "prettier": "rc-tools run prettier", - "chrome-test": "rc-test run chrome-test", - "coverage": "rc-test run coverage", - "validate": "npm ls" + "start": "dumi dev", + "docs:build": "dumi build", + "docs:deploy": "gh-pages -d docs-dist", + "compile": "father-build", + "deploy": "npm run docs:build && npm run docs:deploy", + "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"", + "test": "umi-test test", + "test:coverage": "umi-test --coverage", + "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish", + "lint": "eslint src/ --ext .tsx,.ts", + "lint:tsc": "tsc -p tsconfig.json --noEmit", + "now-build": "npm run docs:build" }, "devDependencies": { - "@types/react": "^16.0.0", - "antd": "^3.12.1", - "core-js": "^2.5.7", - "expect.js": "0.3.x", - "precommit-hook": "^3.0.0", - "rc-scroll-anim": "2.x", - "rc-test": "6.x", - "rc-tools": "8.x", - "react": "^16.4.0", - "react-dom": "^16.4.0", - "tslint-config-prettier": "^1.17.0", - "tslint-react": "^5.0.0", - "typescript": "3.x" + "@ant-design/icons": "^4.3.0", + "@types/enzyme": "^3.10.5", + "@types/jest": "^25.2.1", + "@types/lodash": "^4.14.135", + "@types/react": "^16.8.19", + "@types/react-dom": "^16.8.4", + "@umijs/test": "^3.2.28", + "antd": "^4.8.4", + "dumi": "^1.1.0-rc.1", + "enzyme": "^3.3.0", + "enzyme-adapter-react-16": "^1.0.2", + "enzyme-to-json": "^3.4.0", + "father": "^2.22.6", + "father-build": "^1.18.6", + "gh-pages": "^3.1.0", + "np": "^6.0.3", + "prettier": "^2.1.2", + "rc-scroll-anim": "^2.7.6", + "react": "^16.9.0", + "react-dom": "^16.9.0", + "regenerator-runtime": "^0.13.7", + "typescript": "^4.0.2" }, - "pre-commit": [ - "lint", - "test" - ], - "dependencies": { - "prop-types": "^15.6.1", - "babel-runtime": "6.x", - "raf": "~3.4.0", - "react-lifecycles-compat": "^3.0.4", - "style-utils": "~0.2.0", - "tween-functions": "~1.2.0" + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" }, - "types": "typings/index.d.ts" + "dependencies": { + "@babel/runtime": "^7.11.1", + "style-utils": "^0.3.4", + "tween-one": "^1.0.9" + } } diff --git a/src/Tween.js b/src/Tween.js deleted file mode 100644 index 676f4906..00000000 --- a/src/Tween.js +++ /dev/null @@ -1,487 +0,0 @@ -/* eslint-disable func-names */ -/** - * Created by jljsj on 16/1/27. - */ -import { - getColor, - parseColor, - toFixed, - stylesToCss, - createMatrix, - getGsapType, - isTransform, - checkStyleName, - toCssLowerCase, -} from 'style-utils'; - -import easingTypes from './easing'; -import _plugin from './plugins'; -import StylePlugin from './plugin/StylePlugin'; -import { startConvertToEndUnit, transformOrFilter, dataToArray } from './util.js'; - -const DEFAULT_EASING = 'easeInOutQuad'; -const DEFAULT_DURATION = 450; -const DEFAULT_DELAY = 0; -function noop() { -} -_plugin.push(StylePlugin); -// 设置默认数据 -function defaultData(vars, now) { - const duration = vars.duration || vars.duration === 0 ? vars.duration : DEFAULT_DURATION; - return { - duration: vars.type === 'set' ? 0 : duration, - delay: vars.delay || DEFAULT_DELAY, - ease: typeof vars.ease === 'function' ? vars.ease : easingTypes[vars.ease || DEFAULT_EASING], - onUpdate: vars.onUpdate || noop, - onComplete: vars.onComplete || noop, - onStart: vars.onStart || noop, - onRepeat: vars.onRepeat || noop, - repeat: vars.repeat || 0, - repeatDelay: vars.repeatDelay || 0, - yoyo: vars.yoyo || false, - type: vars.type === 'from' ? 'from' : 'to', - initTime: now, - appearTo: typeof vars.appearTo === 'number' ? vars.appearTo : null, - perTime: 0, - currentRepeat: 0, - }; -} - -const Tween = function (target, to, attr) { - const toData = dataToArray(to); - this.target = target; - this.attr = attr || 'style'; - // 时间精度补齐; - this.accuracy = 0.00001; - // 记录总时间; - this.totalTime = 0; - // 记录当前时间; - this.progressTime = 0; - // 记录时间轴数据; - this.defaultData = []; - // 每个的开始数据; - this.start = {}; - // 开始默认的数据; - this.startDefaultData = {}; - // 动画过程 - this.tween = {}; - // toData; - this.data = toData; - // 每帧的时间; - this.perFrame = Math.round(1000 / 60); - // 注册,第一次进入执行注册 - this.register = false; - // svg元素 - this.isSvg = this.target.ownerSVGElement; - // 设置 style - const data = this.setAttrIsStyle(); - // 设置默认动画数据; - this.setDefaultData(data); -}; -const p = Tween.prototype; -p.setAttrIsStyle = function () { - const data = []; - const defaultParam = defaultData({}, 0); - this.data.forEach((d, i) => { - const _d = { ...d }; - if (this.attr === 'style') { - data[i] = {}; - Object.keys(_d).forEach(key => { - if (key in defaultParam) { - data[i][key] = _d[key]; - delete _d[key]; - } - }); - data[i].style = _d; - this.startDefaultData.style = this.target.getAttribute('style') || ''; - } else if (this.attr === 'attr') { - Object.keys(_d).forEach(key => { - if (key === 'style' && Array.isArray(d[key])) { - throw new Error('Style should be the object.'); - } - if (key === 'bezier') { - _d.style = { ..._d.style, bezier: _d[key] }; - delete _d[key]; - this.startDefaultData.style = this.target.getAttribute('style') || ''; - } else { - if (key in defaultParam) { - return; - } - this.startDefaultData[key] = this.getValue(key); - } - }); - data[i] = _d; - } - }); - return data; -}; -p.setDefaultData = function (_vars) { - let now = 0; - let repeatMax = false; - const data = _vars.map(item => { - const appearToBool = typeof item.appearTo === 'number'; - // 加上延时,在没有播放过时; - if (!appearToBool) { - now += item.delay || 0; - } - const appearToTime = (item.appearTo || 0) + (item.delay || 0); - // 获取默认数据 - const tweenData = defaultData(item, appearToBool ? appearToTime : now); - tweenData.vars = {}; - Object.keys(item).forEach(_key => { - if (!(_key in tweenData)) { - const _data = item[_key]; - if (_key in _plugin) { - tweenData.vars[_key] = new _plugin[_key](this.target, _data, tweenData.type); - } else if ((_key === 'd' || _key === 'points') && 'SVGMorph' in _plugin) { - tweenData.vars[_key] = new _plugin.SVGMorph(this.target, _data, _key); - } else if (_key.match(/color/i) || _key === 'stroke' || _key === 'fill') { - tweenData.vars[_key] = { type: 'color', vars: parseColor(_data) }; - } else if (typeof _data === 'number' || _data.split(/[,|\s]/g).length <= 1) { - const vars = parseFloat(_data); - const unit = _data.toString().replace(/[^a-z|%]/g, ''); - const count = _data.toString().replace(/[^+|=|-]/g, ''); - tweenData.vars[_key] = { unit, vars, count }; - } - } - }); - if (tweenData.yoyo && !tweenData.repeat) { - console.warn('Warning: yoyo must be used together with repeat;');// eslint-disable-line - } - if (tweenData.repeat === -1) { - repeatMax = true; - } - const repeat = tweenData.repeat === -1 ? 0 : tweenData.repeat; - if (appearToBool) { - // 如果有 appearTo 且这条时间比 now 大时,,总时间用这条; - const appearNow = item.appearTo + (item.delay || 0) + - tweenData.duration * (repeat + 1) + tweenData.repeatDelay * repeat; - now = appearNow >= now ? appearNow : now; - } else if (tweenData.delay < -tweenData.duration) { - // 如果延时小于 负时间时,,不加,再减回延时; - now -= tweenData.delay; - } else { - // repeat 为 -1 只记录一次。不能跟 reverse 同时使用; - now += tweenData.duration * (repeat + 1) + tweenData.repeatDelay * repeat; - } - tweenData.mode = ''; - return tweenData; - }); - this.totalTime = repeatMax ? Number.MAX_VALUE : now; - this.defaultData = data; -}; -p.getComputedStyle = function () { - const style = typeof window !== 'undefined' && document.defaultView ? - document.defaultView.getComputedStyle(this.target) : {}; - // 如果是 SVG, 样式全部提出为 transformSVG, 兼容 safari 不能获取 transform; - if (this.isSvg) { - let transform = style[checkStyleName('transform')] || 'none'; - if (transform === 'none') { - const attrStyle = this.target.getAttribute('style'); - if (attrStyle && attrStyle.indexOf('transform:') >= 0) { - transform = attrStyle.split(';') - .filter(k => k.indexOf('transform:') >= 0) - .map(item => createMatrix(item.split(':')[1].trim()).toString())[0]; - } else if (this.target.getAttribute('transform')) { - // 暂时不支持标签上的 transform,后期增加; - console.warn('Do not add transform on the label, otherwise it will be invalid.');// eslint-disable-line no-console - } - } - style.transformSVG = transform; - } - return style; -}; -p.getAnimStartData = function (item) { - const start = {}; - Object.keys(item).forEach(_key => { - if (_key in _plugin || (this.attr === 'attr' && (_key === 'd' || _key === 'points'))) { - this.computedStyle = this.computedStyle || (!this.target.getAttribute ? { ...this.target } : this.getComputedStyle()); - start[_key] = item[_key].getAnimStart(this.computedStyle, this.tween, this.isSvg); - return; - } - if (this.attr === 'attr') { - // 除了d和这points外的标签动画; - const attribute = this.getValue(_key); - const s = _key.match(/opacity/ig) ? 1 : 0 - let data = attribute === 'null' || !attribute ? s : attribute; - if (_key.match(/color/i) || _key === 'stroke' || _key === 'fill') { - data = !data && _key === 'stroke' ? 'rgba(255, 255, 255, 0)' : data; - data = parseColor(data); - start[_key] = data; - } else if (parseFloat(data) || parseFloat(data) === 0 || data === 0) { - const unit = data.toString().replace(/[^a-z|%]/g, ''); - start[_key] = unit !== item[_key].unit ? - startConvertToEndUnit(this.target, _key, parseFloat(data), unit, item[_key].unit) - : parseFloat(data); - } - return; - } - start[_key] = this.target[_key] || 0; - }); - return start; -}; -p.setAnimData = function (data) { - Object.keys(data).forEach(key => { - if (key in _plugin || (this.attr === 'attr' && (key === 'd' || key === 'points'))) { - return; - } - this.target[key] = data[key]; - }); -}; -p.setRatio = function (ratio, endData, i) { - Object.keys(endData.vars).forEach(_key => { - if (_key in _plugin || (this.attr === 'attr' && (_key === 'd' || _key === 'points'))) { - endData.vars[_key].setRatio(ratio, this.tween, this.isSvg && this.computedStyle); - return; - } - const endVars = endData.vars[_key]; - const startVars = this.start[i][_key]; - let data; - if (this.attr === 'attr') { - // 除了d和这points外的标签动画; - if (!endVars.type) { - data = endVars.unit.charAt(1) === '=' ? startVars + endVars.vars * ratio + endVars.unit : - (endVars.vars - startVars) * ratio + startVars + endVars.unit; - this.setValue(_key, endVars.unit ? data : parseFloat(data)); - } else if (endVars.type === 'color') { - if (endVars.vars.length === 3 && startVars.length === 4) { - endVars.vars[3] = 1; - } - data = endVars.vars.map((_endData, _i) => { - const startData = startVars[_i] || 0; - return (_endData - startData) * ratio + startData; - }); - this.setValue(_key, getColor(data)); - } - } - }); - this.setAnimData(this.tween); -}; -p.getValue = function (key) { - return this.target.getAttribute ? this.target.getAttribute(key) : this.target[key]; -} -p.setValue = function (key, value) { - if (this.target.setAttribute) { - this.target.setAttribute(key, value); - } else { - this.target[key] = value; - } -} -p.render = function () { - const reverse = this.reverse; - this.defaultData.forEach((item, i) => { - let initTime = item.initTime; - const duration = toFixed(item.duration); - // 处理 yoyo 和 repeat; yoyo 是在时间轴上的, 并不是倒放 - let repeatNum = Math.ceil((this.progressTime - initTime) / - (duration + item.repeatDelay)) - 1 || 0; - repeatNum = repeatNum < 0 ? 0 : repeatNum; - if (item.repeat) { - if (item.repeat < repeatNum && item.repeat !== -1) { - return; - } - if (item.repeat || item.repeat <= repeatNum) { - initTime += repeatNum * (duration + item.repeatDelay); - } - } - let startData = item.yoyo && repeatNum % 2 ? 1 : 0; - let endData = item.yoyo && repeatNum % 2 ? 0 : 1; - startData = item.type === 'from' ? 1 - startData : startData; - endData = item.type === 'from' ? 1 - endData : endData; - // 精度损失,只取小数点后10位。 - let progressTime = toFixed(this.progressTime - initTime); - - let ratio; - - // 开始注册; - // from 时需先执行参数位置; - const fromDelay = item.type === 'from' ? item.delay : 0; - if (progressTime + fromDelay >= 0) { - if (!this.start[i]) { - // 设置 start - this.start[i] = this.getAnimStartData(item.vars); - if (progressTime < this.perFrame) { - ratio = !item.duration && !item.delay ? item.ease(1, startData, endData, 1) - : item.ease(0, startData, endData, 1); - this.setRatio(ratio, item, i); - } else if (progressTime > duration) { - ratio = item.ease(1, startData, endData, 1); - this.setRatio(ratio, item, i); - } - if (!this.register || i && !initTime) { - this.register = true; - if (progressTime === 0 && item.duration && item.delay) { - return; - } - } - } - } - - const e = { - index: i, - target: this.target, - }; - const cb = { - moment: this.progressTime, - ...e, - }; - const maxPer = this.perFrame - this.accuracy; - const startTime = item.delay && reverse ? -maxPer : 0; - if ((progressTime >= startTime && - !(progressTime > duration && item.mode === 'onComplete') - || (progressTime < startTime && item.mode && item.mode !== 'onStart') - ) && - this.start[i]) { - const updateAnim = this.updateAnim === 'update'; - progressTime = (progressTime < maxPer) && !reverse - && item.duration >= this.perFrame ? 0 : progressTime; - if (((progressTime >= duration - this.accuracy && !reverse) || (reverse && progressTime <= 0)) - && repeatNum >= item.repeat) { - if (item.mode === 'onComplete') { - return; - } - // onReveresComplete 和 onComplete 统一用 onComplete; - ratio = item.ease(reverse ? 0 : 1, startData, endData, 1); - this.setRatio(ratio, item, i, item.currentRepeat !== repeatNum); - if ((!item.reset || item.reset && progressTime >= duration) && !updateAnim) { - // duration 为 0 时的一个回调; - if (duration < maxPer) { - if (!duration) { - item.onStart(e); - cb.mode = 'onStart'; - this.onChange(cb); - } - item.onUpdate({ ratio, ...e }); - cb.mode = 'onUpdate'; - this.onChange(cb); - } - item.onComplete(e); - } else if (progressTime >= duration + maxPer) { - return; - } - item.mode = 'onComplete'; - } else if (duration > maxPer) { - let currentProgress = progressTime < 0 ? 0 : progressTime; - currentProgress = currentProgress > duration ? duration : currentProgress; - ratio = item.ease(currentProgress, startData, endData, duration); - this.setRatio(ratio, item, i); - if (!updateAnim) { - if (item.repeat && repeatNum > 0 && item.currentRepeat !== repeatNum) { - item.mode = 'onRepeat'; - item.currentRepeat = repeatNum; - item.onRepeat({ ...e, repeatNum }); - } else if ((item.perTime <= 0 || - (reverse && (item.perTime >= this.reverseStartTime - initTime))) - && item.mode !== 'onStart') { - // onReveresStart 和 onStart 统一用 onStart; - item.mode = 'onStart'; - item.onStart(e); - } else { - item.mode = 'onUpdate'; - item.onUpdate({ ratio, ...e }); - } - } - } - - if (!updateAnim) { - cb.mode = item.mode; - this.onChange(cb); - } - item.perTime = progressTime; - if (item.reset) { - delete item.reset; - } - } - }); -}; -// 播放帧 -p.frame = function (moment) { - this.progressTime = moment; - this.defaultData.forEach(item => { - const t = this.progressTime - item.duration - item.initTime; - if (t < this.perFrame && t > 0) { - this.progressTime = item.duration + item.initTime; - } - }); - this.render(); -}; - -p.init = p.frame; - -p.resetAnimData = function () { - this.tween = {}; - this.start = {}; -}; - -const getDefaultStyle = function (domStyle, defaultStyle, tweenData) { - const $data = defaultData({}, 0); - const getStyleToArray = (styleString) => ( - styleString.split(';').filter(c => c).map(str => - str.split(':').map(s => s.trim()) - ) - ); - const styleToArray = getStyleToArray(defaultStyle); - let domStyleToArray = getStyleToArray(domStyle); - tweenData.forEach(value => { - Object.keys(value).forEach(name => { - if (!(name in $data)) { - const $name = name === 'bezier' ? 'transform' : name; - const styleName = toCssLowerCase(isTransform(getGsapType($name))); - domStyleToArray = domStyleToArray.filter(item => { - // 去除 plugins 的特殊名称。 - if (transformOrFilter[item[0]] && transformOrFilter[styleName]) { - return false; - } - return item[0] !== styleName; - }); - } - }) - }); - styleToArray.forEach(item => { - domStyleToArray = domStyleToArray.filter($item => { - if ($item[0] === item[0]) { - return false; - } - return true; - }); - }) - return styleToArray.concat(domStyleToArray).map(item => item.join(':')).join(';'); -} - -p.resetDefaultStyle = function () { - this.tween = {}; - this.defaultData = this.defaultData.map(item => { - item.reset = true; - delete item.mode; - return item; - }); - const data = defaultData({}, 0); - Object.keys(this.startDefaultData).forEach(key => { - if (!(key in data)) { - if (key === 'style') { - const value = getDefaultStyle(this.target.style.cssText, - this.startDefaultData.style, - this.data); - this.setValue(key, value); - } else { - this.setValue(key, this.startDefaultData[key]); - } - this.computedStyle = null; - } - }); -}; - -p.reStart = function (style, preStyle, isTween) { - this.start = {}; - this.tween = {}; - Object.keys(style || {}).forEach(key => { - if (isTween || !preStyle || style[key] !== preStyle[key]) { - this.target.style[key] = stylesToCss(key, style[key]); - } - }); - this.setAttrIsStyle(); - this.computedStyle = null; -}; - -p.onChange = noop; -export default Tween; diff --git a/src/TweenOne.jsx b/src/TweenOne.jsx deleted file mode 100644 index 0bd373f7..00000000 --- a/src/TweenOne.jsx +++ /dev/null @@ -1,363 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import ReactDom from 'react-dom'; -import { polyfill } from 'react-lifecycles-compat'; - -import { objectEqual } from './util'; -import Tween from './Tween'; -import ticker from './ticker'; - -function noop() {} - -const perFrame = Math.round(1000 / 60); -const objectOrArray = PropTypes.oneOfType([PropTypes.object, PropTypes.array]); - -class TweenOne extends Component { - static propTypes = { - component: PropTypes.any, - componentProps: PropTypes.any, - animation: objectOrArray, - children: PropTypes.any, - style: PropTypes.object, - paused: PropTypes.bool, - reverse: PropTypes.bool, - reverseDelay: PropTypes.number, - yoyo: PropTypes.bool, - repeat: PropTypes.number, - moment: PropTypes.number, - attr: PropTypes.string, - onChange: PropTypes.func, - resetStyle: PropTypes.bool, - forcedJudg: PropTypes.object, - }; - - static defaultProps = { - component: 'div', - componentProps: {}, - reverseDelay: 0, - repeat: 0, - attr: 'style', - onChange: noop, - }; - - static getDerivedStateFromProps(props, { prevProps, $self }) { - const nextState = { - prevProps: props, - }; - if (prevProps && props !== prevProps) { - if (!$self.tween && !$self.dom) { - $self.updateAnim = true; - return nextState; - } - - // 动画处理 - const newAnimation = props.animation; - const currentAnimation = prevProps.animation; - const equal = objectEqual(currentAnimation, newAnimation); - if (!equal) { - if (props.resetStyle && $self.tween) { - $self.tween.resetDefaultStyle(); - } - $self.updateAnim = true; - } - - // 跳帧事件 moment; - const nextMoment = props.moment; - if (typeof nextMoment === 'number' && nextMoment !== prevProps.moment) { - if ($self.tween && !$self.updateAnim) { - $self.startMoment = nextMoment; - $self.startTime = ticker.time; - if (props.paused) { - $self.raf(); - } - if ($self.tween.progressTime >= $self.tween.totalTime) { - $self.play(); - } - } else { - $self.updateAnim = true; - } - } - - // 暂停倒放 - if ($self.paused !== props.paused || $self.reverse !== props.reverse) { - $self.paused = props.paused; - $self.reverse = props.reverse; - if ($self.paused) { - $self.cancelRequestAnimationFrame(); - } else if ($self.reverse && props.reverseDelay) { - $self.cancelRequestAnimationFrame(); - ticker.timeout($self.restart, props.reverseDelay); - } else { - // 在 form 状态下,暂停时拉 moment 时,start 有值恢复播放,在 delay 的时间没有处理。。 - if ($self.tween) { - $self.tween.resetAnimData(); - $self.tween.resetDefaultStyle(); - } - if (!$self.updateAnim) { - $self.restart(); - } - } - } - - const styleEqual = objectEqual(prevProps.style, props.style); - if (!styleEqual) { - // 在动画时更改了 style, 作为更改开始数值。 - if ($self.tween) { - $self.tween.reStart( - props.style, - prevProps.style, - $self.tween.progressTime < $self.tween.totalTime, - ); - if ($self.paused) { - $self.raf(); - } - } - } - $self.setForcedJudg(props); - } - return nextState; // eslint-disable-line - } - - constructor(props) { - super(props); - this.rafID = -1; - this.paused = props.paused; - this.reverse = props.reverse; - this.updateAnim = false; - this.repeatNum = 0; - // 定义 ref 给外部使用; - this.currentRef = null; - this.forced = {}; - this.setForcedJudg(props); - this.state = { - $self: this, - }; - } - - componentDidMount() { - this.dom = ReactDom.findDOMNode(this); - if (this.dom && this.dom.nodeName !== '#text') { - this.start(); - } - } - - componentDidUpdate() { - if (!this.dom) { - this.dom = ReactDom.findDOMNode(this); - } - // 样式更新了后再执行动画; - if (this.updateAnim && this.dom && this.dom.nodeName !== '#text') { - if (this.tween) { - this.cancelRequestAnimationFrame(); - } - this.start(); - } - } - - componentWillUnmount() { - this.cancelRequestAnimationFrame(); - } - - /** - * @method setForcedJudg - * @param props - * QueueAnim 套在组件下面后导至子级变化。 - * - * - * - * - * - * rc-Menu 里是以 isXXX 来判断是 rc-Menu 的子级; - * 如: 用 isSubMenu 来处理 hover 事件 - * 地址: https://github.com/react-component/menu/blob/master/src/MenuMixin.js#L172 - * 暂时方案: 在组件里添加判断用的值。 - */ - - setForcedJudg = props => { - Object.keys(this.forced).forEach(key => { - delete this[key]; - delete this.forced[key]; - }); - if (props.forcedJudg) { - Object.keys(props.forcedJudg).forEach(key => { - if (!this[key]) { - this[key] = props.forcedJudg[key]; - this.forced[key] = 1; - } - }); - } - }; - - setDefault = props => { - this.moment = props.moment || 0; - this.startMoment = props.moment || 0; - this.startTime = ticker.time; - }; - - restart = () => { - if (!this.tween) { - return; - } - this.startMoment = this.moment; - this.startTime = ticker.time; - this.tween.reverse = this.reverse; - this.tween.reverseStartTime = this.startMoment; - this.raf(); - this.play(); - }; - - start = () => { - this.updateAnim = false; - const props = this.props; - if (props.animation && Object.keys(props.animation).length) { - this.setDefault(props); - this.tween = new Tween(this.dom, props.animation, props.attr); - this.tween.reverse = this.reverse; - // 预先注册 raf, 初始动画数值。 - this.raf(); - // 开始动画 - this.play(); - } else { - this.tween = null; - } - }; - - play = () => { - this.cancelRequestAnimationFrame(); - if (this.paused) { - return; - } - this.rafID = ticker.add(this.raf); - }; - - frame = () => { - const { yoyo } = this.props; - let { repeat } = this.props; - const totalTime = repeat === -1 ? Number.MAX_VALUE : this.tween.totalTime * (repeat + 1); - repeat = repeat >= 0 ? repeat : Number.MAX_VALUE; - let moment = ticker.time - this.startTime + this.startMoment; - if (this.reverse) { - moment = (this.startMoment || 0) - (ticker.time - this.startTime); - } - moment = moment > totalTime ? totalTime : moment; - moment = moment <= 0 ? 0 : moment; - let repeatNum = Math.floor(moment / this.tween.totalTime) || 0; - repeatNum = repeatNum > repeat ? repeat : repeatNum; - let tweenMoment = moment - this.tween.totalTime * repeatNum; - tweenMoment = - tweenMoment < perFrame && !this.reverse && totalTime >= perFrame ? 0 : tweenMoment; - if (repeat && moment && moment - this.tween.totalTime * repeatNum < perFrame) { - // 在重置样式之前补 complete; - this.tween.frame(this.tween.totalTime * repeatNum); - } - if ( - (moment < this.moment && !this.reverse) || - (repeat !== 0 && repeatNum && repeatNum !== this.repeatNum) - ) { - // 在 form 状态下,暂停时拉 moment 时,start 有值,,往返方向播放时,在 delay 的时间没有处理。。 - // 与上面的处理一样,删除 start ,重新走一遍 start。。 - this.tween.resetAnimData(); - this.tween.resetDefaultStyle(); - } - const yoyoReverse = yoyo && repeatNum % 2; - if (yoyoReverse) { - tweenMoment = this.tween.totalTime - tweenMoment; - } - this.tween.onChange = e => { - const cb = { - ...e, - timelineMode: '', - }; - - if ( - (this.moment === this.startMoment && !this.reverse && !e.index && e.mode === 'onStart') || - this.reverse - ) { - cb.timelineMode = 'onTimelineStart'; - } else if ((moment >= totalTime && !this.reverse) || (!moment && this.reverse)) { - cb.timelineMode = 'onTimelineComplete'; - } else if (repeatNum !== this.timelineRepeatNum) { - cb.timelineMode = 'onTimelineRepeat'; - } else { - cb.timelineMode = 'onTimelineUpdate'; - } - this.timelineRepeatNum = repeatNum; - this.props.onChange(cb); - }; - this.moment = moment; - this.repeatNum = repeatNum; - this.tween.frame(tweenMoment); - }; - - raf = () => { - const tween = this.tween; - this.frame(); - if (tween !== this.tween) { - // 在 onComplete 时更换动画时,raf 没结束,所以需要强制退出,避逸两个时间的冲突。 - return null; - } - const { repeat } = this.props; - const totalTime = repeat === -1 ? Number.MAX_VALUE : this.tween.totalTime * (repeat + 1); - if ( - (this.moment >= totalTime && !this.reverse) || - this.paused || - (this.reverse && this.moment === 0) - ) { - return this.cancelRequestAnimationFrame(); - } - return null; - }; - - cancelRequestAnimationFrame = () => { - ticker.clear(this.rafID); - this.rafID = -1; - }; - - render() { - const { - animation, - component, - componentProps, - reverseDelay, - attr, - paused, - reverse, - repeat, - yoyo, - moment, - resetStyle, - forcedJudg, - ...props - } = this.props; - Object.keys(props.style || {}).forEach(p => { - if (p.match(/filter/i)) { - ['Webkit', 'Moz', 'Ms', 'ms'].forEach(prefix => { - props.style[`${prefix}Filter`] = props.style[p]; - }); - } - }); - const refFunc = (c) => { - this.currentRef = c; - } - // component 为空时调用子级的。。 - const { className, children } = props; - if (!component && typeof children !== 'string') { - if (!children) { - return children; - } - const childrenProps = children.props; - const { style: childStyle, className: childClass } = childrenProps || {}; - // 合并 style 与 className。 - const newStyle = { ...childStyle, ...props.style }; - const newClassName = className ? `${className} ${childClass}` : childClass; - return React.cloneElement(children, { style: newStyle, ref: refFunc, className: newClassName }); - } - return React.createElement(component, { - ref: refFunc, - ...props, - ...componentProps, - }); - } -} -TweenOne.isTweenOne = true; -export default polyfill(TweenOne); diff --git a/src/TweenOne.tsx b/src/TweenOne.tsx new file mode 100644 index 00000000..4cebda73 --- /dev/null +++ b/src/TweenOne.tsx @@ -0,0 +1,144 @@ +import React, { useRef, createElement, useLayoutEffect } from 'react'; +import { findDOMNode } from 'react-dom'; +import TweenOneJS, { Tween } from 'tween-one'; +import { toStyleUpperCase, stylesToCss } from 'style-utils'; + +import { IAnimProps, IAnimObject, TweenOneRef } from './type'; +import { objectEqual } from './utils'; + +const TweenOne: TweenOneRef = React.forwardRef( + ( + { + component = 'div', + componentProps, + animation, + attr, + paused, + reverse, + repeat, + repeatDelay, + yoyo, + moment, + onChange, + onChangeTimeline, + resetStyle, + killPrevAnim = true, + ...props + }, + ref, + ) => { + const { children, className, style = {} } = props || {}; + + const domRef = useRef(); + const prevAnim = useRef(); + const animRef = useRef(); + const commonFunc = ( + key: 'paused' | 'moment' | 'reverse', + value: boolean | number | undefined, + ) => { + const tween: Tween = animRef.current!; + if (tween) { + if (key === 'moment') { + if (typeof value === 'number') { + tween.goto(value, paused); + } + return; + } + tween[key] = !!value; + } + }; + + useLayoutEffect(() => { + commonFunc('paused', paused); + }, [paused]); + // yoyo, moment, reverse, repeat, repeatDelay + useLayoutEffect(() => { + commonFunc('moment', moment); + }, [moment]); + + useLayoutEffect(() => { + commonFunc('reverse', reverse); + }, [reverse]); + useLayoutEffect(() => { + if (!domRef.current) { + return console.warn('Warning: TweenOne domRef is error.'); + } + // 动画写在标签上,手动对比; + if (!objectEqual(animation, prevAnim.current)) { + const dom = + domRef.current instanceof Element ? domRef.current : findDOMNode(domRef.current); + + if (!(dom instanceof Element)) { + // dom instanceof Text || !dom.tagName || + return console.error('Error: TweenOne tag is not dom.'); + } + if (animRef.current && killPrevAnim) { + animRef.current.kill(); + } + if (resetStyle && animRef.current) { + const styleStr = Object.keys(style) + .map((key: string) => `${toStyleUpperCase(key)}:${stylesToCss(key, style[key])}`) + .join(';'); + dom.setAttribute('style', styleStr); + // dom.style.cssText = styleStr; + delete dom._tweenOneVars; + } + animRef.current = + animation && + TweenOneJS(dom, { + animation, + attr, + yoyo, + moment, + repeat, + reverse, + paused, + repeatDelay, + onChange, + onChangeTimeline, + }); + prevAnim.current = animation; + } + }, [animation]); + + const refFunc = (c: any) => { + domRef.current = c; + if (ref && 'current' in ref) { + ref.current = c; + } else if (typeof ref === 'function') { + ref(c); + } + }; + + if ( + !component && + children && + typeof children !== 'string' && + typeof children !== 'boolean' && + typeof children !== 'number' + ) { + const childrenProps = children.props; + const { style: childStyle, className: childClass = '' } = childrenProps || {}; + // 合并 style 与 className。 + const newStyle = { ...childStyle, ...style }; + const newClassName = className ? `${className} ${childClass}`.trim() : childClass; + return React.cloneElement(children, { + style: newStyle, + ref: refFunc, + className: newClassName, + }); + } else if (!component) { + console.warn('Warning: component is null, children must be ReactElement.'); + return children; + } + return createElement(component, { + ref: refFunc, + ...props, + ...componentProps, + }); + }, +); +TweenOne.isTweenOne = true; +TweenOne.displayName = 'TweenOne'; + +export default TweenOne; diff --git a/src/TweenOneGroup.jsx b/src/TweenOneGroup.jsx deleted file mode 100644 index d3a33397..00000000 --- a/src/TweenOneGroup.jsx +++ /dev/null @@ -1,276 +0,0 @@ -import React, { Component, createElement } from 'react'; -import PropTypes from 'prop-types'; -import { polyfill } from 'react-lifecycles-compat'; - -import TweenOne from './TweenOne'; -import { - dataToArray, - toArrayChildren, - getChildrenFromProps, - mergeChildren, - transformArguments, - findChildInChildrenByKey, -} from './util'; - -function noop() {} - -class TweenOneGroup extends Component { - static getDerivedStateFromProps(props, { prevProps, $self }) { - const nextState = { - prevProps: props, - }; - if (prevProps && props !== prevProps) { - const nextChildren = toArrayChildren(props.children); - if (Object.keys($self.isTween).length && !props.exclusive) { - $self.animQueue.push(nextChildren); - return nextState; - } - const currentChildren = toArrayChildren($self.currentChildren); - nextState.children = $self.changeChildren(nextChildren, currentChildren); - } - return nextState; // eslint-disable-line - } - - constructor(props) { - super(props); - this.keysToEnter = []; - this.keysToLeave = []; - this.saveTweenTag = {}; - this.onEnterBool = false; - this.animQueue = []; - this.isTween = {}; - // 第一进入,appear 为 true 时默认用 enter 或 tween-one 上的效果 - const children = toArrayChildren(getChildrenFromProps(this.props)); - this.currentChildren = toArrayChildren(getChildrenFromProps(this.props)); - this.state = { - children, - $self: this, - }; - } - - componentDidMount() { - this.onEnterBool = true; - } - - onChange = (animation, key, type, obj) => { - const length = dataToArray(animation).length; - const tag = obj.target; - const classIsSvg = typeof tag.className === 'object' && 'baseVal' in tag.className; - const isEnter = type === 'enter' || type === 'appear'; - if (obj.mode === 'onStart') { - if (classIsSvg) { - tag.className.baseVal = this.setClassName(tag.className.baseVal, isEnter); - } else { - tag.className = this.setClassName(tag.className, isEnter); - } - } else if (obj.index === length - 1 && obj.mode === 'onComplete') { - delete this.isTween[key]; - if (classIsSvg) { - tag.className.baseVal = tag.className.baseVal - .replace(this.props.animatingClassName[isEnter ? 0 : 1], '') - .trim(); - } else { - tag.className = tag.className - .replace(this.props.animatingClassName[isEnter ? 0 : 1], '') - .trim(); - } - if (type === 'enter') { - this.keysToEnter.splice(this.keysToEnter.indexOf(key), 1); - if (!this.keysToEnter.length) { - this.reAnimQueue(); - } - } else if (type === 'leave') { - this.keysToLeave.splice(this.keysToLeave.indexOf(key), 1); - this.currentChildren = this.currentChildren.filter(child => key !== child.key); - if (!this.keysToLeave.length) { - const currentChildrenKeys = this.currentChildren.map(item => item.key); - Object.keys(this.saveTweenTag).forEach($key => { - if (currentChildrenKeys.indexOf($key) === -1) { - delete this.saveTweenTag[$key]; - } - }); - this.setState( - { - children: this.currentChildren, - }, - this.reAnimQueue, - ); - } - } - const _obj = { key, type }; - this.props.onEnd(_obj); - } - }; - - setClassName = (name, isEnter) => { - let className = name.replace(this.props.animatingClassName[isEnter ? 1 : 0], '').trim(); - if (className.indexOf(this.props.animatingClassName[isEnter ? 0 : 1]) === -1) { - className = `${className} ${this.props.animatingClassName[isEnter ? 0 : 1]}`.trim(); - } - return className; - }; - - getTweenChild = (child, props = {}) => { - const key = child.key; - this.saveTweenTag[key] = React.createElement( - TweenOne, - { - ...props, - key, - component: null, - }, - child, - ); - return this.saveTweenTag[key]; - }; - - getCoverAnimation = (child, i, type) => { - let animation; - animation = type === 'leave' ? this.props.leave : this.props.enter; - if (type === 'appear') { - const appear = transformArguments(this.props.appear, child.key, i); - animation = (appear && this.props.enter) || null; - } - const animate = transformArguments(animation, child.key, i); - const onChange = this.onChange.bind(this, animate, child.key, type); - const props = { - key: child.key, - animation: animate, - onChange, - resetStyle: this.props.resetStyle, - }; - if ( - this.keysToEnter.concat(this.keysToLeave).indexOf(child.key) >= 0 || - (!this.onEnterBool && animation) - ) { - if (!this.saveTweenTag[child.key]) { - this.isTween[child.key] = type; - } - } - const children = this.getTweenChild(child, props); - return children; - }; - - getChildrenToRender = children => { - return children.map((child, i) => { - if (!child || !child.key) { - return child; - } - const key = child.key; - if (this.keysToLeave.indexOf(key) >= 0) { - return this.getCoverAnimation(child, i, 'leave'); - } else if ( - (this.keysToEnter.indexOf(key) >= 0 || - (this.isTween[key] && this.keysToLeave.indexOf(key) === -1)) && - !(this.isTween[key] === 'enter' && this.saveTweenTag[key]) - ) { - /** - * 1. 在 key 在 enter 里。 - * 2. 出场未结束,触发进场, this.isTween[key] 为 leave, key 在 enter 里。 - * 3. 状态为 enter 且 tweenTag 里有值时,不执行重载动画属性,直接调用 tweenTag 里的。 - */ - return this.getCoverAnimation(child, i, 'enter'); - } else if (!this.onEnterBool) { - return this.getCoverAnimation(child, i, 'appear'); - } - return this.saveTweenTag[key]; - }); - }; - - reAnimQueue = () => { - if (!Object.keys(this.isTween).length && this.animQueue.length) { - const children = this.changeChildren( - this.animQueue[this.animQueue.length - 1], - this.state.children, - ); - this.setState({ - children, - }); - this.animQueue = []; - } - }; - - changeChildren(nextChildren, currentChildren) { - const newChildren = mergeChildren(currentChildren, nextChildren); - this.keysToEnter = []; - this.keysToLeave = []; - nextChildren.forEach(c => { - if (!c) { - return; - } - const key = c.key; - const hasPrev = findChildInChildrenByKey(currentChildren, key); - // 如果当前 key 已存在 saveTweenTag 里,,刷新 child; - if (this.saveTweenTag[key]) { - this.saveTweenTag[key] = React.cloneElement(this.saveTweenTag[key], {}, c); - } - if (!hasPrev && key) { - this.keysToEnter.push(key); - } - }); - - currentChildren.forEach(c => { - if (!c) { - return; - } - const key = c.key; - const hasNext = findChildInChildrenByKey(nextChildren, key); - if (!hasNext && key) { - this.keysToLeave.push(key); - delete this.saveTweenTag[key]; - } - }); - return newChildren; - } - - render() { - const { children } = this.state; - // fix in strict mode https://github.com/ant-design/ant-motion/issues/323; - this.currentChildren = children; - const childrenToRender = this.getChildrenToRender(children); - const { - component, - componentProps, - appear, - enter, - leave, - animatingClassName, - onEnd, - exclusive, - resetStyle, - ...props - } = this.props; - if (!component) { - return childrenToRender[0] || null; - } - return createElement(component, { ...props, ...componentProps }, childrenToRender); - } -} - -TweenOneGroup.propTypes = { - component: PropTypes.any, - componentProps: PropTypes.object, - children: PropTypes.any, - style: PropTypes.object, - appear: PropTypes.bool, - enter: PropTypes.any, - leave: PropTypes.any, - animatingClassName: PropTypes.array, - onEnd: PropTypes.func, - resetStyle: PropTypes.bool, - exclusive: PropTypes.bool, -}; - -TweenOneGroup.defaultProps = { - component: 'div', - componentProps: {}, - appear: true, - animatingClassName: ['tween-one-entering', 'tween-one-leaving'], - enter: { x: 50, opacity: 0, type: 'from' }, - leave: { x: -50, opacity: 0 }, - onEnd: noop, - resetStyle: true, - exclusive: false, -}; -TweenOneGroup.isTweenOneGroup = true; -export default polyfill(TweenOneGroup); diff --git a/src/TweenOneGroup.tsx b/src/TweenOneGroup.tsx new file mode 100644 index 00000000..6dcc4a92 --- /dev/null +++ b/src/TweenOneGroup.tsx @@ -0,0 +1,223 @@ +import React, { useRef, useEffect, useState, createElement, ReactElement, ReactText } from 'react'; +import { IGroupProps, IAnimObject, TweenOneGroupRef, ICallBack } from './type'; +import { + dataToArray, + getChildrenFromProps, + toArrayChildren, + transformArguments, + mergeChildren, + findChildInChildrenByKey, +} from './utils/group'; + +import TweenOne from './TweenOne'; + +const TweenOneGroup: TweenOneGroupRef = React.forwardRef((props, ref) => { + const { + component = 'div', + componentProps = {}, + leave: leaveAnim = { x: -50, opacity: 0 }, + enter: enterAnim = { x: 50, opacity: 0, type: 'from' }, + appear: appearBool = true, + resetStyle = true, + animatingClassName = ['tween-one-entering', 'tween-one-leaving'], + onEnd = () => {}, + exclusive = false, + ...tagProps + } = props; + const keysToEnter = useRef([]); + const keysToLeave = useRef([]); + const saveTweenTag = useRef({}); + const oneEnter = useRef(false); + const animQueue = useRef([]); + const isTween = useRef({}); + const cChild = toArrayChildren(getChildrenFromProps(props)); + const currentChildren = useRef(cChild); + const [children, setChild] = useState(cChild); + + const getTweenChild = (child: ReactElement, props = {}) => { + const key: string | number = child.key as string; + saveTweenTag.current[key] = React.createElement( + TweenOne, + { + ...props, + key, + component: null, + }, + child, + ); + return saveTweenTag.current[key]; + }; + const setClassName = (name: string, isEnter: boolean) => { + let className = name.replace(animatingClassName[isEnter ? 1 : 0], '').trim(); + if (className.indexOf(animatingClassName[isEnter ? 0 : 1]) === -1) { + className = `${className} ${animatingClassName[isEnter ? 0 : 1]}`.trim(); + } + return className; + }; + const changeChildren = (nextChildren: ReactElement[], currentChildren: ReactElement[]) => { + const newChildren: ReactElement[] = mergeChildren(currentChildren, nextChildren); + keysToEnter.current = []; + keysToLeave.current = []; + nextChildren.forEach((c) => { + if (!c) { + return; + } + const key = c.key; + const hasPrev = findChildInChildrenByKey(currentChildren, key); + // 如果当前 key 已存在 saveTweenTag 里,,刷新 child; + if (key && saveTweenTag.current[key]) { + saveTweenTag.current[key] = React.cloneElement(saveTweenTag.current[key], {}, c); + } + if (!hasPrev && key) { + keysToEnter.current.push(key); + } + }); + + currentChildren.forEach((c) => { + if (!c) { + return; + } + const key = c.key; + const hasNext = findChildInChildrenByKey(nextChildren, key); + if (!hasNext && key) { + keysToLeave.current.push(key); + delete saveTweenTag.current[key]; + } + }); + return newChildren; + }; + + const reAnimQueue = () => { + if (!Object.keys(isTween.current).length && animQueue.current.length) { + // 取最后一个继续动画; + const child = changeChildren(animQueue.current[animQueue.current.length - 1], children); + setChild(child); + animQueue.current = []; + } + }; + + const onChange = (animation: IAnimObject, key: string | number | null, type: string, obj: ICallBack) => { + const length = dataToArray(animation).length; + const tag = obj.targets as IObject; + const classIsSvg = typeof tag!.className === 'object' && 'baseVal' in tag!.className; + const isEnter = type === 'enter' || type === 'appear'; + if (key && obj.index === length - 1 && obj.mode === 'onComplete') { + delete isTween.current[key]; + if (classIsSvg) { + tag.className.baseVal = tag.className.baseVal + .replace(animatingClassName[isEnter ? 0 : 1], '') + .trim(); + } else { + tag.className = tag.className.replace(animatingClassName[isEnter ? 0 : 1], '').trim(); + } + if (type === 'enter') { + keysToEnter.current.splice(keysToEnter.current.indexOf(key), 1); + if (!keysToEnter.current.length) { + // enter 不会触发 did update, 手动触发一次; + reAnimQueue(); + } + } else if (type === 'leave') { + keysToLeave.current.splice(keysToLeave.current.indexOf(key), 1); + currentChildren.current = currentChildren.current.filter((child) => key !== child.key); + if (!keysToLeave.current.length) { + const currentChildrenKeys = currentChildren.current.map((item) => item.key); + Object.keys(saveTweenTag.current).forEach(($key) => { + if (currentChildrenKeys.indexOf($key) === -1) { + delete saveTweenTag.current[$key]; + } + }); + + setChild(currentChildren.current); + } + } + const _obj = { key, type }; + onEnd(_obj); + } + }; + const getCoverAnimation = (child: ReactElement, i: number, type: string) => { + let animation: IAnimObject = type === 'leave' ? leaveAnim : enterAnim; + if (type === 'appear') { + const appear = transformArguments(appearBool, child.key, i); + animation = (appear && enterAnim) || null; + } + const animate = transformArguments(animation, child.key, i); + const onChangeCb = (obj: ICallBack) => { + onChange(animate, child.key, type, obj); + }; + const className = + setClassName(child.props.className || '', type === 'enter' || type === 'appear') || ''; + + const p = { + key: child.key, + animation: animate, + onChange: onChangeCb, + resetStyle: resetStyle, + className, + }; + if ( + child.key && + keysToEnter.current.concat(keysToLeave.current).indexOf(child.key) >= 0 || + (!oneEnter.current && animation) + ) { + if (child.key && !saveTweenTag.current[child.key]) { + isTween.current[child.key] = type; + } + } + + const children = getTweenChild(child, p); + return children; + }; + useEffect(() => { + if (oneEnter.current) { + const nextChild = toArrayChildren(props.children); + // 如果还在动画,暂存动画队列里,等前一次动画结束后再启动最后次的更新动画 + if (Object.keys(isTween.current).length && !exclusive) { + animQueue.current.push(nextChild); + } else { + const currentChild = toArrayChildren(currentChildren.current); + setChild(changeChildren(nextChild, currentChild)); + } + } + }, [props.children]); + + useEffect(() => { + oneEnter.current = true; + }, []); + useEffect(() => { + reAnimQueue(); + }); + currentChildren.current = children; + + const childrenToRender = children.map((child: ReactElement, i: number) => { + if (!child || !child.key) { + return child; + } + const { key } = child; + if (keysToLeave.current.indexOf(key) >= 0) { + return getCoverAnimation(child, i, 'leave'); + } else if ( + (keysToEnter.current.indexOf(key) >= 0 || + (isTween.current[key] && keysToLeave.current.indexOf(key) === -1)) && + !(isTween.current[key] === 'enter' && saveTweenTag.current[key]) + ) { + /** + * 1. 在 key 在 enter 里。 + * 2. 出场未结束,触发进场, this.isTween[key] 为 leave, key 在 enter 里。 + * 3. 状态为 enter 且 tweenTag 里有值时,不执行重载动画属性,直接调用 tweenTag 里的。 + */ + return getCoverAnimation(child, i, 'enter'); + } else if (!oneEnter.current) { + return getCoverAnimation(child, i, 'appear'); + } + return saveTweenTag.current[key]; + }); + if (!component) { + return childrenToRender[0] || null; + } + return createElement(component, { ...tagProps, ...componentProps, ref }, childrenToRender); +}); + +TweenOneGroup.displayName = 'TweenOneGroup'; +TweenOneGroup.isTweenOneGroup = true; + +export default TweenOneGroup \ No newline at end of file diff --git a/src/easing.js b/src/easing.js deleted file mode 100644 index 4134c172..00000000 --- a/src/easing.js +++ /dev/null @@ -1,29 +0,0 @@ -import easingTypes from 'tween-functions'; -import { windowIsUndefined, parsePath } from './util'; - -easingTypes.path = (_path, _param) => { - const param = _param || {}; - if (windowIsUndefined) { - return 'linear'; - } - const pathNode = parsePath(_path); - const pathLength = pathNode.getTotalLength(); - const rect = param.rect || 100;// path 的大小,100 * 100, - const lengthPixel = param.lengthPixel || 200; // 线上取点像素,默认分为 200 段。。 - const points = []; - for (let i = 0; i < lengthPixel - 1; i++) { - points.push(pathNode.getPointAtLength((pathLength / (lengthPixel - 1)) * i)); - } - points.push(pathNode.getPointAtLength(lengthPixel)); - return function path(t, b, _c, d) { - const p = easingTypes.linear(t, b, _c, d); - const timePointX = rect * p; // X 轴的百分比; - // 取出 x 轴百分比上的点; - const point = points.filter((item) => - item.x >= timePointX - )[0] || pathNode.getPointAtLength(p * pathLength); - return 1 - (point.y / rect); - }; -}; - -export default easingTypes; diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 948b873c..00000000 --- a/src/index.js +++ /dev/null @@ -1,25 +0,0 @@ -// export this package's api -import TweenOne from './TweenOne'; -import _tween from './Tween'; -import group from './TweenOneGroup'; -import _easing from './easing'; -import _plugins from './plugins'; -import _ticker from './ticker'; - -TweenOne.TweenOneGroup = group; -TweenOne.easing = _easing; -TweenOne.plugins = _plugins; -TweenOne.ticker = _ticker; -TweenOne.Tween = _tween - -export default TweenOne; - -export const TweenOneGroup = group; - -export const easing = _easing; - -export const plugins = _plugins; - -export const ticker = _ticker; - -export const Tween = _tween; \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx new file mode 100644 index 00000000..c9b0152f --- /dev/null +++ b/src/index.tsx @@ -0,0 +1,12 @@ +import TweenOne from './TweenOne'; +import { Ticker, Plugins, Easing } from 'tween-one'; + +export { Easing, Ticker, Plugins }; + +TweenOne.plugins = Plugins; +TweenOne.ticker = Ticker; +TweenOne.easing = Easing; + +export default TweenOne; + +export * from './type'; \ No newline at end of file diff --git a/src/plugin/BezierPlugin.jsx b/src/plugin/BezierPlugin.jsx deleted file mode 100644 index ef2cab1e..00000000 --- a/src/plugin/BezierPlugin.jsx +++ /dev/null @@ -1,531 +0,0 @@ -/* eslint-disable */ -/** - * Created by jljsj on 15/12/22. - * The algorithm is GSAP BezierPlugin VERSION: beta 1.3.4 - */ -import { - checkStyleName, - createMatrix, - getTransform, -} from 'style-utils'; -const _RAD2DEG = 180 / Math.PI; -const _r1 = []; -const _r2 = []; -const _r3 = []; -const _corProps = {}; -const _correlate = ',x,y,z,left,top,right,bottom,marginTop,marginLeft,marginRight,marginBottom,paddingLeft,paddingTop,paddingRight,paddingBottom,backgroundPosition,backgroundPosition_y,'; - -const GsapBezier = { - Segment(a, b, c, d) { - this.a = a; - this.b = b; - this.c = c; - this.d = d; - this.da = d - a; - this.ca = c - a; - this.ba = b - a; - }, - cubicToQuadratic(a, b, c, d) { - const q1 = { a: a }; - const q2 = {}; - const q3 = {}; - const q4 = { c: d }; - const mab = (a + b) / 2; - const mbc = (b + c) / 2; - const mcd = (c + d) / 2; - const mabc = (mab + mbc) / 2; - const mbcd = (mbc + mcd) / 2; - const m8 = (mbcd - mabc) / 8; - q1.b = mab + (a - mab) / 4; - q2.b = mabc + m8; - q1.c = q2.a = (q1.b + q2.b) / 2; - q2.c = q3.a = (mabc + mbcd) / 2; - q3.b = mbcd - m8; - q4.b = mcd + (d - mcd) / 4; - q3.c = q4.a = (q3.b + q4.b) / 2; - return [q1, q2, q3, q4]; - }, - calculateControlPoints(a, curviness, quad, basic, correlate) { - const l = a.length - 1; - let i; - let ii = 0; - let p1; - let p2; - let p3; - let seg; - let m1; - let m2; - let mm; - let cp2; - let qb; - let r1; - let r2; - let tl; - let cp1 = a[0].a; - for (i = 0; i < l; i++) { - seg = a[ii]; - p1 = seg.a; - p2 = seg.d; - p3 = a[ii + 1].d; - - if (correlate) { - r1 = _r1[i]; - r2 = _r2[i]; - tl = ((r2 + r1) * curviness * 0.25) / (basic ? 0.5 : _r3[i] || 0.5); - const _aa = (r1 !== 0 ? tl / r1 : 0); - const _a = (basic ? curviness * 0.5 : _aa); - m1 = p2 - (p2 - p1) * _a; - const bb = (r2 !== 0 ? tl / r2 : 0); - const b = (basic ? curviness * 0.5 : bb); - m2 = p2 + (p3 - p2) * b; - mm = p2 - (m1 + (((m2 - m1) * ((r1 * 3 / (r1 + r2)) + 0.5) / 4) || 0)); - } else { - m1 = p2 - (p2 - p1) * curviness * 0.5; - m2 = p2 + (p3 - p2) * curviness * 0.5; - mm = p2 - (m1 + m2) / 2; - } - m1 += mm; - m2 += mm; - - seg.c = cp2 = m1; - if (i !== 0) { - seg.b = cp1; - } else { - seg.b = cp1 = seg.a + (seg.c - seg.a) * 0.6; - } - - seg.da = p2 - p1; - seg.ca = cp2 - p1; - seg.ba = cp1 - p1; - - if (quad) { - qb = this.cubicToQuadratic(p1, cp1, cp2, p2); - a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]); - ii += 4; - } else { - ii++; - } - - cp1 = m2; - } - seg = a[ii]; - seg.b = cp1; - seg.c = cp1 + (seg.d - cp1) * 0.4; - seg.da = seg.d - seg.a; - seg.ca = seg.c - seg.a; - seg.ba = cp1 - seg.a; - if (quad) { - qb = this.cubicToQuadratic(seg.a, cp1, seg.c, seg.d); - a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]); - } - }, - parseAnchors(_values, p, correlate, prepend) { - const a = []; - let l; - let i; - let p1; - let p2; - let p3; - let tmp; - let values = _values; - if (prepend) { - values = [prepend].concat(values); - i = values.length; - while (--i > -1) { - tmp = values[i][p]; - if (typeof tmp === 'string' && tmp.charAt(1) === '=') { - values[i][p] = prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)); - } - } - } - l = values.length - 2; - if (l < 0) { - a[0] = new this.Segment(values[0][p], 0, 0, values[(l < -1) ? 0 : 1][p]); - return a; - } - for (i = 0; i < l; i++) { - p1 = values[i][p]; - p2 = values[i + 1][p]; - a[i] = new this.Segment(p1, 0, 0, p2); - if (correlate) { - p3 = values[i + 2][p]; - _r1[i] = (_r1[i] || 0) + (p2 - p1) * (p2 - p1); - _r2[i] = (_r2[i] || 0) + (p3 - p2) * (p3 - p2); - } - } - a[i] = new this.Segment(values[i][p], 0, 0, values[i + 1][p]); - return a; - }, - bezierThrough(_values, _curviness, quadratic, basic, __correlate, _prepend) { - let values = _values; - let curviness = _curviness; - let correlate = __correlate; - let prepend = _prepend; - const obj = {}; - const props = []; - const first = prepend || values[0]; - let i; - let p; - let a; - let j; - let r; - let l; - let seamless; - let last; - correlate = (typeof (correlate) === 'string') ? ',' + correlate + ',' : _correlate; - if (curviness === null) { - curviness = 1; - } - Object.keys(values[0]).forEach(key => { - props.push(key); - }); - if (values.length > 1) { - last = values[values.length - 1]; - seamless = true; - i = props.length; - while (--i > -1) { - p = props[i]; - if (Math.abs(first[p] - last[p]) > 0.05) { - seamless = false; - break; - } - } - if (seamless) { - values = values.concat(); - if (prepend) { - values.unshift(prepend); - } - values.push(values[1]); - prepend = values[values.length - 3]; - } - } - _r1.length = _r2.length = _r3.length = 0; - i = props.length; - while (--i > -1) { - p = props[i]; - _corProps[p] = (correlate.indexOf(',' + p + ',') !== -1); - obj[p] = this.parseAnchors(values, p, _corProps[p], prepend); - } - i = _r1.length; - while (--i > -1) { - _r1[i] = Math.sqrt(_r1[i]); - _r2[i] = Math.sqrt(_r2[i]); - } - if (!basic) { - i = props.length; - while (--i > -1) { - if (_corProps[p]) { - a = obj[props[i]]; - l = a.length - 1; - for (j = 0; j < l; j++) { - r = a[j + 1].da / _r2[j] + a[j].da / _r1[j]; - _r3[j] = (_r3[j] || 0) + r * r; - } - } - } - i = _r3.length; - while (--i > -1) { - _r3[i] = Math.sqrt(_r3[i]); - } - } - i = props.length; - j = quadratic ? 4 : 1; - while (--i > -1) { - p = props[i]; - a = obj[p]; - this.calculateControlPoints(a, curviness, quadratic, basic, _corProps[p]); - if (seamless) { - a.splice(0, j); - a.splice(a.length - j, j); - } - } - return obj; - }, - parseBezierData(data) { - const values = data.vars.concat(); - const type = data.type; - const prepend = data.startPoint; - - const obj = {}; - const inc = (type === 'cubic') ? 3 : 2; - const soft = (type === 'soft'); - let a; - let b; - let c; - let d; - let cur; - let l; - let p; - let cnt; - let tmp; - if (soft) { - values.splice(0, 0, prepend); - } - - if (values === null || values.length < inc + 1) { - return console.error('invalid Bezier data');// eslint-disable-line - } - for (let i = 1; i >= 0; i--) { - p = i ? 'x' : 'y'; - obj[p] = cur = []; - cnt = 0; - for (let j = 0; j < values.length; j++) { - tmp = values[j][p]; - const _a = typeof tmp === 'string' && tmp.charAt(1) === '=' ? - prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)) : Number(tmp); - a = (prepend === null) ? values[j][p] : _a; - if (soft && j > 1 && j < values.length - 1) { - cur[cnt++] = (a + cur[cnt - 2]) / 2; - } - cur[cnt++] = a; - } - l = cnt - inc + 1; - cnt = 0; - for (let jj = 0; jj < l; jj += inc) { - a = cur[jj]; - b = cur[jj + 1]; - c = cur[jj + 2]; - d = (inc === 2) ? 0 : cur[jj + 3]; - cur[cnt++] = tmp = (inc === 3) ? new this.Segment(a, b, c, d) : - new this.Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c); - } - cur.length = cnt; - } - return obj; - }, - addCubicLengths(a, steps, resolution) { - const inc = 1 / resolution; - let j = a.length; - let d; - let d1; - let s; - let da; - let ca; - let ba; - let p; - let i; - let inv; - let bez; - let index; - while (--j > -1) { - bez = a[j]; - s = bez.a; - da = bez.d - s; - ca = bez.c - s; - ba = bez.b - s; - d = d1 = 0; - for (i = 1; i <= resolution; i++) { - p = inc * i; - inv = 1 - p; - d = d1 - (d1 = (p * p * da + 3 * inv * (p * ca + inv * ba)) * p); - index = j * resolution + i - 1; - steps[index] = (steps[index] || 0) + d * d; - } - } - }, - parseLengthData(obj, _resolution) { - const resolution = _resolution || 6; - const a = []; - const lengths = []; - const threshold = resolution - 1; - const segments = []; - let d = 0; - let total = 0; - let curLS = []; - Object.keys(obj).forEach((key) => { - this.addCubicLengths(obj[key], a, resolution); - }); - a.forEach((c, i) => { - d += Math.sqrt(c); - let index = i % resolution; - curLS[index] = d; - if (index === threshold) { - total += d; - index = (i / resolution) >> 0; - segments[index] = curLS; - lengths[index] = total; - d = 0; - curLS = []; - } - }); - return { length: total, lengths: lengths, segments: segments }; - }, -}; - -const Bezier = function (target, vars) { - this.vars = this.getDefaultData(vars); - this.target = target; - this.transform = checkStyleName('transform'); -}; -Bezier.prototype = { - name: 'bezier', - useStyle: 'transform', - getDefaultData(obj) { - return { - type: obj.type || 'soft', - autoRotate: obj.autoRotate || false, - vars: obj.vars || {}, - startPoint: null, - }; - }, - init() { - const vars = this.vars; - const autoRotate = vars.autoRotate; - this._timeRes = !vars.timeResolution ? 6 : parseInt(vars.timeResolution, 10); - const a = (autoRotate === true) ? 0 : Number(autoRotate); - const b = (autoRotate instanceof Array) ? autoRotate : [['x', 'y', 'rotation', (a || 0)]]; - this._autoRotate = autoRotate ? b : null; - this._beziers = (vars.type !== 'cubic' && vars.type !== 'quadratic' && vars.type !== 'soft') ? - GsapBezier.bezierThrough(vars.vars, isNaN(vars.curviness) ? 1 : vars.curviness, - false, (vars.type === 'thruBasic'), vars.correlate, vars.startPoint) : - GsapBezier.parseBezierData(vars); - this._segCount = this._beziers.x.length; - if (this._timeRes) { - const ld = GsapBezier.parseLengthData(this._beziers, this._timeRes); - this._length = ld.length; - this._lengths = ld.lengths; - this._segments = ld.segments; - this._l1 = this._li = this._s1 = this._si = 0; - this._l2 = this._lengths[0]; - this._curSeg = this._segments[0]; - this._s2 = this._curSeg[0]; - this._prec = 1 / this._curSeg.length; - } - }, - set(v) { - const segments = this._segCount; - const XYobj = {}; - let curIndex; - let inv; - let i; - let p; - let b; - let t; - let val; - let l; - let lengths; - let curSeg; - let value; - let rotate; - if (!this._timeRes) { - const _cur = (v >= 1) ? segments - 1 : (segments * v) >> 0; - curIndex = (v < 0) ? 0 : _cur; - t = (v - (curIndex * (1 / segments))) * segments; - } else { - lengths = this._lengths; - curSeg = this._curSeg; - value = v * this._length; - i = this._li; - if (value > this._l2 && i < segments - 1) { - l = segments - 1; - while (i < l && (this._l2 = lengths[++i]) <= value) { } - this._l1 = lengths[i - 1]; - this._li = i; - this._curSeg = curSeg = this._segments[i]; - this._s2 = curSeg[(this._s1 = this._si = 0)]; - } else if (value < this._l1 && i > 0) { - while (i > 0 && (this._l1 = lengths[--i]) >= value) { } - if (i === 0 && value < this._l1) { - this._l1 = 0; - } else { - i++; - } - this._l2 = lengths[i]; - this._li = i; - this._curSeg = curSeg = this._segments[i]; - this._s1 = curSeg[(this._si = curSeg.length - 1) - 1] || 0; - this._s2 = curSeg[this._si]; - } - curIndex = i; - value -= this._l1; - i = this._si; - if (value > this._s2 && i < curSeg.length - 1) { - l = curSeg.length - 1; - while (i < l && (this._s2 = curSeg[++i]) <= value) { } - this._s1 = curSeg[i - 1]; - this._si = i; - } else if (value < this._s1 && i > 0) { - while (i > 0 && (this._s1 = curSeg[--i]) >= value) { } - if (i === 0 && value < this._s1) { - this._s1 = 0; - } else { - i++; - } - this._s2 = curSeg[i]; - this._si = i; - } - t = ((i + (value - this._s1) / (this._s2 - this._s1)) * this._prec) || 0; - } - inv = 1 - t; - for (i = 1; i >= 0; i--) { - p = i ? 'x' : 'y'; - b = this._beziers[p][curIndex]; - val = (t * t * b.da + 3 * inv * (t * b.ca + inv * b.ba)) * t + b.a; - XYobj[p] = val; - } - if (this._autoRotate) { - const ar = this._autoRotate; - let b2; - let x1; - let y1; - let x2; - let y2; - let add; - let conv; - i = ar.length; - while (--i > -1) { - p = ar[i][2]; - add = ar[i][3] || 0; - conv = (ar[i][4] === true) ? 1 : _RAD2DEG; - b = this._beziers[ar[i][0]]; - b2 = this._beziers[ar[i][1]]; - - if (b && b2) { - b = b[curIndex]; - b2 = b2[curIndex]; - - x1 = b.a + (b.b - b.a) * t; - x2 = b.b + (b.c - b.b) * t; - x1 += (x2 - x1) * t; - x2 += ((b.c + (b.d - b.c) * t) - x2) * t; - - y1 = b2.a + (b2.b - b2.a) * t; - y2 = b2.b + (b2.c - b2.b) * t; - y1 += (y2 - y1) * t; - y2 += ((b2.c + (b2.d - b2.c) * t) - y2) * t; - const _r = Math.atan2(y2 - y1, x2 - x1) * conv; - rotate = _r + add; - } - } - } - return rotate ? 'translate(' + XYobj.x + 'px,' + XYobj.y + 'px) rotate(' + rotate + 'deg)' : 'translate(' + XYobj.x + 'px,' + XYobj.y + 'px)'; - }, - getAnimStart(computedStyle, isSvg) { - let transform = computedStyle[isSvg ? 'transformSVG' : this.transform]; - transform = transform === 'none' ? '' : transform; - const matrix = createMatrix(transform); - // this.startRotate = parseFloat((-Math.atan2(matrix.m21, matrix.m11) * _RAD2DEG).toFixed(2)); - this.vars.startPoint = { x: matrix.e, y: matrix.f }; - this.init(); - }, - setRatio(r, t, computedStyle) { - const transform = getTransform(this.set(r)); - // 只覆盖 3 个属性; - t.style.transform = { - ...t.style.transform, - translateX: transform.translateX, - translateY: transform.translateY, - rotate: transform.rotate, - }; - if (computedStyle) { - computedStyle.transformSVG = createMatrix(t.style.transform).toString(); - } - }, -}; -Bezier.bezierThrough = GsapBezier.bezierThrough; -Bezier.cubicToQuadratic = GsapBezier.cubicToQuadratic; -Bezier.quadraticToCubic = (a, b, c) => { - return new GsapBezier.Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c); -}; - -export default Bezier; diff --git a/src/plugin/ChildrenPlugin.jsx b/src/plugin/ChildrenPlugin.jsx deleted file mode 100644 index b57b7a57..00000000 --- a/src/plugin/ChildrenPlugin.jsx +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable func-names */ - -const ChildrenPlugin = function (target, vars) { - this.target = target; - this.vars = vars; -}; - -ChildrenPlugin.prototype = { - name: 'Children', - getAnimStart() { - const { formatMoney } = this.vars; - const opts = { - thousand: formatMoney && formatMoney.thousand || ',', - decimal: formatMoney && formatMoney.decimal || '.', - }; - const rep = new RegExp(`\\${opts.thousand}`, 'g'); - this.start = this.vars.startAt || { - value: parseFloat(this.target.innerHTML.replace(rep, '').replace(opts.decimal, '.')) || 0 - }; - }, - toMoney(v, _opts) { - const opts = { - thousand: _opts.thousand || ',', - decimal: _opts.decimal || '.', - }; - const negative = parseFloat(v) < 0 ? '-' : ''; - const numberArray = v.toString().split('.'); - const base = Math.abs(parseInt(numberArray[0], 10)).toString(); - const mod = base.length > 3 ? base.length % 3 : 0; - const decimal = numberArray[1]; - return `${negative}${mod ? `${base.substr(0, mod)}${opts.thousand}` : ''}${ - base.substr(mod).replace(/(\d{3})(?=\d)/g, `$1${opts.thousand}`)}${ - decimal ? `${opts.decimal}${decimal}` : '' - }`; - }, - setRatio(ratio) { - const { value, floatLength, formatMoney } = this.vars; - let v = (value - this.start.value) * ratio + this.start.value; - if (typeof floatLength === 'number') { - if (floatLength) { - v = v.toFixed(floatLength); - const numberArray = v.toString().split('.'); - let decimal = numberArray[1] || ''; - decimal = decimal.length > floatLength ? decimal.substring(0, floatLength) : decimal; - const l = floatLength - decimal.length; - if (l) { - Array(l).fill(0).forEach(num => { - decimal += `${num}`; - }); - } - v = `${numberArray[0]}.${decimal}`; - } else { - v = Math.round(v); - } - } - v = formatMoney ? this.toMoney(v, formatMoney) : v; - this.target.innerHTML = v; - }, -}; - -export default ChildrenPlugin; diff --git a/src/plugin/ChildrenPlugin.ts b/src/plugin/ChildrenPlugin.ts new file mode 100644 index 00000000..ced7f6fe --- /dev/null +++ b/src/plugin/ChildrenPlugin.ts @@ -0,0 +1,85 @@ + +interface IFormatMoney { + thousand?: string; + decimal?: string; +} +interface IVars { + value: number; + floatLength: number; + formatMoney?: IFormatMoney; +} + +class ChildrenPlugin { + static key: string = 'innerHTML'; + static className: string = 'Children'; + start?: IVars; + startAt?: IObject; + target?: HTMLElement; + constructor(public vars: IVars, public key: string) { + this.vars = vars; + this.key = key; + } + getAnimStart = () => { + const { target, vars, startAt, key } = this; + const { formatMoney } = vars; + const opts = { + thousand: (formatMoney && formatMoney.thousand) || ',', + decimal: (formatMoney && formatMoney.decimal) || '.', + }; + const rep = new RegExp(`\\${opts.thousand}`, 'g'); + + this.start = startAt![key] || { + value: + parseFloat( + this.target!.innerHTML.replace(rep, '').replace(opts.decimal, '.'), + ) || 0, + }; + return this.start; + }; + toMoney = (v: string, _opts: IFormatMoney) => { + const opts = { + thousand: _opts.thousand || ',', + decimal: _opts.decimal || '.', + }; + const negative = parseFloat(v) < 0 ? '-' : ''; + const numberArray = v.split('.'); + const base = Math.abs(parseInt(numberArray[0], 10)).toString(); + const mod = base.length > 3 ? base.length % 3 : 0; + const decimal = numberArray[1]; + return `${negative}${ + mod ? `${base.substr(0, mod)}${opts.thousand}` : '' + }${base.substr(mod).replace(/(\d{3})(?=\d)/g, `$1${opts.thousand}`)}${ + decimal ? `${opts.decimal}${decimal}` : '' + }`; + }; + render = (ratio: number) => { + const { value, floatLength, formatMoney } = this.vars; + let v: number | string = (value - this.start!.value) * ratio + this.start!.value; + if (typeof floatLength === 'number') { + if (floatLength) { + v = v.toFixed(floatLength); + const numberArray = v.toString().split('.'); + let decimal = numberArray[1] || ''; + decimal = + decimal.length > floatLength + ? decimal.substring(0, floatLength) + : decimal; + const l = floatLength - decimal.length; + if (l) { + Array(l) + .fill(0) + .forEach((num) => { + decimal += `${num}`; + }); + } + v = `${numberArray[0]}.${decimal}`; + } else { + v = Math.round(v); + } + } + v = formatMoney ? this.toMoney(`${v}`, formatMoney) : v; + return v + }; +} + +export default ChildrenPlugin; diff --git a/src/plugin/PathMotionPlugin.ts b/src/plugin/PathMotionPlugin.ts new file mode 100644 index 00000000..bb3021ae --- /dev/null +++ b/src/plugin/PathMotionPlugin.ts @@ -0,0 +1,3 @@ +import PathMotionPlugin from 'tween-one/src/plugins/PathMotionPlugin'; + +export default PathMotionPlugin; diff --git a/src/plugin/PathPlugin.jsx b/src/plugin/PathPlugin.jsx deleted file mode 100644 index ebbbc786..00000000 --- a/src/plugin/PathPlugin.jsx +++ /dev/null @@ -1,53 +0,0 @@ -import { - checkStyleName, - getTransform, - createMatrix, -} from 'style-utils'; -import { windowIsUndefined, parsePath, getTransformValue } from '../util'; - -function PathPlugin(target, vars) { - this.target = target; - const path = typeof vars === 'string' ? vars : vars.x || vars.y || vars.rotate; - this.vars = vars; - this.path = windowIsUndefined ? null : parsePath(path); - this.start = {}; - this.pathLength = this.path ? this.path.getTotalLength() : 0; -} - -PathPlugin.prototype = { - name: 'path', - useStyle: 'transform', - getPoint(offset) { - const o = offset || 0; - const p = this.pathLength * this.progress + o; - return this.path ? this.path.getPointAtLength(p) : 0; - }, - getAnimStart(computedStyle, isSvg) { - const transform = getTransform(computedStyle[isSvg ? - 'transformSVG' : checkStyleName('transform')]); - this.start = transform; - this.data = { ...transform }; - }, - setRatio(r, t, computedStyle) { - this.progress = r; - const p = this.getPoint(); - const p0 = this.getPoint(-1); - const p1 = this.getPoint(1); - if (typeof this.vars === 'string') { - this.data.translateX = p.x + this.start.translateX; - this.data.translateY = p.y + this.start.translateY; - this.data.rotate = Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI; - } else { - this.data.translateX = this.vars.x ? p.x + this.start.translateX : this.data.translateX; - this.data.translateY = this.vars.y ? p.y + this.start.translateY : this.data.translateY; - this.data.rotate = this.vars.rotate ? - Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI : this.data.rotate; - } - t.style.transform = getTransformValue(this.data); - if (computedStyle) { - computedStyle.transformSVG = createMatrix(t.style.transform).toString(); - } - }, -}; - -export default PathPlugin; diff --git a/src/plugin/StylePlugin.jsx b/src/plugin/StylePlugin.jsx deleted file mode 100644 index 43d92b94..00000000 --- a/src/plugin/StylePlugin.jsx +++ /dev/null @@ -1,318 +0,0 @@ -/* eslint-disable func-names, no-console */ -import { - cssList, - checkStyleName, - getGsapType, - parseShadow, - getColor, - parseColor, - isTransform, - isConvert, - splitFilterToObject, - getTransform, - stylesToCss, - createMatrix, -} from 'style-utils'; -import { startConvertToEndUnit, getTransformValue, styleValueToArray } from '../util.js'; -import _plugin from '../plugins'; - -const StylePlugin = function (target, vars, type) { - this.target = target; - this.vars = vars; - this.type = type; - this.propsData = {}; - this.setDefaultData(); -}; -StylePlugin.prototype = { - name: 'style', -}; -const p = StylePlugin.prototype; -p.getTweenData = function (key, $vars) { - const data = { - data: {}, - dataType: {}, - dataUnit: {}, - dataCount: {}, - dataSplitStr: {}, - }; - let vars = $vars; - if (styleValueToArray[key]) { - vars = vars.toString().split(' '); - vars = vars.map(c => (typeof $vars === 'number' ? `${c}px` : c)); - vars[1] = vars[1] || vars[0]; - vars[2] = vars[2] || vars[0]; - vars[3] = vars[3] || vars[1] || vars[0]; - vars = vars.join(' '); - } - if (key.match(/colo|fill|storker/i)) { - data.data[key] = parseColor(vars); - data.dataType[key] = 'color'; - } else if (key === 'strokeDasharray') { - data.data[key] = vars.split(','); - data.dataType[key] = 'strokeDasharray'; - } else if (key.match(/shadow/i)) { - data.data[key] = parseShadow(vars); - data.dataType[key] = 'shadow'; - } else if (typeof vars === 'string' && vars.split(/[\s|,]/).length > 1) { - data.data[key] = vars.split(/[\s|,]/); - data.dataSplitStr[key] = vars.replace(/[^\s|,]/g, '').replace(/\s+/g, ' '); - data.dataType[key] = 'string'; - } else { - data.data[key] = vars; - data.dataType[key] = 'other'; - } - if (Array.isArray(data.data[key])) { - data.dataUnit[key] = data.data[key] - .map(_item => _item.toString().replace(/[^a-z|%]/g, '')); - data.dataCount[key] = data.data[key] - .map(_item => _item.toString().replace(/[^+|=|-]/g, '')); - - data.data[key] = data.data[key].map(_item => - !parseFloat(_item) && parseFloat(_item) !== 0 ? _item : parseFloat(_item) - ); - } else { - data.dataUnit[key] = data.data[key].toString().replace(/[^a-z|%]/g, ''); - data.dataCount[key] = data.data[key].toString().replace(/[^+|=|-]/g, ''); - const d = parseFloat(data.data[key].toString().replace(/[a-z|%|=]/g, '')); - data.data[key] = !d && d !== 0 ? data.data[key] : d; - } - return data; -}; -p.setDefaultData = function () { - this.propsData.data = {}; - this.propsData.dataType = {}; - this.propsData.dataUnit = {}; - this.propsData.dataCount = {}; - this.propsData.dataSplitStr = {}; - Object.keys(this.vars).forEach(_key => { - if (_key in _plugin) { - this.propsData.data[_key] = new _plugin[_key](this.target, this.vars[_key]); - return; - } - const key = getGsapType(_key); - const _data = this.getTweenData(key, this.vars[_key]); - this.propsData.data[key] = _data.data[key]; - this.propsData.dataType[key] = _data.dataType[key]; - this.propsData.dataUnit[key] = _data.dataUnit[key]; - this.propsData.dataCount[key] = _data.dataCount[key]; - if (_data.dataSplitStr[key]) { - this.propsData.dataSplitStr[key] = _data.dataSplitStr[key]; - } - }); -}; -p.convertToMarksArray = function (computedStyle, unit, key, data, i) { - const startUnit = data.toString().replace(/[^a-z|%]/g, ''); - const endUnit = unit[i]; - if (startUnit === endUnit) { - return parseFloat(data); - } else if (!parseFloat(data) && parseFloat(data) !== 0) { - return data; - } - return startConvertToEndUnit(this.target, computedStyle, key, data, - startUnit, endUnit, null, key === 'transformOrigin' && !i); -}; -p.getAnimStart = function (computedStyle, tween, isSvg) { - const style = {}; - const tweenStyle = tween.style || {}; - let transform; - Object.keys(this.propsData.data).forEach(key => { - const cssName = isConvert(key); - let startData = tweenStyle[cssName] || computedStyle[cssName]; - const fixed = computedStyle.position === 'fixed'; - if (!startData || startData === 'none' || startData === 'auto') { - startData = ''; - } - let endUnit; - let startUnit; - if (key in _plugin) { - if (key === 'bezier') { - this.transform = checkStyleName('transform'); - startData = computedStyle[isSvg ? 'transformSVG' : this.transform]; - transform = transform || (tweenStyle.transform ? { ...tweenStyle.transform } : - style.transform || getTransform(startData)); - style.transform = transform; - } - this.propsData.data[key].getAnimStart(computedStyle, isSvg); - } else if (cssName === 'transform') { - this.transform = checkStyleName('transform'); - startData = computedStyle[isSvg ? 'transformSVG' : this.transform]; - endUnit = this.propsData.dataUnit[key]; - transform = transform || (tweenStyle.transform ? { ...tweenStyle.transform } : - style.transform || getTransform(startData)); - const unitReg = /%|vw|vh|em|rem/i; - if (endUnit && endUnit.match(unitReg)) { - transform[key] = transform[key] && transform[key].toString().match(unitReg) ? - parseFloat(transform[key]) - : startConvertToEndUnit(this.target, computedStyle, - key, transform[key], null, endUnit); - } - style.transform = transform; - } else if (cssName === 'filter') { - if (tweenStyle[cssName]) { - startData = tweenStyle[cssName]; - } else { - this.filterName = checkStyleName('filter') || 'filter'; - startData = computedStyle[this.filterName]; - this.filterObject = { ...this.filterObject, ...splitFilterToObject(startData) }; - startData = this.filterObject[key] || 0; - } - startUnit = startData.toString().replace(/[^a-z|%]/g, ''); - endUnit = this.propsData.dataUnit[key]; - if (endUnit !== startUnit) { - startData = startConvertToEndUnit(this.target, computedStyle, cssName, - parseFloat(startData), startUnit, endUnit, fixed); - } - style[key] = parseFloat(startData); - } else if (key.match(/color|fill/i) || key === 'stroke') { - startData = !startData && key === 'stroke' ? 'rgba(255, 255, 255, 0)' : startData; - style[cssName] = parseColor(startData); - } else if (key.match(/shadow/i)) { - startData = parseShadow(startData); - endUnit = this.propsData.dataUnit[key]; - startData = startData.map(this.convertToMarksArray.bind(this, computedStyle, endUnit, key)); - style[cssName] = startData; - } else if (Array.isArray(this.propsData.data[key])) { - startData = startData.split(/[\s|,]/).filter(c => (c || c === 0)); - endUnit = this.propsData.dataUnit[key]; - startData = startData.map(this.convertToMarksArray.bind(this, computedStyle, endUnit, key)); - style[cssName] = startData; - } else { - // 计算单位 - endUnit = this.propsData.dataUnit[cssName]; - startUnit = startData.toString().replace(/[^a-z|%]/g, ''); - if (endUnit !== startUnit) { - startData = startConvertToEndUnit(this.target, computedStyle, cssName, - parseFloat(startData), startUnit, endUnit, fixed); - } - style[cssName] = parseFloat(startData || 0); - } - }); - this.start = style; - return style; -}; -p.setArrayRatio = function (ratio, start, vars, unit, type) { - if (type === 'color' && start.length === 4 && vars.length === 3) { - vars[3] = 1; - } - const startInset = start.indexOf('inset') >= 0; - const endInset = vars.indexOf('inset') >= 0; - if (startInset && !endInset || endInset && !startInset) { - throw console.error('Error: "box-shadow" inset have to exist'); - } - const length = endInset ? 9 : 8; - if (start.length === length && vars.length === length - 1) { - vars.splice(3, 0, 0); - unit.splice(3, 0, ''); - } else if (vars.length === length && start.length === length - 1) { - start.splice(3, 0, 0); - } - const _vars = vars.map((endData, i) => { - const startIsAlpha = type === 'color' && i === 3 && !start[i] ? 1 : 0; - const startData = typeof start[i] === 'number' ? start[i] : startIsAlpha; - if (typeof endData === 'string') { - return endData; - } - return (endData - startData) * ratio + startData + (unit[i] || 0); - }); - if (type === 'color') { - return getColor(_vars); - } else if (type === 'shadow') { - const l = _vars.length === length ? 4 : 3; - const s = _vars.slice(0, l).map(item => { - if (typeof item === 'number') { - return `${item}px`; - } - return item; - }); - const c = _vars.slice(l, endInset ? _vars.length - 1 : _vars.length); - const color = getColor(c); - return `${s.join(' ')} ${color} ${endInset ? 'inset' : ''}`.trim(); - } - return _vars; -}; - -p.setRatio = function (ratio, tween, computedStyle) { - tween.style = tween.style || {}; - if (this.start.transform) { - tween.style.transform = tween.style.transform || { ...this.start.transform }; - } - const style = this.target.style; - Object.keys(this.propsData.data).forEach(key => { - const _isTransform = isTransform(key) === 'transform'; - let startVars = _isTransform ? this.start.transform[key] : this.start[key]; - const endVars = this.propsData.data[key]; - let unit = this.propsData.dataUnit[key]; - const count = this.propsData.dataCount[key]; - if (key in _plugin) { - this.propsData.data[key].setRatio(ratio, tween, computedStyle); - if (key === 'bezier') { - style[this.transform] = getTransformValue(tween.style.transform); - } else { - Object.keys(tween.style).forEach(css => { - style[css] = tween.style[css]; - }); - } - return; - } else if (_isTransform) { - if (unit && unit.match(/%|vw|vh|em|rem/i)) { - startVars = parseFloat(this.start.transform[key]); - if (count.charAt(1) === '=') { - tween.style.transform[key] = (startVars + endVars * ratio) + unit; - } else { - tween.style.transform[key] = ((endVars - startVars) * ratio + startVars) + unit; - } - } else if (key === 'scale') { - const xStart = this.start.transform.scaleX; - const yStart = this.start.transform.scaleY; - if (count.charAt(1) === '=') { - tween.style.transform.scaleX = xStart + endVars * ratio; - tween.style.transform.scaleY = yStart + endVars * ratio; - } else { - tween.style.transform.scaleX = (endVars - xStart) * ratio + xStart; - tween.style.transform.scaleY = (endVars - yStart) * ratio + yStart; - } - } else if (count.charAt(1) === '=') { - tween.style.transform[key] = startVars + endVars * ratio; - } else { - tween.style.transform[key] = (endVars - startVars) * ratio + startVars; - } - style[this.transform] = getTransformValue(tween.style.transform); - if (computedStyle) { - computedStyle.transformSVG = createMatrix(style[this.transform]).toString(); - } - return; - } else if (Array.isArray(endVars)) { - const _type = this.propsData.dataType[key]; - tween.style[key] = this.setArrayRatio(ratio, startVars, endVars, unit, _type); - if (_type === 'string') { - tween.style[key] = tween.style[key].join(this.propsData.dataSplitStr[key]); - } - } else { - let styleUnit = stylesToCss(key, 0); - styleUnit = typeof styleUnit === 'number' ? '' : styleUnit.replace(/[^a-z|%]/g, ''); - unit = unit || (cssList.filter.indexOf(key) >= 0 ? '' : styleUnit); - if (typeof endVars === 'string') { - tween.style[key] = endVars; - } else if (count.charAt(1) === '=') { - tween.style[key] = startVars + endVars * ratio + unit; - } else { - const value = (endVars - startVars) * ratio + startVars; - tween.style[key] = unit ? `${value}${unit}` : value; - } - } - if (cssList.filter.indexOf(key) >= 0) { - if (!this.filterObject) { - return; - } - this.filterObject[key] = tween.style[key]; - let filterStyle = ''; - Object.keys(this.filterObject).forEach(filterKey => { - filterStyle += ` ${filterKey}(${this.filterObject[filterKey]})`; - }); - style[this.filterName] = filterStyle.trim(); - return; - } - style[key] = tween.style[key]; - }); -}; -export default StylePlugin; diff --git a/src/plugin/SvgDrawPlugin.jsx b/src/plugin/SvgDrawPlugin.jsx deleted file mode 100644 index 25223805..00000000 --- a/src/plugin/SvgDrawPlugin.jsx +++ /dev/null @@ -1,112 +0,0 @@ -/* eslint-disable func-names */ -const SvgDrawPlugin = function (target, vars) { - this.target = target; - this.vars = vars; - this.start = {}; - this.tagName = this.target.tagName.toLowerCase(); -}; -SvgDrawPlugin.prototype = { - name: 'SVGDraw', - useStyle: 'stroke-dasharray, stroke-dashoffset', - setVars(vars) { - const _vars = { start: 0 }; - if (typeof vars === 'number') { - _vars.end = vars; - return _vars; - } - const data = vars.split(' '); - if (data.length > 1) { - _vars.start = data[0].indexOf('%') >= 0 ? - parseFloat(data[0]) / 100 * this.length : parseFloat(data[0]); - _vars.end = data[1].indexOf('%') >= 0 ? - parseFloat(data[1]) / 100 * this.length : parseFloat(data[1]); - } else if (parseFloat(vars)) { - _vars.end = vars.indexOf('%') >= 0 ? - parseFloat(vars) / 100 * this.length : parseFloat(vars); - } else { - throw new Error(`SVGDraw data[${vars}] error.`); - } - return _vars; - }, - getLineLength(x1, y1, x2, y2) { - const _x2 = parseFloat(x2) - parseFloat(x1); - const _y2 = parseFloat(y2) - parseFloat(y1); - return Math.sqrt(_x2 * _x2 + _y2 * _y2); - }, - getPolyLength(name) { - // .match(/(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/gi) - const pointsArray = []; - (this.target.getAttribute('points') || '').split(/[\s+|,]/) - .forEach((item, i) => { - const arr = pointsArray[Math.floor(i / 2)] || []; - arr.push(parseFloat(item)); - if (!(i % 2)) { - pointsArray.push(arr); - } - }); - if (name === 'polygon') { - pointsArray.push(pointsArray[0]); - } - let length = 0; - pointsArray.forEach((item, i) => { - if (i < pointsArray.length - 1) { - const nextPoint = pointsArray[i + 1]; - length += this.getLineLength(item[0], item[1], nextPoint[0], nextPoint[1]); - } - }); - return length; - }, - getEllipseLength() { - const rx = parseFloat(this.target.getAttribute('rx')); - const ry = parseFloat(this.target.getAttribute('ry')); - if (!rx || !ry) { - throw new Error(`ellipse rx or ry error.`); - } - return Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (3 * ry + rx))); - }, - getAnimStart(computedStyle) { - if (Object.keys(this.start).length) { - return; - } - const getAttribute = (str) => (this.target.getAttribute(str)); - switch (this.tagName) { - case 'circle': - this.length = Math.PI * 2 * getAttribute('r'); - break; - case 'line': - this.length = this.getLineLength(getAttribute('x1'), - getAttribute('y1'), getAttribute('x2'), - getAttribute('y2')); - break; - case 'polyline': - case 'polygon': - this.length = this.getPolyLength(this.tagName); - break; - case 'ellipse': - this.length = this.getEllipseLength(); - break; - case 'rect': - this.length = getAttribute('width') * 2 + getAttribute('height') * 2; - break; - case 'path': - this.length = this.target.getTotalLength(); - break; - default: - throw new Error('The label is not a label in the SVG.'); - } - this.length = parseFloat(this.length.toFixed(3)); - this.start.strokeDasharray = computedStyle.strokeDasharray === 'none' || - !computedStyle.strokeDasharray ? '100% 100%' : computedStyle.strokeDasharray; - this.start.strokeDashoffset = parseFloat(computedStyle.strokeDashoffset); - this.start.strokeDasharray = this.setVars(this.start.strokeDasharray); - this.vars = this.setVars(this.vars); - }, - setRatio(r, t) { - t.style.strokeDasharray = `${(this.vars.end - this.vars.start - - this.start.strokeDasharray.start) * r + - this.start.strokeDasharray.start}px, ${this.length}px`; - t.style.strokeDashoffset = -((this.vars.start + this.start.strokeDashoffset) * r - - this.start.strokeDashoffset); - }, -}; -export default SvgDrawPlugin; diff --git a/src/plugin/SvgDrawPlugin.ts b/src/plugin/SvgDrawPlugin.ts new file mode 100644 index 00000000..36a36e8f --- /dev/null +++ b/src/plugin/SvgDrawPlugin.ts @@ -0,0 +1,3 @@ +import SvgDrawPlugin from 'tween-one/src/plugins/SvgDrawPlugin'; + +export default SvgDrawPlugin; \ No newline at end of file diff --git a/src/plugin/SvgMorphPlugin.jsx b/src/plugin/SvgMorphPlugin.jsx deleted file mode 100644 index 9f8341be..00000000 --- a/src/plugin/SvgMorphPlugin.jsx +++ /dev/null @@ -1,68 +0,0 @@ -/* eslint-disable func-names */ -import { path2curve } from './snapsvglite'; - -const SvgPlugin = function (target, vars, key) { - this.target = target; - this.vars = vars; - this.key = key; - this.propsData = {}; -}; -SvgPlugin.prototype = { - name: 'SVGMorph', -}; -const p = SvgPlugin.prototype; -p.getPointVars = function (d) { - return d.split(/\s+/).map(item => item.split(',').map(_item => parseFloat(_item))); -}; -p.polygonPoints = function (start, end) { - const startArray = this.getPointVars(start); - const endArray = this.getPointVars(end); - if (startArray.length !== endArray.length) { - const long = startArray.length > endArray.length ? startArray : endArray; - const short = long === startArray ? endArray : startArray; - for (let i = short.length; i < long.length; i++) { - short[i] = short[short.length - 1]; - } - return startArray.length > endArray.length ? [long, short] : [short, long]; - } - return [startArray, endArray]; -}; -p.getAnimStart = function () { - this.start = this.target.getAttribute ? this.target.getAttribute(this.key) : this.target[this.key]; - if (this.key === 'd') { - this.pathArray = path2curve(this.start, this.vars); - } else { - this.pathArray = this.polygonPoints(this.start, this.vars); - } - return this.pathArray; -}; -p.setArrayRatio = function (ratio, start, item, i) { - if (typeof item === 'string') { - return item; - } - const startData = start[i]; - return (item - startData) * ratio + startData; -}; -p.setRatio = function (ratio, tween) { - const start = this.pathArray[0]; - const end = this.pathArray[1]; - tween[this.key] = end.map((item, i) => { - const startData = start[i]; - const t = item.map(this.setArrayRatio.bind(this, ratio, startData)); - const name = t[0]; - if (this.key === 'd') { - t.shift(); - } - return this.key === 'd' ? `${name}${t.join(',')}` : t.join(','); - }); - let vars = ratio === 1 ? this.vars : tween[this.key].join(' '); - vars = ratio === 0 ? this.start : vars; - if (vars) { - if (this.target.setAttribute) { - this.target.setAttribute(this.key, vars); - } else { - this.target[this.key] = vars; - } - } -}; -export default SvgPlugin; diff --git a/src/plugin/SvgMorphPlugin.ts b/src/plugin/SvgMorphPlugin.ts new file mode 100644 index 00000000..01b46c8c --- /dev/null +++ b/src/plugin/SvgMorphPlugin.ts @@ -0,0 +1,3 @@ +import SvgMorph from 'tween-one/src/plugins/SvgMorphPlugin'; + +export default SvgMorph; \ No newline at end of file diff --git a/src/plugin/snapsvglite.js b/src/plugin/snapsvglite.js deleted file mode 100644 index d6e6bb4d..00000000 --- a/src/plugin/snapsvglite.js +++ /dev/null @@ -1,483 +0,0 @@ -/* eslint-disable */ - -/* - * Useful things from Adobe's Snap.svg adopted to the library needs - * source: https://github.com/alexk111/SVG-Morpheus - */ -/* - * Paths - */ - -var spaces = "\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029"; -var pathCommand = new RegExp("([a-z])[" + spaces + ",]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[" + spaces + "]*,?[" + spaces + "]*)+)", "ig"); -var pathValues = new RegExp("(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[" + spaces + "]*,?[" + spaces + "]*", "ig"); - -// Parses given path string into an array of arrays of path segments -var parsePathString = function(pathString) { - if (!pathString) { - return null; - } - - if (typeof pathString === typeof []) { - return pathString; - } else { - var paramCounts = { a: 7, c: 6, o: 2, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, u: 3, z: 0 }, - data = []; - - String(pathString).replace(pathCommand, function(a, b, c) { - var params = [], - name = b.toLowerCase(); - c.replace(pathValues, function(a, b) { - b && params.push(+b); - }); - if (name == "m" && params.length > 2) { - data.push([b].concat(params.splice(0, 2))); - name = "l"; - b = b == "m" ? "l" : "L"; - } - if (name == "o" && params.length == 1) { - data.push([b, params[0]]); - } - if (name == "r") { - data.push([b].concat(params)); - } else while (params.length >= paramCounts[name]) { - data.push([b].concat(params.splice(0, paramCounts[name]))); - if (!paramCounts[name]) { - break; - } - } - }); - - return data; - } -}; - - -// http://schepers.cc/getting-to-the-point -var catmullRom2bezier = function(crp, z) { - var d = []; - for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { - var p = [ - { x: +crp[i - 2], y: +crp[i - 1] }, - { x: +crp[i], y: +crp[i + 1] }, - { x: +crp[i + 2], y: +crp[i + 3] }, - { x: +crp[i + 4], y: +crp[i + 5] } - ]; - if (z) { - if (!i) { - p[0] = { x: +crp[iLen - 2], y: +crp[iLen - 1] }; - } else if (iLen - 4 == i) { - p[3] = { x: +crp[0], y: +crp[1] }; - } else if (iLen - 2 == i) { - p[2] = { x: +crp[0], y: +crp[1] }; - p[3] = { x: +crp[2], y: +crp[3] }; - } - } else { - if (iLen - 4 == i) { - p[3] = p[2]; - } else if (!i) { - p[0] = { x: +crp[i], y: +crp[i + 1] }; - } - } - d.push(["C", - (-p[0].x + 6 * p[1].x + p[2].x) / 6, - (-p[0].y + 6 * p[1].y + p[2].y) / 6, - (p[1].x + 6 * p[2].x - p[3].x) / 6, - (p[1].y + 6 * p[2].y - p[3].y) / 6, - p[2].x, - p[2].y - ]); - } - - return d; - -}; - -var ellipsePath = function(x, y, rx, ry, a) { - if (a == null && ry == null) { - ry = rx; - } - x = +x; - y = +y; - rx = +rx; - ry = +ry; - if (a != null) { - var rad = Math.PI / 180, - x1 = x + rx * Math.cos(-ry * rad), - x2 = x + rx * Math.cos(-a * rad), - y1 = y + rx * Math.sin(-ry * rad), - y2 = y + rx * Math.sin(-a * rad), - res = [["M", x1, y1], ["A", rx, rx, 0, +(a - ry > 180), 0, x2, y2]]; - } else { - res = [ - ["M", x, y], - ["m", 0, -ry], - ["a", rx, ry, 0, 1, 1, 0, 2 * ry], - ["a", rx, ry, 0, 1, 1, 0, -2 * ry], - ["z"] - ]; - } - return res; -}; - -var pathToAbsolute = function(pathArray) { - pathArray = parsePathString(pathArray); - - if (!pathArray || !pathArray.length) { - return [["M", 0, 0]]; - } - var res = [], - x = 0, - y = 0, - mx = 0, - my = 0, - start = 0, - pa0; - if (pathArray[0][0] == "M") { - x = +pathArray[0][1]; - y = +pathArray[0][2]; - mx = x; - my = y; - start++; - res[0] = ["M", x, y]; - } - var crz = pathArray.length == 3 && - pathArray[0][0] == "M" && - pathArray[1][0].toUpperCase() == "R" && - pathArray[2][0].toUpperCase() == "Z"; - for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) { - res.push(r = []); - pa = pathArray[i]; - pa0 = pa[0]; - if (pa0 != pa0.toUpperCase()) { - r[0] = pa0.toUpperCase(); - switch (r[0]) { - case "A": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +pa[6] + x; - r[7] = +pa[7] + y; - break; - case "V": - r[1] = +pa[1] + y; - break; - case "H": - r[1] = +pa[1] + x; - break; - case "R": - var dots = [x, y].concat(pa.slice(1)); - for (var j = 2, jj = dots.length; j < jj; j++) { - dots[j] = +dots[j] + x; - dots[++j] = +dots[j] + y; - } - res.pop(); - res = res.concat(catmullRom2bezier(dots, crz)); - break; - case "O": - res.pop(); - dots = ellipsePath(x, y, pa[1], pa[2]); - dots.push(dots[0]); - res = res.concat(dots); - break; - case "U": - res.pop(); - res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3])); - r = ["U"].concat(res[res.length - 1].slice(-2)); - break; - case "M": - mx = +pa[1] + x; - my = +pa[2] + y; - default: - for (j = 1, jj = pa.length; j < jj; j++) { - r[j] = +pa[j] + ((j % 2) ? x : y); - } - } - } else if (pa0 == "R") { - dots = [x, y].concat(pa.slice(1)); - res.pop(); - res = res.concat(catmullRom2bezier(dots, crz)); - r = ["R"].concat(pa.slice(-2)); - } else if (pa0 == "O") { - res.pop(); - dots = ellipsePath(x, y, pa[1], pa[2]); - dots.push(dots[0]); - res = res.concat(dots); - } else if (pa0 == "U") { - res.pop(); - res = res.concat(ellipsePath(x, y, pa[1], pa[2], pa[3])); - r = ["U"].concat(res[res.length - 1].slice(-2)); - } else { - for (var k = 0, kk = pa.length; k < kk; k++) { - r[k] = pa[k]; - } - } - pa0 = pa0.toUpperCase(); - if (pa0 != "O") { - switch (r[0]) { - case "Z": - x = +mx; - y = +my; - break; - case "H": - x = r[1]; - break; - case "V": - y = r[1]; - break; - case "M": - mx = r[r.length - 2]; - my = r[r.length - 1]; - default: - x = r[r.length - 2]; - y = r[r.length - 1]; - } - } - } - - return res; -}; - - -var l2c = function(x1, y1, x2, y2) { - return [x1, y1, x2, y2, x2, y2]; -}; -var q2c = function(x1, y1, ax, ay, x2, y2) { - var _13 = 1 / 3, - _23 = 2 / 3; - return [ - _13 * x1 + _23 * ax, - _13 * y1 + _23 * ay, - _13 * x2 + _23 * ax, - _13 * y2 + _23 * ay, - x2, - y2 - ]; -}; -var a2c = function(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { - // for more information of where this math came from visit: - // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - var _120 = Math.PI * 120 / 180, - rad = Math.PI / 180 * (+angle || 0), - res = [], - xy, - rotate = function(x, y, rad) { - var X = x * Math.cos(rad) - y * Math.sin(rad), - Y = x * Math.sin(rad) + y * Math.cos(rad); - return { x: X, y: Y }; - }; - if (!recursive) { - xy = rotate(x1, y1, -rad); - x1 = xy.x; - y1 = xy.y; - xy = rotate(x2, y2, -rad); - x2 = xy.x; - y2 = xy.y; - var cos = Math.cos(Math.PI / 180 * angle), - sin = Math.sin(Math.PI / 180 * angle), - x = (x1 - x2) / 2, - y = (y1 - y2) / 2; - var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); - if (h > 1) { - h = Math.sqrt(h); - rx = h * rx; - ry = h * ry; - } - var rx2 = rx * rx, - ry2 = ry * ry, - k = (large_arc_flag == sweep_flag ? -1 : 1) * - Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))), - cx = k * rx * y / ry + (x1 + x2) / 2, - cy = k * -ry * x / rx + (y1 + y2) / 2, - f1 = Math.asin(((y1 - cy) / ry).toFixed(9)), - f2 = Math.asin(((y2 - cy) / ry).toFixed(9)); - - f1 = x1 < cx ? Math.PI - f1 : f1; - f2 = x2 < cx ? Math.PI - f2 : f2; - f1 < 0 && (f1 = Math.PI * 2 + f1); - f2 < 0 && (f2 = Math.PI * 2 + f2); - if (sweep_flag && f1 > f2) { - f1 = f1 - Math.PI * 2; - } - if (!sweep_flag && f2 > f1) { - f2 = f2 - Math.PI * 2; - } - } else { - f1 = recursive[0]; - f2 = recursive[1]; - cx = recursive[2]; - cy = recursive[3]; - } - var df = f2 - f1; - if (Math.abs(df) > _120) { - var f2old = f2, - x2old = x2, - y2old = y2; - f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); - x2 = cx + rx * Math.cos(f2); - y2 = cy + ry * Math.sin(f2); - res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); - } - df = f2 - f1; - var c1 = Math.cos(f1), - s1 = Math.sin(f1), - c2 = Math.cos(f2), - s2 = Math.sin(f2), - t = Math.tan(df / 4), - hx = 4 / 3 * rx * t, - hy = 4 / 3 * ry * t, - m1 = [x1, y1], - m2 = [x1 + hx * s1, y1 - hy * c1], - m3 = [x2 + hx * s2, y2 - hy * c2], - m4 = [x2, y2]; - m2[0] = 2 * m1[0] - m2[0]; - m2[1] = 2 * m1[1] - m2[1]; - if (recursive) { - return [m2, m3, m4].concat(res); - } else { - res = [m2, m3, m4].concat(res).join().split(","); - var newres = []; - for (var i = 0, ii = res.length; i < ii; i++) { - newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; - } - return newres; - } -}; - -export function path2curve(path, path2) { - var p = pathToAbsolute(path), - p2 = path2 && pathToAbsolute(path2), - attrs = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null }, - attrs2 = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null }, - processPath = function(path, d, pcom) { - var nx, ny; - if (!path) { - return ["C", d.x, d.y, d.x, d.y, d.x, d.y]; - } - !(path[0] in { T: 1, Q: 1 }) && (d.qx = d.qy = null); - switch (path[0]) { - case "M": - d.X = path[1]; - d.Y = path[2]; - break; - case "A": - path = ["C"].concat(a2c.apply(0, [d.x, d.y].concat(path.slice(1)))); - break; - case "S": - if (pcom == "C" || pcom == "S") { // In "S" case we have to take into account, if the previous command is C/S. - nx = d.x * 2 - d.bx; // And reflect the previous - ny = d.y * 2 - d.by; // command's control point relative to the current point. - } - else { // or some else or nothing - nx = d.x; - ny = d.y; - } - path = ["C", nx, ny].concat(path.slice(1)); - break; - case "T": - if (pcom == "Q" || pcom == "T") { // In "T" case we have to take into account, if the previous command is Q/T. - d.qx = d.x * 2 - d.qx; // And make a reflection similar - d.qy = d.y * 2 - d.qy; // to case "S". - } - else { // or something else or nothing - d.qx = d.x; - d.qy = d.y; - } - path = ["C"].concat(q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])); - break; - case "Q": - d.qx = path[1]; - d.qy = path[2]; - path = ["C"].concat(q2c(d.x, d.y, path[1], path[2], path[3], path[4])); - break; - case "L": - path = ["C"].concat(l2c(d.x, d.y, path[1], path[2])); - break; - case "H": - path = ["C"].concat(l2c(d.x, d.y, path[1], d.y)); - break; - case "V": - path = ["C"].concat(l2c(d.x, d.y, d.x, path[1])); - break; - case "Z": - path = ["C"].concat(l2c(d.x, d.y, d.X, d.Y)); - break; - } - return path; - }, - fixArc = function(pp, i) { - if (pp[i].length > 7) { - pp[i].shift(); - var pi = pp[i]; - while (pi.length) { - pcoms1[i] = "A"; // if created multiple C:s, their original seg is saved - p2 && (pcoms2[i] = "A"); // the same as above - pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6))); - } - pp.splice(i, 1); - ii = Math.max(p.length, p2 && p2.length || 0); - } - }, - fixM = function(path1, path2, a1, a2, i) { - if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") { - path2.splice(i, 0, ["M", a2.x, a2.y]); - a1.bx = 0; - a1.by = 0; - a1.x = path1[i][1]; - a1.y = path1[i][2]; - ii = Math.max(p.length, p2 && p2.length || 0); - } - }, - pcoms1 = [], // path commands of original path p - pcoms2 = [], // path commands of original path p2 - pfirst = "", // temporary holder for original path command - pcom = ""; // holder for previous path command of original path - for (var i = 0, ii = Math.max(p.length, p2 && p2.length || 0); i < ii; i++) { - p[i] && (pfirst = p[i][0]); // save current path command - - if (pfirst != "C") { // C is not saved yet, because it may be result of conversion - pcoms1[i] = pfirst; // Save current path command - i && ( pcom = pcoms1[i - 1]); // Get previous path command pcom - } - p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath - - if (pcoms1[i] != "A" && pfirst == "C") pcoms1[i] = "C"; // A is the only command - // which may produce multiple C:s - // so we have to make sure that C is also C in original path - - fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1 - - if (p2) { // the same procedures is done to p2 - p2[i] && (pfirst = p2[i][0]); - if (pfirst != "C") { - pcoms2[i] = pfirst; - i && (pcom = pcoms2[i - 1]); - } - p2[i] = processPath(p2[i], attrs2, pcom); - - if (pcoms2[i] != "A" && pfirst == "C") { - pcoms2[i] = "C"; - } - - fixArc(p2, i); - } - fixM(p, p2, attrs, attrs2, i); - fixM(p2, p, attrs2, attrs, i); - var seg = p[i], - seg2 = p2 && p2[i], - seglen = seg.length, - seg2len = p2 && seg2.length; - attrs.x = seg[seglen - 2]; - attrs.y = seg[seglen - 1]; - attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x; - attrs.by = parseFloat(seg[seglen - 3]) || attrs.y; - attrs2.bx = p2 && (parseFloat(seg2[seg2len - 4]) || attrs2.x); - attrs2.by = p2 && (parseFloat(seg2[seg2len - 3]) || attrs2.y); - attrs2.x = p2 && seg2[seg2len - 2]; - attrs2.y = p2 && seg2[seg2len - 1]; - } - - return p2 ? [p, p2] : p; -}; diff --git a/src/plugins.jsx b/src/plugins.jsx deleted file mode 100644 index 24c9a767..00000000 --- a/src/plugins.jsx +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-disable func-names */ -const Plugins = function () { -}; -const p = Plugins.prototype; -p.push = function (plugin) { - this[plugin.prototype.name] = plugin; -}; -export default new Plugins; diff --git a/src/ticker.js b/src/ticker.js deleted file mode 100644 index 73790518..00000000 --- a/src/ticker.js +++ /dev/null @@ -1,116 +0,0 @@ -/* eslint-disable func-names */ -import requestAnimationFrame from 'raf'; - -const getTime = Date.now || (() => new Date().getTime()); -const sortObj = { - interval: 1, - timeout: 1, - TweenOneTicker: 2, -} -const tickObjToArray = (obj) => ( - Object.keys(obj).map(k => ({ - key: k, - func: obj[k], - })).sort((a, b) => { - const aa = a.key.split('_')[0]; - const bb = b.key.split('_')[0]; - return sortObj[bb] - sortObj[aa]; - }) -); -const Ticker = function () { -}; -Ticker.prototype = { - tickFnArray: [], - tickKeyObject: {}, - id: -1, - tweenId: 0, - frame: 0, - perFrame: Math.round(1000 / 60), - elapsed: 0, - lastUpdate: getTime(), - startTime: getTime(),// 开始时间,不计算 react 渲染时间; - nextTime: 0, - time: 0, -}; -const p = Ticker.prototype; -p.add = function (fn) { - const key = `TweenOneTicker_${this.tweenId}`; - this.tweenId++; - this.wake(key, fn); - return key; -}; -p.wake = function (key, fn) { - this.tickKeyObject[key] = fn; - this.tickFnArray = tickObjToArray(this.tickKeyObject); - if (this.id === -1) { - this.id = requestAnimationFrame(this.tick); - } -}; -p.clear = function (key) { - delete this.tickKeyObject[key]; - this.tickFnArray = tickObjToArray(this.tickKeyObject); -}; -p.sleep = function () { - requestAnimationFrame.cancel(this.id); - this.id = -1; - this.frame = 0; -}; -const ticker = new Ticker; -p.tick = function (a) { - ticker.elapsed = getTime() - ticker.lastUpdate; - // 离开当前时设值 300;大于 300 则为离开。 - if (ticker.elapsed > 300) { - ticker.startTime += ticker.elapsed - ticker.perFrame; - } - ticker.lastUpdate += ticker.elapsed; - ticker.time = ticker.lastUpdate - ticker.startTime; - const overlap = ticker.time - ticker.nextTime; - if (overlap > 0 || !ticker.frame) { - ticker.frame++; - ticker.nextTime += overlap; - } - // console.log(ticker.frame, ticker.nextTime, ticker.time) - ticker.tickFnArray.forEach(item => item.func(a)); - // 如果 object 里没对象了,自动杀掉; - if (!ticker.tickFnArray.length) { - ticker.sleep(); - return; - } - ticker.id = requestAnimationFrame(ticker.tick); -}; -let timeoutIdNumber = 0; -p.timeout = function (fn, time) { - if (!(typeof fn === 'function')) { - return console.warn('not function');// eslint-disable-line - } - const timeoutID = `timeout_${Date.now()}-${timeoutIdNumber}`; - const startTime = this.time; - this.wake(timeoutID, () => { - const moment = this.time - startTime; - if (moment >= (time || 0)) { - this.clear(timeoutID); - fn(); - } - }); - timeoutIdNumber++; - return timeoutID; -}; -let intervalIdNumber = 0; -p.interval = function (fn, time) { - if (!(typeof fn === 'function')) { - console.warn('not function');// eslint-disable-line - return null; - } - const intervalID = `interval_${Date.now()}-${intervalIdNumber}`; - let starTime = this.time; - this.wake(intervalID, () => { - const moment = this.time - starTime; - if (moment >= (time || 0)) { - starTime = this.time; - fn(); - } - }); - intervalIdNumber++; - return intervalID; -}; -export default ticker; diff --git a/src/type.ts b/src/type.ts new file mode 100644 index 00000000..345dc114 --- /dev/null +++ b/src/type.ts @@ -0,0 +1,68 @@ +import React from 'react'; +import { IAnimObject as AnimObject, IObject, IMode, ITimelineCallBack } from 'tween-one'; + +export interface ICallBack { + mode?: IMode; + moment?: number; + ratio?: number; + index: number; + repeat?: number; + timelineMoment?: number; + vars?: IObject | IObject[]; + targets?: IObject | IObject[] +}; + +export type AnimObjectOrArray = AnimObject | AnimObject[]; + +export type IAnimObject = AnimObjectOrArray | ((key: string, index: number) => AnimObject); + +export interface IAnimProps extends Omit, 'onChange'> { + style?: React.CSSProperties; + children?: any; + animation?: AnimObjectOrArray; + paused?: boolean; + reverse?: boolean; + repeatDelay?: number; + repeat?: number; + yoyo?: boolean; + onChange?: (v: ICallBack) => void; + onChangeTimeline?: (v: ITimelineCallBack) => void; + moment?: number; + attr?: boolean; + resetStyle?: boolean; + component?: + | string + | React.ClassType> + | null + | undefined; + componentProps?: IObject; + forcedJudg?: IObject; + killPrevAnim?: boolean; +} + +export interface IGroupProps extends Omit, 'onChange'> { + appear?: boolean; + enter?: IAnimObject; + leave?: IAnimObject; + animatingClassName?: string[] | [string, string]; + exclusive?: boolean; + resetStyle?: boolean; + onEnd?: (e: { key?: string | React.ReactText; type?: string }) => void; + component?: + | string + | React.ClassType> + | null + | undefined; + componentProps?: {}; +} + +export interface TweenOneRef extends React.ForwardRefExoticComponent { + isTweenOne?: boolean; + plugins?: any; + ticker?: any; + easing?: any; +} + +export interface TweenOneGroupRef extends React.ForwardRefExoticComponent { + isTweenOneGroup?: boolean; +} \ No newline at end of file diff --git a/src/util.js b/src/util.js deleted file mode 100644 index 12939a42..00000000 --- a/src/util.js +++ /dev/null @@ -1,289 +0,0 @@ -import React from 'react'; - -export const windowIsUndefined = !( - typeof window !== 'undefined' && - window.document && - window.document.createElement -); - -export const transformOrFilter = { - transform: 1, - '-ms-transform': 1, - '-moz-transform': 1, - '-webkit-transform': 1, - '-o-transform': 1, - filter: 1, - '-webkit-filter': 1 -}; - -export const styleValueToArray = { - margin: 1, - padding: 1, - borderWidth: 1, - borderRadius: 1 -} - -export function toArrayChildren(children) { - const ret = []; - React.Children.forEach(children, (c) => { - ret.push(c); - }); - return ret; -} - -export function dataToArray(vars) { - if (!vars && vars !== 0) { - return []; - } - if (Array.isArray(vars)) { - return vars; - } - return [vars]; -} - -function deepEql(a, b) { - if (!a || !b) { - return false; - } - const $a = Object.keys(a); - const $b = Object.keys(b); - if ($a.length && $b.length && $a.length === $b.length) { - return !$a.some((key) => { - let aa = a[key]; - let bb = b[key]; - if (Array.isArray(aa) && Array.isArray(bb)) { - const aaa = aa.join(); - const bbb = bb.join(); - if (aaa === bbb && !aaa.match(/\[object object\]/ig)) { - aa = aaa; - bb = bbb; - } - } - return aa !== bb; - }); - } - return false; -} - -export function objectEqual(obj1, obj2) { - if (obj1 === obj2 || deepEql(obj1, obj2)) { - return true; - } - if (!obj1 || !obj2 || Object.keys(obj1).length !== Object.keys(obj2).length) { - return false; - } - // animation 写在标签上的进行判断是否相等, 判断每个参数有没有 function; - let equalBool = true; - const setEqualBool = ($a, $b) => { - const objA = Object.keys($a).length > Object.keys($b).length ? $a : $b; - const objB = Object.keys($a).length > Object.keys($b).length ? $b : $a; - Object.keys(objA).forEach(key => { - // 如果前面有参数匹配不相同则直接返回; - if (!equalBool) { - return; - } - if (!(key in objB)) { - equalBool = false; - } - - if (typeof objA[key] === 'object' && typeof objB[key] === 'object') { - equalBool = objectEqual(objA[key], objB[key]); - } else if (typeof objA[key] === 'function' && typeof objB[key] === 'function') { - if (objA[key].toString().replace(/\s+/g, '') !== objB[key].toString().replace(/\s+/g, '')) { - equalBool = false; - } - } else if (objA[key] !== objB[key]) { - equalBool = false; - } - }); - }; - - if (Array.isArray(obj1) && Array.isArray(obj2)) { - if (obj1.length !== obj2.length) { - return false; - } - obj1.forEach((item, i) => { - setEqualBool(item, obj2[i]); - }); - } else { - setEqualBool(obj1, obj2); - } - return equalBool; -} - -export function findChildInChildrenByKey(children, key) { - let ret = null; - if (children) { - children.forEach((c) => { - if (ret || !c) { - return; - } - if (c.key === key) { - ret = c; - } - }); - } - return ret; -} - -export function mergeChildren(prev, next) { - let ret = []; - // For each key of `next`, the list of keys to insert before that key in - // the combined list - const nextChildrenPending = {}; - let pendingChildren = []; - let followChildrenKey; - prev.forEach((c) => { - if (!c) { - return; - } - if (findChildInChildrenByKey(next, c.key)) { - if (pendingChildren.length) { - nextChildrenPending[c.key] = pendingChildren; - pendingChildren = []; - } - followChildrenKey = c.key; - } else if (c.key) { - pendingChildren.push(c); - } - }); - if (!followChildrenKey) { - ret = ret.concat(pendingChildren); - } - - next.forEach((c) => { - if (!c) { - return; - } - if (nextChildrenPending.hasOwnProperty(c.key)) { // eslint-disable-line no-prototype-builtins - ret = ret.concat(nextChildrenPending[c.key]); - } - ret.push(c); - if (c.key === followChildrenKey) { - ret = ret.concat(pendingChildren); - } - }); - - return ret; -} - -export function transformArguments(arg, key, i) { - let result; - if (typeof arg === 'function') { - result = arg({ - key, - index: i, - }); - } else { - result = arg; - } - return result; -} - -export function getChildrenFromProps(props) { - return props && props.children; -} - -export function startConvertToEndUnit( - target, computedStyle, style, num, - unit, dataUnit, fixed, isOriginWidth -) { - if (windowIsUndefined) { - return num; - } - let horiz = /(?:Left|Right|Width|X)/i.test(style) || isOriginWidth; - horiz = style === 'padding' || style === 'marign' ? true : horiz; - let t = style.indexOf('border') !== -1 || style.indexOf('translate') !== -1 || style === 'transformOrigin' ? - target : target.parentNode || document.body; - t = fixed ? document.body : t; - let pix; - let htmlComputedStyle; - // transform 在 safari 下会留着单位,chrome 下会全部转换成 px; - switch (unit) { - case '%': - pix = parseFloat(num) / 100 * (horiz ? t.clientWidth : t.clientHeight); - break; - case 'vw': - pix = parseFloat(num) * document.body.clientWidth / 100; - break; - case 'vh': - pix = parseFloat(num) * document.body.clientHeight / 100; - break; - case 'em': - pix = parseFloat(num) * parseFloat(computedStyle.fontSize); - break; - case 'rem': { - htmlComputedStyle = window.getComputedStyle(document.getElementsByTagName('html')[0]); - pix = parseFloat(num) * parseFloat(htmlComputedStyle.fontSize); - break; - } - default: - pix = parseFloat(num); - break; - } - switch (dataUnit) { - case '%': - pix = pix ? pix * 100 / (horiz ? t.clientWidth : t.clientHeight) : 0; - break; - case 'vw': - pix = parseFloat(num) / document.body.clientWidth * 100; - break; - case 'vh': - pix = parseFloat(num) / document.body.clientHeight * 100; - break; - case 'em': - pix = parseFloat(num) / parseFloat(computedStyle.fontSize); - break; - case 'rem': { - htmlComputedStyle = htmlComputedStyle || - window.getComputedStyle(document.getElementsByTagName('html')[0]); - pix = parseFloat(num) / parseFloat(htmlComputedStyle.fontSize); - break; - } - default: - break; - } - return pix; -} - -export function parsePath(path) { - if (typeof path === 'string') { - if (path.charAt(0).match(/m/i)) { - const domPath = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - domPath.setAttributeNS(null, 'd', path); - return domPath; - } - return document.querySelector(path); - } else if (path.style) { - return path; - } - throw new Error('Error while parsing the path'); -} - -export function getTransformValue(t) { - if (typeof t === 'string') { - return t; - } - const perspective = t.perspective; - const angle = t.rotate; - const rotateX = t.rotateX; - const rotateY = t.rotateY; - const sx = t.scaleX; - const sy = t.scaleY; - const sz = t.scaleZ; - const skx = t.skewX; - const sky = t.skewY; - const translateX = typeof t.translateX === 'string' ? t.translateX : `${t.translateX}px`; - const translateY = typeof t.translateY === 'string' ? t.translateY : `${t.translateY}px`; - const translateZ = typeof t.translateZ === 'string' ? t.translateZ : `${t.translateZ}px`; - const sk = skx || sky ? `skew(${skx}deg,${sky}deg)` : ''; - const an = angle ? `rotate(${angle}deg)` : ''; - const ss = sx !== 1 || sy !== 1 || sz !== 1 ? `scale3d(${sx},${sy},${sz})` : ''; - const rX = rotateX ? `rotateX(${rotateX}deg)` : ''; - const rY = rotateY ? `rotateY(${rotateY}deg)` : ''; - const per = perspective ? `perspective(${perspective}px)` : ''; - const defaultTranslate = (ss || an || rX || rY || sk) ? '' : 'translate(0px, 0px)'; - const translate = t.translateZ ? `translate3d(${translateX},${translateY},${translateZ})` : - (t.translateX || t.translateY) && `translate(${translateX},${translateY})` || defaultTranslate; - return `${per} ${translate} ${ss} ${an} ${rX} ${rY} ${sk}`.trim(); -} diff --git a/src/utils/group.ts b/src/utils/group.ts new file mode 100644 index 00000000..489c35ce --- /dev/null +++ b/src/utils/group.ts @@ -0,0 +1,98 @@ +import React, { ReactElement } from 'react'; + +export const windowIsUndefined = !( + typeof window !== 'undefined' && + window.document && + window.document.createElement +); + +export function toArrayChildren(children: any) { + const ret: any[] = []; + React.Children.forEach(children, (c) => { + ret.push(c); + }); + return ret; +} + +export function dataToArray(vars: any) { + if (!vars && vars !== 0) { + return []; + } + if (Array.isArray(vars)) { + return vars; + } + return [vars]; +} + +export function findChildInChildrenByKey(children: ReactElement[], key: string | number | null) { + let ret: any = null; + if (children) { + children.forEach((c) => { + if (ret || !c) { + return; + } + if (c.key === key) { + ret = c; + } + }); + } + return ret; +} + +export function mergeChildren(prev: ReactElement[], next: ReactElement[]) { + let ret: any[] = []; + // For each key of `next`, the list of keys to insert before that key in + // the combined list + const nextChildrenPending: any = {}; + let pendingChildren: any[] = []; + let followChildrenKey: string | number | null = null; + prev.forEach((c) => { + if (!c) { + return; + } + if (c.key && findChildInChildrenByKey(next, c.key)) { + if (pendingChildren.length) { + nextChildrenPending[c.key] = pendingChildren; + pendingChildren = []; + } + followChildrenKey = c.key; + } else if (c.key) { + pendingChildren.push(c); + } + }); + if (!followChildrenKey) { + ret = ret.concat(pendingChildren); + } + + next.forEach((c) => { + if (!c) { + return; + } + if (c.key && nextChildrenPending.hasOwnProperty(c.key)) { // eslint-disable-line no-prototype-builtins + ret = ret.concat(nextChildrenPending[c.key]); + } + ret.push(c); + if (c.key === followChildrenKey) { + ret = ret.concat(pendingChildren); + } + }); + + return ret; +} + +export function transformArguments(arg: any, key: string | number | null, i: number) { + let result; + if (typeof arg === 'function') { + result = arg({ + key, + index: i, + }); + } else { + result = arg; + } + return result; +} + +export function getChildrenFromProps(props: IObject) { + return props && props.children; +} \ No newline at end of file diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 00000000..c334e264 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,72 @@ +function deepEql(a: any, b: any) { + if (!a || !b) { + return false; + } + const $a = Object.keys(a); + const $b = Object.keys(b); + if ($a.length && $b.length && $a.length === $b.length) { + return !$a.some(key => { + let aa = a[key]; + let bb = b[key]; + if (Array.isArray(aa) && Array.isArray(bb)) { + const aaa = aa.join(); + const bbb = bb.join(); + if (aaa === bbb && !aaa.match(/\[object object\]/gi)) { + aa = aaa; + bb = bbb; + } + } + return aa !== bb; + }); + } + return false; +} + +export function objectEqual(obj1: any, obj2: any) { + if (obj1 === obj2 || deepEql(obj1, obj2)) { + return true; + } + if (!obj1 || !obj2 || Object.keys(obj1).length !== Object.keys(obj2).length) { + return false; + } + // animation 写在标签上的进行判断是否相等, 判断每个参数有没有 function; + let equalBool = true; + const setEqualBool = ($a: any, $b: any) => { + const objA = Object.keys($a).length > Object.keys($b).length ? $a : $b; + const objB = Object.keys($a).length > Object.keys($b).length ? $b : $a; + Object.keys(objA).forEach(key => { + // 如果前面有参数匹配不相同则直接返回; + if (!equalBool) { + return; + } + if (!(key in objB)) { + equalBool = false; + } + + if (typeof objA[key] === 'object' && typeof objB[key] === 'object') { + equalBool = objectEqual(objA[key], objB[key]); + } else if ( + typeof objA[key] === 'function' && + typeof objB[key] === 'function' + ) { + if ( + objA[key].toString().replace(/\s+/g, '') !== + objB[key].toString().replace(/\s+/g, '') + ) { + equalBool = false; + } + } else if (objA[key] !== objB[key]) { + equalBool = false; + } + }); + }; + + if (Array.isArray(obj1) && Array.isArray(obj2)) { + obj1.forEach((item, i) => { + setEqualBool(item, obj2[i]); + }); + } else { + setEqualBool(obj1, obj2); + } + return equalBool; +} diff --git a/tests/index.js b/tests/index.js deleted file mode 100755 index 096237d9..00000000 --- a/tests/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import 'core-js/es6/map'; -import 'core-js/es6/set'; - -const req = require.context('.', false, /\.spec\.jsx?$/); -req.keys().forEach(req); diff --git a/tests/index.tsx b/tests/index.tsx deleted file mode 100644 index 4c1f6dc7..00000000 --- a/tests/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from 'react'; - -import TweenOne from '../typings'; - -const path = 'M0,100 C30,60 0,20 50,50 C70,70 60,0 100,0'; -const ease = TweenOne.easing.path(path, { rect: 100, lengthPixel: 200 }); -const Group = TweenOne.TweenOneGroup; -const tween = new TweenOne.Tween({}, { x: 100 }); -tween.init(); -export default () => ( -
- { - console.log(index, target); - }, - }} - > - test - - { - console.log(index, target); - }, - }, { - x: 200, - ease, - onComplete: ({ index, target }) => { - console.log(index, target); - }, - }]} - > - test - - -
test
-
-
-); diff --git a/tests/tweenOne.spec.jsx b/tests/tweenOne.spec.jsx deleted file mode 100644 index fb389559..00000000 --- a/tests/tweenOne.spec.jsx +++ /dev/null @@ -1,700 +0,0 @@ -/* eslint no-console:0 */ -import React from 'react'; -import ReactDom from 'react-dom'; -import PropTypes from 'prop-types'; -import expect from 'expect.js'; -import TestUtils from 'react-dom/test-utils'; -import { checkStyleName } from 'style-utils'; - -import TweenOne, { easing, plugins } from '../src'; -import ticker from '../src/ticker'; -import BezierPlugin from '../src/plugin/BezierPlugin'; - -plugins.push(BezierPlugin); - -const Div = React.forwardRef(({ show }, ref) => { - return show ?
text
: null; -}); - -Div.propTypes = { - show: PropTypes.bool, -} -describe('rc-tween-one', () => { - let div; - let instance; - - function createTweenInstance(props) { - class TweenDemo extends React.Component { - constructor(componentProps) { - super(componentProps); - this.state = { - animation: this.props.animation, - style: this.props.style, - reverse: false, - paused: this.props.paused, - moment: null, - showChild: false, - }; - } - - render() { - if (this.props.component === 'rect') { - return ( - - ); - } - return ( - demo - ); - } - } - const objectOrArray = PropTypes.oneOfType([PropTypes.object, - PropTypes.array]); - - TweenDemo.propTypes = { - animation: objectOrArray, - style: PropTypes.object, - component: PropTypes.any, - paused: PropTypes.bool, - }; - - return ReactDom.render(, div); - } - - beforeEach(() => { - div = document.createElement('div'); - document.body.appendChild(div); - }); - - afterEach(() => { - try { - ReactDom.unmountComponentAtNode(div); - document.body.removeChild(div); - } catch (e) { - console.log(e); - } - }); - - function getFloat(str) { - return parseFloat(str); - } - - it('single tween-one', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - left: '100vw', - width: '10vh', - height: '100%', - boxShadow: '0 0 30px rgba(255,125,0,0.5)', - margin: '30rem', - scale: 1.5, - x: '+=100', - transformOrign: '30% 10%', - delay: 100, - yoyo: true, - }, - style: { top: 0, left: '10vw', width: '5vh', height: '10%', margin: '10rem' }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log('start:', child.style.top); - expect(getFloat(child.style.top)).to.be(0); - ticker.timeout(() => { - // 默认时间为450,用500是肯定过值; - console.log('end:', child.style.top); - expect(getFloat(child.style.top)).to.be(100); - done(); - }, 600); - }); - - it('tween-one repeat -1 and yoyo', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - repeat: -1, - yoyo: true, - }, - style: { top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log('start:', child.style.top); - expect(getFloat(child.style.top)).to.be(0); - ticker.timeout(() => { - console.log('end:', child.style.top); - expect(getFloat(child.style.top)).to.above(0); - done(); - }, 200); - }); - - it('single tween-one duration is 0', (done) => { - let start; - let update; - let complete; - instance = createTweenInstance({ - animation: { - scale: '+=0.1', - x: '20%', - left: '+=20', - duration: 0, - onStart() { - start = 1; - }, - onUpdate() { - update = 1; - }, - onComplete() { - complete = 1; - } - }, - }); - ticker.timeout(() => { - expect(start).to.be(1); - expect(update).to.be(1); - expect(complete).to.be(1); - done(); - }, 34); - }); - - it('timeline tween-one', (done) => { - instance = createTweenInstance({ - animation: [{ top: 100 }, { left: 100 }, { top: 0 }, { left: 0 }], - style: { position: 'relative' }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - console.log('top===100,data:', child.style.top, '########', - 'left>0,data:', child.style.left); - expect(getFloat(child.style.top)).to.be(100); - expect(getFloat(child.style.left)).to.above(0); - ticker.timeout(() => { - console.log('top<100,data:', child.style.top, '########', - 'left===0,data:', child.style.left); - expect(getFloat(child.style.left)).to.be(100); - expect(getFloat(child.style.top)).to.below(100); - ticker.timeout(() => { - console.log('top===0,data:', child.style.top, '########', - 'left<100,data:', child.style.left); - expect(getFloat(child.style.left)).to.below(100); - expect(getFloat(child.style.top)).to.be(0); - ticker.timeout(() => { - console.log('top===0,data:', child.style.top, - '########', 'left===0,data:', child.style.left); - expect(getFloat(child.style.top)).to.be(0); - expect(getFloat(child.style.left)).to.be(0); - done(); - }, 450); - }, 450); - }, 450); - }, 500); - }); - - it('repeat tween-one', (done) => { - instance = createTweenInstance({ - animation: { top: 100, repeat: 1, repeatDelay: 300 }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log('start:', child.style.top); - expect(getFloat(child.style.top)).to.be(0); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.above(95); - console.log('20 milliseconds before the first repeat end, top>95, data:', child.style.top); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.below(10); - console.log('20 ms after the beginning of the second repeat, top<10, data', - child.style.top); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.be(100); - console.log('repeat end,top:', child.style.top); - done(); - }, 450); - }, 340); - }, 430); - }); - - it('repeat yoyo tween-one', (done) => { - instance = createTweenInstance({ - animation: { top: 100, repeat: 1, yoyo: true }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log('start:', child.style.top); - expect(getFloat(child.style.top)).to.be(0); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.above(95); - console.log('20 milliseconds before the first repeat end, top>95, data:', child.style.top); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.below(101).above(95); - console.log('20 ms after the beginning of the second repeat, 95 { - expect(getFloat(child.style.top)).to.be(0); - console.log('repeat end,top:', child.style.top); - done(); - }, 450); - }, 40); - }, 430); - }); - - it('type is from tween-one', (done) => { - instance = createTweenInstance({ - animation: { top: 100, type: 'from' }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log(`default:${child.style.top}`); - expect(getFloat(child.style.top)).to.be(100); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.above(95); - console.log(`start:${child.style.top}`); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.be(0); - console.log(`end:${child.style.top}`); - done(); - }, 450); - }, 30); - }); - - it('is Bezier', (done) => { - instance = createTweenInstance({ - animation: { - bezier: { - type: 'soft', - autoRotate: true, - vars: [{ x: 100, y: 100 }, { x: 200, y: 0 }], - }, - duration: 1000, - }, - style: { position: 'absolute' }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - let transform = child.style[checkStyleName('transform')]; - let xy = transform.split(')').filter(item => item).map(item => item.split('(')[1]); - let rotate = xy[1]; - let x = xy[0].split(',')[0]; - let y = xy[0].split(',')[1]; - console.log(`x:${x}, y: ${y}, rotate:${rotate}`); - expect(getFloat(x)).to.above(-0.5).below(5); - expect(getFloat(y)).to.above(-0.5).below(5); - expect(getFloat(rotate)).to.above(44).below(45.1); - - ticker.timeout(() => { - transform = child.style[checkStyleName('transform')]; - xy = transform.split(')').filter(item => item).map(item => item.split('(')[1]); - rotate = xy[1]; - x = xy[0].split(',')[0]; - y = xy[0].split(',')[1]; - expect(getFloat(x)).to.above(80).below(120); - expect(getFloat(y)).to.above(40).below(60); - expect(getFloat(rotate)).to.above(-15).below(15); - console.log(`x:${x}, y: ${y}, rotate:${rotate}`); - ticker.timeout(() => { - transform = child.style[checkStyleName('transform')]; - xy = transform.split(')').filter(item => item).map(item => item.split('(')[1]); - x = xy[0].split(',')[0]; - y = xy[0].split(',')[1]; - expect(getFloat(x)).to.be(200); - expect(getFloat(y)).to.be(0); - console.log(`x:${x}, y: ${y}`); - done(); - }, 530); - }, 470); - }, 30); - }); - - it('is Bezier type is cubic', (done) => { - instance = createTweenInstance({ - animation: { - bezier: { - type: 'cubic', - vars: [{ x: 100, y: 0 }, { x: 300, y: 400 }, { x: 500, y: 0 }, { x: 700, y: 400 }], - }, - duration: 1000, - }, - style: { position: 'absolute' }, - }); - BezierPlugin.cubicToQuadratic(0, 100, 200, 300); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - let transform = child.style[checkStyleName('transform')]; - let xy = transform.split(')').filter(item => item).map(item => item.split('(')[1]); - let x = xy[0].split(',')[0]; - let y = xy[0].split(',')[1]; - console.log(`x:${x},y:${y}`); - expect(getFloat(x)).to.above(99); - expect(getFloat(y)).to.above(-1); - ticker.timeout(() => { - transform = child.style[checkStyleName('transform')]; - xy = transform.split(')').filter(item => item).map(item => item.split('(')[1]); - x = xy[0].split(',')[0]; - y = xy[0].split(',')[1]; - console.log(`x:${x},y:${y}`); - expect(getFloat(x)).to.be(700); - expect(getFloat(y)).to.be(400); - done(); - }, 1030); - }, 30); - }); - - it('is Bezier type is thru', (done) => { - instance = createTweenInstance({ - animation: { - bezier: { - type: 'thru', - vars: [{ x: 100, y: 0 }, { x: 300, y: 400 }], - }, - duration: 1000, - }, - style: { position: 'absolute' }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - let transform = child.style[checkStyleName('transform')]; - let xy = transform.split(')').filter(item => item).map(item => item.split('(')[1]); - let x = xy[0].split(',')[0]; - let y = xy[0].split(',')[1]; - console.log(`x:${x},y:${y}`); - expect(getFloat(x)).to.above(-1); - expect(getFloat(y)).to.above(-1); - ticker.timeout(() => { - transform = child.style[checkStyleName('transform')]; - xy = transform.split(')').filter(item => item).map(item => item.split('(')[1]); - x = xy[0].split(',')[0]; - y = xy[0].split(',')[1]; - console.log(`x:${x},y:${y}`); - expect(Math.round(getFloat(x))).to.be(300); - expect(Math.round(getFloat(y))).to.be(400); - done(); - }, 1050); - }, 30); - }); - - it('is update Animation and filter', (done) => { - instance = createTweenInstance({ - animation: { top: 100, x: 100, color: '#fff', sepia: '100%', blur: '2px', duration: 1000 }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.above(99); - console.log(`child top:${child.style.top}`); - instance.setState({ - animation: { left: 100, y: 100 }, - }); - ticker.timeout(() => { - expect(getFloat(child.style.left)).to.above(99); - console.log(`child left:${child.style.left}`); - done(); - }, 540); - }, 1040); - }); - - it('is update style', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - textShadow: '0 1em 5px rgba(0,0,0,1)', - boxShadow: '0 0 30px rgba(255,125,0,0.5)', - duration: 1000, - }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.above(50); - instance.setState({ - style: { - top: 40, - left: 100, - position: 'relative', - }, - }); - ticker.timeout(() => { - expect(getFloat(child.style.left)).to.be(100); - console.log('child left:', child.style.left); - ticker.timeout(() => { - done(); - }, 400); - }, 30); - }, 600); - }); - - it('is update animation', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - expect(getFloat(child.style.top)).to.above(0); - instance.setState({ - animation: { - left: 100, - }, - }); - ticker.timeout(() => { - expect(getFloat(child.style.left)).to.be(100); - console.log('child left:', child.style.left); - done(); - }, 500); - }, 200); - }); - - it('update animation is array', (done) => { - instance = createTweenInstance({ - animation: [{ top: 100, onStart: () => { console.log('update'); } }, { left: 100 }], - style: { top: 0, position: 'relative' }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log('start:', child.style.top); - expect(getFloat(child.style.top)).to.be(0); - ticker.timeout(() => { - instance.setState({ - animation: [{ top: 100, onStart: () => { console.log('update'); } }, { left: 100 }], - }); - // 默认时间为450,用500是肯定过值; - console.log('end:', child.style.top); - expect(getFloat(child.style.top)).to.be(100); - ticker.timeout(() => { - expect(getFloat(child.style.left)).to.be(100); - done(); - }, 500); - }, 600); - }); - - it('is reverse', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - }, - style: { position: 'relative', top: 0 }, - }); - ticker.timeout(() => { - instance.setState({ - reverse: true, - animation: { - top: 100, - }, - }); - ticker.timeout(() => { - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log(getFloat(child.style.top)); - expect(getFloat(child.style.top)).to.be(0); - done(); - }, 350); - }, 300); - }); - - it('is reverse delay', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - color: '#fff000', - }, - reverseDelay: 500, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log(getFloat(child.style.top)); - ticker.timeout(() => { - instance.setState({ - reverse: true, - }); - const top = getFloat(child.style.top); - console.log(top); - ticker.timeout(() => { - console.log(getFloat(child.style.top)); - expect(getFloat(child.style.top)).to.be(top); - ticker.timeout(() => { - console.log(getFloat(child.style.top)) - expect(getFloat(child.style.top)).to.be(0); - done(); - }, 700); - }, 300); - }, 300); - }); - - it('is paused', (done) => { - instance = createTweenInstance({ - animation: { top: 100 }, - forcedJudg: { isComp: true }, - }); - - ticker.timeout(() => { - let child = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div')[0]; - const top = getFloat(child.style.top); - expect(top).to.above(50); - instance.setState({ - paused: true, - }); - ticker.timeout(() => { - child = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div')[0]; - console.log('top:', child.style.top); - expect(getFloat(child.style.top)).to.be(top); - done(); - }, 100); - }, 300); - }); - - it('is moment', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - duration: 1000, - }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - instance.setState({ - moment: 1000, - }, () => { - instance.setState({ - moment: null, - }); - }); - ticker.timeout(() => { - console.log(child.style.top); - expect(getFloat(child.style.top)).to.be(100); - done(); - }, 10); - }, 100); - }); - - it('is moment tween end re', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - duration: 500, - }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - instance.setState({ - moment: 10, - }, () => { - instance.setState({ - moment: null, - }); - }); - ticker.timeout(() => { - console.log(child.style.top); - expect(getFloat(child.style.top)).to.be(100); - done(); - }, 550); - }, 600); - }); - - it('is timerout', (done) => { - instance = createTweenInstance({ - animation: { - top: 100, - duration: 500, - }, - style: { position: 'relative', top: 0 }, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - console.log(child.style.top); - expect(getFloat(child.style.top)).to.be(100); - const t = ticker.interval(() => { - ticker.clear(t); - done(); - }, 500); - }, 500); - }); - - it('is attr', (done) => { - instance = createTweenInstance({ - animation: { - width: 100, - color: '#fff000', - }, - attr: 'attr', - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - ticker.timeout(() => { - const width = child.getAttribute('width'); - console.log(width); - expect(getFloat(width)).to.be(100); - done(); - }, 500); - }); - - it('single tween-one component is svg', (done) => { - const ease = easing.path('M0,100L100,0'); - instance = createTweenInstance({ - animation: { translateX: 100, ease }, - component: 'rect', - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'rect'); - console.log('start:', child.style[checkStyleName('transform')]); - expect(child.style[checkStyleName('transform')]).to.be('translate(0px, 0px)'); - ticker.timeout(() => { - // 默认时间为450,用500是肯定过值; - console.log('end:', child.style[checkStyleName('transform')]); - expect(child.style[checkStyleName('transform')]).to.be('translate(100px, 0px)'); - done(); - }, 500); - }); - - it('child component is null', (done) => { - instance = createTweenInstance({ - animation: { x: 100 }, - component: Div, - }); - let child = TestUtils.scryRenderedDOMComponentsWithTag(instance); - expect(child.length).to.be(0); - ticker.timeout(() => { - instance.setState({ - showChild: true, - }); - child = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div'); - expect(child.length).to.be(1); - done(); - }, 1000); - }); - - it('timeline repeat and yoyo', (done) => { - instance = createTweenInstance({ - animation: [{ x: 100, duration: 200 }, { y: 100, duration: 200 }], - yoyo: true, - repeat: 2, - }); - const child = TestUtils.findRenderedDOMComponentWithTag(instance, 'div'); - console.log(child.style[checkStyleName('transform')]); - expect(child.style[checkStyleName('transform')]).to.be('translate(0px, 0px)'); - ticker.timeout(() => { - console.log(child.style[checkStyleName('transform')]); - expect(child.style[checkStyleName('transform')]).to.be('translate(100px, 100px)'); - ticker.timeout(() => { - console.log(child.style[checkStyleName('transform')]); - expect(child.style[checkStyleName('transform')]).to.be('translate(0px, 0px)'); - ticker.timeout(() => { - console.log(child.style[checkStyleName('transform')]); - expect(child.style[checkStyleName('transform')]).to.be('translate(100px, 100px)'); - done(); - }, 400); - }, 400); - }, 400); - }); -}); diff --git a/tests/tweenOne.test.jsx b/tests/tweenOne.test.jsx new file mode 100644 index 00000000..9bb8b155 --- /dev/null +++ b/tests/tweenOne.test.jsx @@ -0,0 +1,504 @@ +/* eslint no-console:0 */ +import React from 'react'; +import Enzyme, { mount } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +import TweenOne, { Plugins, Ticker } from '../src'; + +import ChildrenPlugin from '../src/plugin/ChildrenPlugin'; + +import PathMotionPlugin from '../src/plugin/PathMotionPlugin'; + +Plugins.push(ChildrenPlugin); + +Plugins.push(PathMotionPlugin); + +Enzyme.configure({ adapter: new Adapter() }); + +const TweenComp = (props) => { + return ( +
+ +
动画
+
+
+ ); +}; + +describe('rc-tween-one', () => { + let instance; + it('single tween-one', (done) => { + instance = mount( +
+ { + console.log(c); + }} + > +
动画
+
+
, + ); + const TweenNode = instance.instance().children[0]; + console.log('start:', TweenNode.style.top); + expect(parseFloat(TweenNode.style.top)).toBe(0); + Ticker.timeout(() => { + // 默认时间为450,用500是肯定过值; + console.log('end:', TweenNode.style.top); + expect(parseFloat(TweenNode.style.top)).toBe(100); + done(); + }, 600); + }); + it('tween-one repeat -1 and yoyo', (done) => { + instance = mount( +
+ +
动画
+
+
, + ); + const TweenNode = instance.instance().children[0]; + console.log('start:', TweenNode.style.top); + expect(parseFloat(TweenNode.style.top)).toBe(0); + Ticker.timeout(() => { + console.log('end:', TweenNode.style.top); + expect(parseFloat(TweenNode.style.top)).toBeLessThan(2); + done(); + }, 900); + }); + it('single tween-one duration is 0', (done) => { + let complete; + instance = mount( +
+ +
动画
+
+
, + ); + Ticker.timeout(() => { + console.log(complete); + expect(complete).toBe(1); + done(); + }, 34); + }); + it('timeline tween-one', (done) => { + instance = mount( +
+ +
动画
+
+
, + ); + const child = instance.instance().children[0]; + + Ticker.timeout(() => { + console.log('top===100,data:', child.style.top, '########', 'left>0,data:', child.style.left); + expect(parseFloat(child.style.top)).toBe(100); + expect(parseFloat(child.style.left)).toBeGreaterThan(0); + Ticker.timeout(() => { + console.log( + 'top<100,data:', + child.style.top, + '########', + 'left===0,data:', + child.style.left, + ); + expect(parseFloat(child.style.left)).toBe(100); + expect(parseFloat(child.style.top)).toBeLessThan(100); + Ticker.timeout(() => { + console.log( + 'top===0,data:', + child.style.top, + '########', + 'left<100,data:', + child.style.left, + ); + expect(parseFloat(child.style.left)).toBeLessThan(100); + expect(parseFloat(child.style.top)).toBe(0); + Ticker.timeout(() => { + console.log( + 'top===0,data:', + child.style.top, + '########', + 'left===0,data:', + child.style.left, + ); + expect(parseFloat(child.style.top)).toBe(0); + expect(parseFloat(child.style.left)).toBe(0); + done(); + }, 450); + }, 450); + }, 450); + }, 500); + }); + it('repeat tween-one', (done) => { + instance = mount( +
+ +
动画
+
+
, + ); + const child = instance.instance().children[0]; + console.log('start:', child.style.top); + expect(parseFloat(child.style.top)).toBe(0); + Ticker.timeout(() => { + expect(parseFloat(child.style.top)).toBeGreaterThan(95); + console.log('20 milliseconds before the first repeat end, top>95, data:', child.style.top); + Ticker.timeout(() => { + expect(parseFloat(child.style.top)).toBeLessThan(10); + console.log( + '20 ms after the beginning of the second repeat, top<10, data', + child.style.top, + ); + Ticker.timeout(() => { + expect(parseFloat(child.style.top)).toBe(100); + console.log('repeat end,top:', child.style.top); + done(); + }, 450); + }, 340); + }, 430); + }); + it('attr is true tween-one', (done) => { + instance = mount( + + + , + ); + const child = instance.instance().children[0]; + Ticker.timeout(() => { + const cx = child.getAttribute('cx'); + console.log('svg cx:', cx); + expect(parseFloat(cx)).toBe(50); + done(); + }, 500); + }); + it('type is from tween-one', (done) => { + instance = mount( +
+ +
动画
+
+
, + ); + const child = instance.instance().children[0]; + console.log(`default:${child.style.top}`); + expect(parseFloat(child.style.top)).toBe(100); + Ticker.timeout(() => { + expect(parseFloat(child.style.top)).toBeGreaterThan(95); + console.log(`start:${child.style.top}`); + Ticker.timeout(() => { + expect(parseFloat(child.style.top)).toBe(0); + console.log(`end:${child.style.top}`); + done(); + }, 450); + }, 30); + }); + it('is update Animation', (done) => { + instance = mount( + , + ); + let child = instance.find('.wrapper').instance().children[0]; + Ticker.timeout(() => { + expect(parseFloat(child.style.top)).toBeGreaterThan(99); + console.log(`child top:${child.style.top}`); + instance.setProps({ + animation: { left: 100, y: 100 }, + }); + expect(instance.props().animation.left).toBe(100); + child = instance.find('.wrapper').instance().children[0]; + Ticker.timeout(() => { + expect(parseFloat(child.style.left)).toBeGreaterThan(99); + console.log(`child left:${child.style.left}`); + done(); + }, 540); + }, 1040); + }); + it('is update Animation2', (done) => { + instance = mount( + , + ); + let child = instance.find('.wrapper').instance().children[0]; + Ticker.timeout(() => { + expect(parseFloat(child.style.top)).toBeGreaterThan(99); + console.log(`child top:${child.style.top}`); + instance.setProps({ + animation: { left: 100 }, + }); + expect(instance.props().animation.left).toBe(100); + child = instance.find('.wrapper').instance().children[0]; + Ticker.timeout(() => { + expect(parseFloat(child.style.left)).toBeGreaterThan(99); + console.log(`child left:${child.style.left}`); + done(); + }, 540); + }, 1040); + }); + it('is update Animation no change', (done) => { + instance = mount( + { + console.log('start'); + }, + }, + { y: 100, a: [100, 100] }, + ]} + style={{ position: 'relative' }} + />, + ); + let child = instance.find('.wrapper').instance().children[0]; + Ticker.timeout(() => { + console.log(`child top:${child.style.top}`); + expect(parseFloat(child.style.top)).toBeGreaterThan(90); + + instance.setProps({ + animation: [ + { + top: 100, + color: 'red', + onStart: () => { + console.log('start'); + }, + }, + { y: 100, a: [100, 100] }, + ], + }); + + Ticker.timeout(() => { + console.log(`child top:${child.style.top}`); + expect(parseFloat(child.style.top)).toBe(100); + done(); + }, 50); + }, 440); + }); + it('component is null tween-one', (done) => { + instance = mount( +
+ +
动画
+
+
, + ); + const child = instance.find('.child').instance(); + console.log(`start: ${child.style.top}`); + expect(parseFloat(child.style.top)).toBe(0); + Ticker.timeout(() => { + expect(parseFloat(child.style.top)).toBe(100); + console.log(`end: ${child.style.top}`); + done(); + }, 450); + }); + it('component is null children i string tween-one', () => { + instance = mount( +
+ + 动画 + +
, + ); + const child = instance.find('div').instance().children; + console.log(child.length, instance.text()); + + expect(child.length).toBe(0); + expect(instance.text()).toEqual('动画'); + }); + it('is resetStyle tween-one', (done) => { + instance = mount( + , + ); + + Ticker.timeout(() => { + instance.setProps({ + animation: [{ left: 100 }, { opacity: 0 }], + }); + Ticker.timeout(() => { + const child = instance.find('.wrapper').instance().children[0]; + console.log(child.style.top); + expect(child.style.top).toEqual(''); + done(); + }, 500); + }, 100); + }); + it('is reverse', (done) => { + instance = mount( + , + ); + + Ticker.timeout(() => { + instance.setProps({ + reverse: true, + animation: { + top: 100, + }, + }); + Ticker.timeout(() => { + const child = instance.find('.wrapper').instance().children[0]; + console.log(parseFloat(child.style.top)); + expect(parseFloat(child.style.top)).toBe(0); + done(); + }, 350); + }, 300); + }); + it('is paused', (done) => { + instance = mount( + , + ); + + Ticker.timeout(() => { + let child = instance.find('.wrapper').instance().children[0]; + const top = parseFloat(child.style.top); + expect(top).toBeGreaterThan(50); + instance.setProps({ + paused: true, + }); + Ticker.timeout(() => { + child = instance.find('.wrapper').instance().children[0]; + console.log('top:', child.style.top); + expect(parseFloat(child.style.top)).toBe(top); + done(); + }, 100); + }, 300); + }); + it('is moment', (done) => { + instance = mount( + , + ); + const child = instance.find('.wrapper').instance().children[0]; + Ticker.timeout(() => { + instance.setProps({ + moment: 1000, + }); + Ticker.timeout(() => { + console.log(child.style.top); + expect(parseFloat(child.style.top)).toBe(100); + done(); + }, 10); + }, 100); + }); + + it('plugin: children plugin tween-one', (done) => { + instance = mount( +
+ + 0 + +
, + ); + console.log(`default:${instance.text()}`); + expect(instance.text()).toEqual('0'); + Ticker.timeout(() => { + expect(instance.text()).toEqual('1000'); + console.log(`end:${instance.text()}`); + done(); + }, 450); + }); + it('plugin: children plugin toMoney tween-one', (done) => { + instance = mount( +
+ + 0 + +
, + ); + console.log(`default:${instance.text()}`); + expect(instance.text()).toEqual('0.00'); + Ticker.timeout(() => { + expect(instance.text()).toEqual('1,000.00'); + console.log(`end:${instance.text()}`); + done(); + }, 450); + }); + + it('plugin: pathMotion plugin tween-one', (done) => { + instance = mount( + , + ); + Ticker.timeout(() => { + const child = instance.find('.wrapper').instance().children[0]; + console.log('transform:', child.style.transform); + expect(child.style.transform).toEqual('translate(-15px,-15px) rotate(90deg)'); + done(); + }, 450); + }); +}); diff --git a/tests/tweenOneGroup.spec.jsx b/tests/tweenOneGroup.spec.jsx deleted file mode 100644 index 375c3502..00000000 --- a/tests/tweenOneGroup.spec.jsx +++ /dev/null @@ -1,124 +0,0 @@ -/* eslint no-console:0 */ -import React from 'react'; -import ReactDom from 'react-dom'; -import PropTypes from 'prop-types'; -import expect from 'expect.js'; -import TestUtils from 'react-dom/test-utils'; - -import { TweenOneGroup } from '../src'; - -describe('rc-tween-one-group', () => { - let div; - let instance; - let children; - - function createTweenGroupInstance(props) { - class TweenGroupDemo extends React.Component { - constructor(componetProps) { - super(componetProps); - this.state = { - children: [ -

demo

, - ], - }; - } - - removeAll() { - this.setState({ - children: null, - }); - } - - add() { - children = this.state.children || []; - const elem = (

demo

); - children.push(elem); - this.setState({ - children, - }); - } - - render() { - return ( - {this.state.children} - ); - } - } - const objectOrArray = PropTypes.oneOfType([PropTypes.object, - PropTypes.array]); - - TweenGroupDemo.propTypes = { - animation: objectOrArray, - style: PropTypes.object, - }; - - return ReactDom.render(, div); - } - - beforeEach(() => { - div = document.createElement('div'); - document.body.appendChild(div); - }); - - afterEach(() => { - try { - ReactDom.unmountComponentAtNode(div); - document.body.removeChild(div); - } catch (e) { - console.log(e); - } - }); - - function getFloat(str) { - return parseFloat(str); - } - - it('should render children', () => { - instance = createTweenGroupInstance(); - children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'p'); - expect(children.length).to.be(1); - }); - - it('is normal tween', (done) => { - instance = createTweenGroupInstance({ - enter: { marginLeft: 100, opacity: 0, type: 'from' }, - }); - setTimeout(() => { - children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'p')[0]; - console.log('marginLeft > 95:', children.style.marginLeft); - expect(getFloat(children.style.marginLeft)).to.above(95); - setTimeout(() => { - console.log('marginLeft is 0:', children.style.marginLeft); - expect(getFloat(children.style.marginLeft)).to.be(0); - done(); - }, 500); - }, 50); - }); - - it('appear is false', () => { - instance = createTweenGroupInstance({ - appear: false, - }); - children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'p')[0]; - expect(children.style.opacity).to.be(''); - }); - - it('add and remove', (done) => { - instance = createTweenGroupInstance(); - setTimeout(() => { - instance.add(); - children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'p'); - console.log('length is 2:', children.length); - expect(children.length).to.be(2); - setTimeout(() => { - instance.removeAll(); - setTimeout(() => { - children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'p'); - console.log('length is 0:', children.length); - expect(children.length).to.be(0); - done(); - }, 500); - }, 500); - }, 500); - }); -}); diff --git a/tests/tweenOneGroup.test.jsx b/tests/tweenOneGroup.test.jsx new file mode 100644 index 00000000..07f992f6 --- /dev/null +++ b/tests/tweenOneGroup.test.jsx @@ -0,0 +1,102 @@ +/* eslint no-console:0 */ +import React from 'react'; +import Enzyme, { mount } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +import TweenOneGroup from '../src/TweenOneGroup'; + +Enzyme.configure({ adapter: new Adapter() }); + +const TweenOneGroupComp = (props) => { + return ( + + + + ); +}; + +describe('rc-tween-one-group', () => { + let instance; + function getFloat(str) { + return parseFloat(str); + } + + it('should render children', (done) => { + instance = mount( + +

a

+
, + ); + const children = instance.find('p'); + console.log(children.length, instance.find('p')); + expect(children.length).toBe(1); + done(); + }); + it('appear is false', () => { + instance = mount( + +

a

+
, + ); + const children = instance.find('p').instance(); + console.log('opacity:', children.style.opacity); + expect(children.style.opacity).toBe(''); + }); + it('component is null', () => { + instance = mount( +
+ +

a

+
+
, + ); + const children = instance.find('.wrapper').instance().children[0]; + console.log('tagName:', children.tagName); + expect(children.tagName).toEqual('P'); + }); + it('is normal tween', (done) => { + instance = mount( + +

a

+
, + ); + + setTimeout(() => { + const children = instance.find('p').instance(); + console.log('marginLeft < 100:', children.style.marginLeft); + expect(getFloat(children.style.marginLeft)).toBeLessThan(100); + setTimeout(() => { + console.log('marginLeft is 0:', children.style.marginLeft); + expect(getFloat(children.style.marginLeft)).toBe(0); + done(); + }, 500); + }, 50); + }); + it('is switch children', (done) => { + instance = mount(); + let children = instance.find('p').children(); + console.log('children length:', children.length); + expect(children.length).toBe(0); + setTimeout(() => { + instance.setProps({ + children: [

a

,

b

], + }); + + setTimeout(() => { + children = instance.find('.wrapper').instance().children[0].children; + console.log('children length:', children.length); + expect(children.length).toBe(2); + + instance.setProps({ + children: [

a

], + }); + setTimeout(() => { + children = instance.find('.wrapper').instance().children[0].children; + console.log('children length:', children.length); + expect(children.length).toBe(1); + done(); + }, 500); + }, 500); + }, 50); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index f5622bd2..1b644d5b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,31 +1,28 @@ { "compilerOptions": { - "outDir": "build/dist", + "target": "esnext", "module": "esnext", - "target": "es2016", - "lib": ["es6", "dom"], - "sourceMap": true, - "jsx": "react", - "allowSyntheticDefaultImports": true, "moduleResolution": "node", - "rootDirs": ["/src", "./typings"], - "forceConsistentCasingInFileNames": true, - "noImplicitReturns": true, - "suppressImplicitAnyIndexErrors": true, - "noUnusedLocals": true, - "allowJs": true, - "experimentalDecorators": true + "importHelpers": true, + "jsx": "react", + "esModuleInterop": true, + "sourceMap": true, + "baseUrl": "./", + "strict": true, + "paths": { + "@/*": ["src/*"], + "@@/*": ["src/.umi/*"], + "rc-tween-one": ["src/index.tsx"] + }, + "allowSyntheticDefaultImports": true }, - "include": ["./src"], "exclude": [ "node_modules", - "build", - "scripts", - "acceptance-tests", - "webpack", - "jest", - "src/setupTests.ts", - "tslint:latest", - "tslint-config-prettier" + "lib", + "es", + "dist", + "typings", + "**/__test__", + "test" ] } diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 125e217e..00000000 --- a/tslint.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": ["tslint:latest", "tslint-react", "tslint-config-prettier"], - "rules": { - "no-var-requires": false, - "no-submodule-imports": false, - "object-literal-sort-keys": false, - "jsx-no-lambda": false, - "no-implicit-dependencies": false, - "no-console": false - } -} diff --git a/typings/AnimObject.d.ts b/typings/AnimObject.d.ts deleted file mode 100644 index 87841492..00000000 --- a/typings/AnimObject.d.ts +++ /dev/null @@ -1,130 +0,0 @@ -type IEaseCallBack = ((t: number, b: number, c: number, d: number) => number); - -export declare type IAnimType = 'to' | 'from'; - -export declare type IEaseType = 'linear' | - 'easeInSine' | 'easeOutSine' | 'easeInOutSine' | - 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | - 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' | - 'easeInQuart' | 'easeOutQuart' | 'easeInOutQuart' | - 'easeInQuint' | 'easeOutQuint' | 'easeInOutQuint' | - 'easeInExpo' | 'easeInOutExpo' | 'easeInOutExpo' | - 'easeInCirc' | 'easeOutCirc' | 'easeInOutCirc' | - 'easeInBack' | 'easeOutBack' | 'easeInOutBack' | - 'easeInElastic' | 'easeOutElastic' | 'easeInOutElastic' | - 'easeInBounce' | 'easeOutBounce' | 'easeInOutBounce' | - IEaseCallBack; // TweenOne ease path; - -export interface IBezierProps { - type?: string; - autoRotate?: boolean; - vars: { x: number, y: number }[]; -} - -export interface IChildrenProps { - value: number; - floatLength?: number; - formatMoney?: { thousand: string, decimal: string }; -} - -export interface IStyleAnimProps { - [key: string]: any; - bezier?: IBezierProps; - SVGDraw?: number | string;// DrawPlugin - // Children - Children?: IChildrenProps; - // path - path?: string; - // transform - x?: number | string; - y?: number | string; - z?: number | string; - translateX?: number | string; - translateY?: number | string; - translateZ?: number | string; - rotate?: number | string; - rotateX?: number | string; - rotateY?: number | string; - scale?: number | string; - scaleX?: number | string; - scaleY?: number | string; - transformOrigin?: number | string; - // filter - grayScale?: number; - sepia?: number; - hueRotate?: string; - invert?: number; - brightness?: number; - contrast?: number; - saturate?: number; - blur?: string; - // basic - width?: number | string; - maxWidth?: number | string; - minWidth?: number | string; - height?: number | string; - maxHeight?: number | string; - minHeight?: number | string; - lineHeight?: number | string; - opacity?: number | string; - top?: number | string; - right?: number | string; - bottom?: number | string; - left?: number | string; - marginTop?: number | string; - marginRight?: number | string; - marginBottom?: number | string; - marginLeft?: number | string; - paddingTop?: number | string; - paddingRight?: number | string; - paddingBottom?: number | string; - paddingLeft?: number | string; - color?: string; - backgroundColor?: string; - borderWidth?: number | string; - borderRadius?: number | string; - borderColor?: string; - boxShadow?: string; - textShadow?: string; - // svg style - storkeWidth?: number; - fill?: string; - stroke?: string; - strokeDashoffset?: number; - strokeDasharray?: string; -} - -export interface IAnimObject extends IStyleAnimProps { - type?: IAnimType; - duration?: number; - delay?: number; - repeat?: number; - repeatDelay?: number; - appearTo?: number; - yoyo?: boolean; - ease?: IEaseType; - style?: IStyleAnimProps; - // morphPlugin - points?: string; - d?: string; - // attr svg - cx?: number; - cy?: number; - r?: number; - x1?: number; - y1?: number; - x2?: number; - y2?: number; - rx?: number; - ry?: number; - dx?: number; - dy?: number; - offset?: number | string; - stdDeviation?: number | string; - stopColor?: string; - stopOpacity?: number; - onStart?: (e: { index: number, target: HTMLElement }) => void; - onUpdate?: (e: { index: number, target: HTMLElement, ratio: number }) => void; - onComplete?: (e: { index: number, target: HTMLElement }) => void; - onRepeat?: (e: { index: number, target: HTMLElement }) => void; -} \ No newline at end of file diff --git a/typings/Tween.d.ts b/typings/Tween.d.ts deleted file mode 100644 index d8612ea5..00000000 --- a/typings/Tween.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { IAnimObject } from './AnimObject'; - -export default class RcTweenOneGroup { - constructor(target: Object, animation: IAnimObject | IAnimObject[], attr?: 'style' | 'attr'); - init: () => void; - frame: (moment?: Number) => void; - target: Object; - progressTime: Number; - totalTime: Number; -} \ No newline at end of file diff --git a/typings/TweenOneGroup.d.ts b/typings/TweenOneGroup.d.ts deleted file mode 100644 index d98da140..00000000 --- a/typings/TweenOneGroup.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from 'react'; - -import { IAnimObject, IEaseCallBack } from './AnimObject'; - -import { Omit } from './index'; - -export interface IGroupProps extends Omit, 'onChange'> { - appear?: boolean; - enter?: IAnimObject | IAnimObject[] | ((key: string, index: number) => IAnimObject); - leave?: IAnimObject | IAnimObject[] | ((key: string, index: number) => IAnimObject); - animatingClassName?: string[] | [string, string]; - exclusive?: boolean; - resetStyle?: boolean; - onEnd?: (e: { key: string, type: string }) => void; - component?: string | React.ReactNode; - componentProps?: {}; -} - -export default class RcTweenOneGroup extends React.Component>{ } \ No newline at end of file diff --git a/typings/index.d.ts b/typings/index.d.ts deleted file mode 100644 index 95b4d7ae..00000000 --- a/typings/index.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -// Type definitions for rc-tween-one 2.2 -// Project: https://github.com/react-component/tween-one -// Definitions by: jljsj33 -// Definitions: https://github.com/react-component/tween-one -import * as React from 'react'; - -import Group from './TweenOneGroup'; -import Tween from './Tween'; -import { IAnimObject, IEaseCallBack } from './AnimObject'; - -export type Omit = Pick>; - -export declare type IAttrType = 'style' | 'attr'; - -export interface IChangeProps { - moment?: number; - target?: HTMLElement; - index?: number; - mode?: string; - timelineMode?: string; -} - -export interface IProps extends Omit, 'onChange'> { - animation?: IAnimObject | IAnimObject[]; - paused?: boolean; - reverse?: boolean; - reverseDelay?: number; - repeat?: number; - yoyo?: boolean; - onChange?: (e: IChangeProps) => void; - moment?: number; - attr?: IAttrType, - resetStyle?: boolean, - component?: string | React.ReactNode; - componentProps?: {}; -} - -export const TweenOneGroup: typeof Group; - -export default class RcTweenOne extends React.Component> { - static easing: { - path(path: string, parame?: { rect?: number, lengthPixel?: number }): IEaseCallBack; - }; - static plugins: { - push(plugin: any): void; - } - static TweenOneGroup: typeof Group; - - static Tween: typeof Tween; -} From 517eb45ac69d6ea92a57bf9e128f20e3f2a9c47e Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 18:22:17 +0800 Subject: [PATCH 02/69] fix lint --- package.json | 4 +-- src/TweenOne.tsx | 10 +++++-- src/TweenOneGroup.tsx | 52 +++++++++++++++++++----------------- src/index.tsx | 6 ++--- src/plugin/ChildrenPlugin.ts | 29 ++++++++++---------- src/plugin/SvgDrawPlugin.ts | 2 +- src/plugin/SvgMorphPlugin.ts | 2 +- src/type.ts | 10 +++---- src/utils/group.ts | 13 ++++----- 9 files changed, 70 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index 2bea8f3d..51a4916a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "version": "3.0.0-beta.0", "description": "tween-one anim component for react", "typings": "es/index.d.ts", - "type": "module", "engines": { "node": ">=8.x" }, @@ -53,7 +52,7 @@ "test": "umi-test test", "test:coverage": "umi-test --coverage", "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish", - "lint": "eslint src/ --ext .tsx,.ts", + "lint": "eslint src/ --fix --ext .tsx,.ts", "lint:tsc": "tsc -p tsconfig.json --noEmit", "now-build": "npm run docs:build" }, @@ -70,6 +69,7 @@ "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.0.2", "enzyme-to-json": "^3.4.0", + "eslint": "^7.14.0", "father": "^2.22.6", "father-build": "^1.18.6", "gh-pages": "^3.1.0", diff --git a/src/TweenOne.tsx b/src/TweenOne.tsx index 4cebda73..7382ade8 100644 --- a/src/TweenOne.tsx +++ b/src/TweenOne.tsx @@ -81,7 +81,7 @@ const TweenOne: TweenOneRef = React.forwardRef( .join(';'); dom.setAttribute('style', styleStr); // dom.style.cssText = styleStr; - delete dom._tweenOneVars; + delete dom._tweenOneVars; // eslint-disable-line no-underscore-dangle } animRef.current = animation && @@ -99,6 +99,11 @@ const TweenOne: TweenOneRef = React.forwardRef( }); prevAnim.current = animation; } + return () => { + if (animRef.current) { + animRef.current.kill(); + } + }; }, [animation]); const refFunc = (c: any) => { @@ -127,7 +132,8 @@ const TweenOne: TweenOneRef = React.forwardRef( ref: refFunc, className: newClassName, }); - } else if (!component) { + } + if (!component) { console.warn('Warning: component is null, children must be ReactElement.'); return children; } diff --git a/src/TweenOneGroup.tsx b/src/TweenOneGroup.tsx index 6dcc4a92..3ce79543 100644 --- a/src/TweenOneGroup.tsx +++ b/src/TweenOneGroup.tsx @@ -34,12 +34,12 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop const currentChildren = useRef(cChild); const [children, setChild] = useState(cChild); - const getTweenChild = (child: ReactElement, props = {}) => { + const getTweenChild = (child: ReactElement, p = {}) => { const key: string | number = child.key as string; saveTweenTag.current[key] = React.createElement( TweenOne, { - ...props, + ...p, key, component: null, }, @@ -54,16 +54,16 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop } return className; }; - const changeChildren = (nextChildren: ReactElement[], currentChildren: ReactElement[]) => { - const newChildren: ReactElement[] = mergeChildren(currentChildren, nextChildren); + const changeChildren = (nextChildren: ReactElement[], currentChild: ReactElement[]) => { + const newChildren: ReactElement[] = mergeChildren(currentChild, nextChildren); keysToEnter.current = []; keysToLeave.current = []; - nextChildren.forEach((c) => { + nextChildren.forEach(c => { if (!c) { return; } - const key = c.key; - const hasPrev = findChildInChildrenByKey(currentChildren, key); + const { key } = c; + const hasPrev = findChildInChildrenByKey(currentChild, key); // 如果当前 key 已存在 saveTweenTag 里,,刷新 child; if (key && saveTweenTag.current[key]) { saveTweenTag.current[key] = React.cloneElement(saveTweenTag.current[key], {}, c); @@ -73,11 +73,11 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop } }); - currentChildren.forEach((c) => { + currentChild.forEach(c => { if (!c) { return; } - const key = c.key; + const { key } = c; const hasNext = findChildInChildrenByKey(nextChildren, key); if (!hasNext && key) { keysToLeave.current.push(key); @@ -96,8 +96,13 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop } }; - const onChange = (animation: IAnimObject, key: string | number | null, type: string, obj: ICallBack) => { - const length = dataToArray(animation).length; + const onChange = ( + animation: IAnimObject, + key: string | number | null, + type: string, + obj: ICallBack, + ) => { + const { length } = dataToArray(animation); const tag = obj.targets as IObject; const classIsSvg = typeof tag!.className === 'object' && 'baseVal' in tag!.className; const isEnter = type === 'enter' || type === 'appear'; @@ -118,10 +123,10 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop } } else if (type === 'leave') { keysToLeave.current.splice(keysToLeave.current.indexOf(key), 1); - currentChildren.current = currentChildren.current.filter((child) => key !== child.key); + currentChildren.current = currentChildren.current.filter(child => key !== child.key); if (!keysToLeave.current.length) { - const currentChildrenKeys = currentChildren.current.map((item) => item.key); - Object.keys(saveTweenTag.current).forEach(($key) => { + const currentChildrenKeys = currentChildren.current.map(item => item.key); + Object.keys(saveTweenTag.current).forEach($key => { if (currentChildrenKeys.indexOf($key) === -1) { delete saveTweenTag.current[$key]; } @@ -130,8 +135,7 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop setChild(currentChildren.current); } } - const _obj = { key, type }; - onEnd(_obj); + onEnd({ key, type }); } }; const getCoverAnimation = (child: ReactElement, i: number, type: string) => { @@ -151,12 +155,11 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop key: child.key, animation: animate, onChange: onChangeCb, - resetStyle: resetStyle, + resetStyle, className, }; if ( - child.key && - keysToEnter.current.concat(keysToLeave.current).indexOf(child.key) >= 0 || + (child.key && keysToEnter.current.concat(keysToLeave.current).indexOf(child.key) >= 0) || (!oneEnter.current && animation) ) { if (child.key && !saveTweenTag.current[child.key]) { @@ -164,8 +167,7 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop } } - const children = getTweenChild(child, p); - return children; + return getTweenChild(child, p); }; useEffect(() => { if (oneEnter.current) { @@ -195,7 +197,8 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop const { key } = child; if (keysToLeave.current.indexOf(key) >= 0) { return getCoverAnimation(child, i, 'leave'); - } else if ( + } + if ( (keysToEnter.current.indexOf(key) >= 0 || (isTween.current[key] && keysToLeave.current.indexOf(key) === -1)) && !(isTween.current[key] === 'enter' && saveTweenTag.current[key]) @@ -206,7 +209,8 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop * 3. 状态为 enter 且 tweenTag 里有值时,不执行重载动画属性,直接调用 tweenTag 里的。 */ return getCoverAnimation(child, i, 'enter'); - } else if (!oneEnter.current) { + } + if (!oneEnter.current) { return getCoverAnimation(child, i, 'appear'); } return saveTweenTag.current[key]; @@ -220,4 +224,4 @@ const TweenOneGroup: TweenOneGroupRef = React.forwardRef((prop TweenOneGroup.displayName = 'TweenOneGroup'; TweenOneGroup.isTweenOneGroup = true; -export default TweenOneGroup \ No newline at end of file +export default TweenOneGroup; diff --git a/src/index.tsx b/src/index.tsx index c9b0152f..6cf42285 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,7 @@ -import TweenOne from './TweenOne'; import { Ticker, Plugins, Easing } from 'tween-one'; +import TweenOne from './TweenOne'; + +export * from './type'; export { Easing, Ticker, Plugins }; @@ -8,5 +10,3 @@ TweenOne.ticker = Ticker; TweenOne.easing = Easing; export default TweenOne; - -export * from './type'; \ No newline at end of file diff --git a/src/plugin/ChildrenPlugin.ts b/src/plugin/ChildrenPlugin.ts index ced7f6fe..4ef8103e 100644 --- a/src/plugin/ChildrenPlugin.ts +++ b/src/plugin/ChildrenPlugin.ts @@ -1,4 +1,3 @@ - interface IFormatMoney { thousand?: string; decimal?: string; @@ -11,14 +10,20 @@ interface IVars { class ChildrenPlugin { static key: string = 'innerHTML'; + static className: string = 'Children'; + start?: IVars; + startAt?: IObject; + target?: HTMLElement; + constructor(public vars: IVars, public key: string) { this.vars = vars; this.key = key; } + getAnimStart = () => { const { target, vars, startAt, key } = this; const { formatMoney } = vars; @@ -29,13 +34,11 @@ class ChildrenPlugin { const rep = new RegExp(`\\${opts.thousand}`, 'g'); this.start = startAt![key] || { - value: - parseFloat( - this.target!.innerHTML.replace(rep, '').replace(opts.decimal, '.'), - ) || 0, + value: parseFloat(target!.innerHTML.replace(rep, '').replace(opts.decimal, '.')) || 0, }; return this.start; }; + toMoney = (v: string, _opts: IFormatMoney) => { const opts = { thousand: _opts.thousand || ',', @@ -46,12 +49,13 @@ class ChildrenPlugin { const base = Math.abs(parseInt(numberArray[0], 10)).toString(); const mod = base.length > 3 ? base.length % 3 : 0; const decimal = numberArray[1]; - return `${negative}${ - mod ? `${base.substr(0, mod)}${opts.thousand}` : '' - }${base.substr(mod).replace(/(\d{3})(?=\d)/g, `$1${opts.thousand}`)}${ + return `${negative}${mod ? `${base.substr(0, mod)}${opts.thousand}` : ''}${base + .substr(mod) + .replace(/(\d{3})(?=\d)/g, `$1${opts.thousand}`)}${ decimal ? `${opts.decimal}${decimal}` : '' }`; }; + render = (ratio: number) => { const { value, floatLength, formatMoney } = this.vars; let v: number | string = (value - this.start!.value) * ratio + this.start!.value; @@ -60,15 +64,12 @@ class ChildrenPlugin { v = v.toFixed(floatLength); const numberArray = v.toString().split('.'); let decimal = numberArray[1] || ''; - decimal = - decimal.length > floatLength - ? decimal.substring(0, floatLength) - : decimal; + decimal = decimal.length > floatLength ? decimal.substring(0, floatLength) : decimal; const l = floatLength - decimal.length; if (l) { Array(l) .fill(0) - .forEach((num) => { + .forEach(num => { decimal += `${num}`; }); } @@ -78,7 +79,7 @@ class ChildrenPlugin { } } v = formatMoney ? this.toMoney(`${v}`, formatMoney) : v; - return v + return v; }; } diff --git a/src/plugin/SvgDrawPlugin.ts b/src/plugin/SvgDrawPlugin.ts index 36a36e8f..42e6e57c 100644 --- a/src/plugin/SvgDrawPlugin.ts +++ b/src/plugin/SvgDrawPlugin.ts @@ -1,3 +1,3 @@ import SvgDrawPlugin from 'tween-one/src/plugins/SvgDrawPlugin'; -export default SvgDrawPlugin; \ No newline at end of file +export default SvgDrawPlugin; diff --git a/src/plugin/SvgMorphPlugin.ts b/src/plugin/SvgMorphPlugin.ts index 01b46c8c..665014ee 100644 --- a/src/plugin/SvgMorphPlugin.ts +++ b/src/plugin/SvgMorphPlugin.ts @@ -1,3 +1,3 @@ import SvgMorph from 'tween-one/src/plugins/SvgMorphPlugin'; -export default SvgMorph; \ No newline at end of file +export default SvgMorph; diff --git a/src/type.ts b/src/type.ts index 345dc114..dd314f9d 100644 --- a/src/type.ts +++ b/src/type.ts @@ -9,8 +9,8 @@ export interface ICallBack { repeat?: number; timelineMoment?: number; vars?: IObject | IObject[]; - targets?: IObject | IObject[] -}; + targets?: IObject | IObject[]; +} export type AnimObjectOrArray = AnimObject | AnimObject[]; @@ -44,7 +44,7 @@ export interface IGroupProps extends Omit, 'onChange'> appear?: boolean; enter?: IAnimObject; leave?: IAnimObject; - animatingClassName?: string[] | [string, string]; + animatingClassName?: string[]; exclusive?: boolean; resetStyle?: boolean; onEnd?: (e: { key?: string | React.ReactText; type?: string }) => void; @@ -53,7 +53,7 @@ export interface IGroupProps extends Omit, 'onChange'> | React.ClassType> | null | undefined; - componentProps?: {}; + componentProps?: IObject; } export interface TweenOneRef extends React.ForwardRefExoticComponent { @@ -65,4 +65,4 @@ export interface TweenOneRef extends React.ForwardRefExoticComponent { export interface TweenOneGroupRef extends React.ForwardRefExoticComponent { isTweenOneGroup?: boolean; -} \ No newline at end of file +} diff --git a/src/utils/group.ts b/src/utils/group.ts index 489c35ce..0bcfc642 100644 --- a/src/utils/group.ts +++ b/src/utils/group.ts @@ -8,7 +8,7 @@ export const windowIsUndefined = !( export function toArrayChildren(children: any) { const ret: any[] = []; - React.Children.forEach(children, (c) => { + React.Children.forEach(children, c => { ret.push(c); }); return ret; @@ -27,7 +27,7 @@ export function dataToArray(vars: any) { export function findChildInChildrenByKey(children: ReactElement[], key: string | number | null) { let ret: any = null; if (children) { - children.forEach((c) => { + children.forEach(c => { if (ret || !c) { return; } @@ -46,7 +46,7 @@ export function mergeChildren(prev: ReactElement[], next: ReactElement[]) { const nextChildrenPending: any = {}; let pendingChildren: any[] = []; let followChildrenKey: string | number | null = null; - prev.forEach((c) => { + prev.forEach(c => { if (!c) { return; } @@ -64,11 +64,12 @@ export function mergeChildren(prev: ReactElement[], next: ReactElement[]) { ret = ret.concat(pendingChildren); } - next.forEach((c) => { + next.forEach(c => { if (!c) { return; } - if (c.key && nextChildrenPending.hasOwnProperty(c.key)) { // eslint-disable-line no-prototype-builtins + if (c.key && nextChildrenPending.hasOwnProperty(c.key)) { + // eslint-disable-line no-prototype-builtins ret = ret.concat(nextChildrenPending[c.key]); } ret.push(c); @@ -95,4 +96,4 @@ export function transformArguments(arg: any, key: string | number | null, i: num export function getChildrenFromProps(props: IObject) { return props && props.children; -} \ No newline at end of file +} From 254e3407ace9b0abd5e25e8336998cbdd2335a8f Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 18:43:30 +0800 Subject: [PATCH 03/69] fix compile --- import.d.ts | 13 ------------- index.d.ts | 25 +------------------------ src/TweenOneGroup.tsx | 2 +- src/plugin/ChildrenPlugin.ts | 3 ++- src/type.ts | 6 +++++- src/utils/group.ts | 2 ++ tsconfig.json | 1 + typings/global/import.d.ts | 6 ++++++ typings/global/index.d.ts | 20 ++++++++++++++++++++ 9 files changed, 38 insertions(+), 40 deletions(-) delete mode 100644 import.d.ts create mode 100644 typings/global/import.d.ts create mode 100644 typings/global/index.d.ts diff --git a/import.d.ts b/import.d.ts deleted file mode 100644 index 912a0106..00000000 --- a/import.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as CSS from 'csstype'; -import * as TweenOne from 'tween-one'; - -declare module 'csstype' { - interface Properties { - [key: string]: any; - } -} -declare module 'TweenOne' { - interface Ticker { - [key: string]: any; - } -} diff --git a/index.d.ts b/index.d.ts index 3417d388..8e20c037 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,24 +1 @@ - -declare module '*.css'; -declare module '*.less'; -declare module 'style-utils'; -declare module 'tween-functions'; - -declare module 'rc-tween-one'; -declare module 'rc-tween-one/src/plugin/ChildrenPlugin'; -declare module 'rc-tween-one/src/plugin/PathMotionPlugin'; -declare module 'rc-tween-one/src/plugin/SvgDrawPlugin'; -declare module 'rc-tween-one/src/plugin/SvgMorphPlugin'; -declare module 'rc-tween-one/src/TweenOneGroup'; - - -interface IObject { - [key: string]: any -} -interface Element { - _tweenOneVars: any; -} - -interface Ticker { - [key: string]: any; -} \ No newline at end of file +/// diff --git a/src/TweenOneGroup.tsx b/src/TweenOneGroup.tsx index 3ce79543..dfae0c60 100644 --- a/src/TweenOneGroup.tsx +++ b/src/TweenOneGroup.tsx @@ -1,5 +1,5 @@ import React, { useRef, useEffect, useState, createElement, ReactElement, ReactText } from 'react'; -import { IGroupProps, IAnimObject, TweenOneGroupRef, ICallBack } from './type'; +import { IGroupProps, IAnimObject, TweenOneGroupRef, ICallBack, IObject } from './type'; import { dataToArray, getChildrenFromProps, diff --git a/src/plugin/ChildrenPlugin.ts b/src/plugin/ChildrenPlugin.ts index 4ef8103e..d3163bb7 100644 --- a/src/plugin/ChildrenPlugin.ts +++ b/src/plugin/ChildrenPlugin.ts @@ -1,3 +1,4 @@ +import { IObject } from '../type'; interface IFormatMoney { thousand?: string; decimal?: string; @@ -69,7 +70,7 @@ class ChildrenPlugin { if (l) { Array(l) .fill(0) - .forEach(num => { + .forEach((num) => { decimal += `${num}`; }); } diff --git a/src/type.ts b/src/type.ts index dd314f9d..d010f235 100644 --- a/src/type.ts +++ b/src/type.ts @@ -1,6 +1,10 @@ import React from 'react'; -import { IAnimObject as AnimObject, IObject, IMode, ITimelineCallBack } from 'tween-one'; +import { IAnimObject as AnimObject, IMode, ITimelineCallBack } from 'tween-one'; + +export interface IObject { + [key: string]: any +} export interface ICallBack { mode?: IMode; moment?: number; diff --git a/src/utils/group.ts b/src/utils/group.ts index 0bcfc642..5ffadf35 100644 --- a/src/utils/group.ts +++ b/src/utils/group.ts @@ -1,5 +1,7 @@ import React, { ReactElement } from 'react'; +import { IObject } from '../type'; + export const windowIsUndefined = !( typeof window !== 'undefined' && window.document && diff --git a/tsconfig.json b/tsconfig.json index 1b644d5b..c0eb7c0d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "moduleResolution": "node", "importHelpers": true, "jsx": "react", + "typeRoots": ["./typings"], "esModuleInterop": true, "sourceMap": true, "baseUrl": "./", diff --git a/typings/global/import.d.ts b/typings/global/import.d.ts new file mode 100644 index 00000000..1b73c187 --- /dev/null +++ b/typings/global/import.d.ts @@ -0,0 +1,6 @@ +import * as CSS from 'csstype'; +declare module 'csstype' { + interface Properties { + [key: string]: any; + } +} \ No newline at end of file diff --git a/typings/global/index.d.ts b/typings/global/index.d.ts new file mode 100644 index 00000000..070295c4 --- /dev/null +++ b/typings/global/index.d.ts @@ -0,0 +1,20 @@ +/// +declare module '*.css'; +declare module '*.less'; +declare module 'style-utils'; +declare module 'tween-functions'; +declare module 'raf'; +declare module 'flubber'; + + +declare module 'rc-tween-one'; +declare module 'rc-tween-one/src/plugin/ChildrenPlugin'; +declare module 'rc-tween-one/src/plugin/PathMotionPlugin'; +declare module 'rc-tween-one/src/plugin/SvgDrawPlugin'; +declare module 'rc-tween-one/src/plugin/SvgMorphPlugin'; +declare module 'rc-tween-one/src/TweenOneGroup'; + + +interface Element { + _tweenOneVars: any; +} From 243ede24a54a434359a4738415432b26a7c02ba0 Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 19:54:04 +0800 Subject: [PATCH 04/69] fix willUnmount --- src/TweenOne.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/TweenOne.tsx b/src/TweenOne.tsx index 7382ade8..8849f28a 100644 --- a/src/TweenOne.tsx +++ b/src/TweenOne.tsx @@ -1,4 +1,4 @@ -import React, { useRef, createElement, useLayoutEffect } from 'react'; +import React, { useRef, createElement, useLayoutEffect, useEffect } from 'react'; import { findDOMNode } from 'react-dom'; import TweenOneJS, { Tween } from 'tween-one'; import { toStyleUpperCase, stylesToCss } from 'style-utils'; @@ -65,6 +65,7 @@ const TweenOne: TweenOneRef = React.forwardRef( } // 动画写在标签上,手动对比; if (!objectEqual(animation, prevAnim.current)) { + console.log('update animation'); const dom = domRef.current instanceof Element ? domRef.current : findDOMNode(domRef.current); @@ -99,12 +100,16 @@ const TweenOne: TweenOneRef = React.forwardRef( }); prevAnim.current = animation; } - return () => { + return; + }, [animation]); + useEffect( + () => () => { if (animRef.current) { animRef.current.kill(); } - }; - }, [animation]); + }, + [], + ); const refFunc = (c: any) => { domRef.current = c; From d288c9a8440494cd9c1223dc8aef094e67340974 Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 19:57:01 +0800 Subject: [PATCH 05/69] update ChildrenPlugin constructor --- src/plugin/ChildrenPlugin.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugin/ChildrenPlugin.ts b/src/plugin/ChildrenPlugin.ts index d3163bb7..f2459a0f 100644 --- a/src/plugin/ChildrenPlugin.ts +++ b/src/plugin/ChildrenPlugin.ts @@ -20,10 +20,7 @@ class ChildrenPlugin { target?: HTMLElement; - constructor(public vars: IVars, public key: string) { - this.vars = vars; - this.key = key; - } + constructor(public vars: IVars, public key: string) {} getAnimStart = () => { const { target, vars, startAt, key } = this; From 61400346d170dd00d2c897dd20230a759be0e104 Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 20:05:23 +0800 Subject: [PATCH 06/69] lint fix --- src/TweenOne.tsx | 2 +- src/plugin/ChildrenPlugin.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/TweenOne.tsx b/src/TweenOne.tsx index 8849f28a..e671f874 100644 --- a/src/TweenOne.tsx +++ b/src/TweenOne.tsx @@ -100,7 +100,7 @@ const TweenOne: TweenOneRef = React.forwardRef( }); prevAnim.current = animation; } - return; + return () => {}; }, [animation]); useEffect( () => () => { diff --git a/src/plugin/ChildrenPlugin.ts b/src/plugin/ChildrenPlugin.ts index f2459a0f..9bb305b7 100644 --- a/src/plugin/ChildrenPlugin.ts +++ b/src/plugin/ChildrenPlugin.ts @@ -1,4 +1,5 @@ import { IObject } from '../type'; + interface IFormatMoney { thousand?: string; decimal?: string; @@ -20,6 +21,7 @@ class ChildrenPlugin { target?: HTMLElement; + // eslint-disable-next-line no-useless-constructor,no-empty-function constructor(public vars: IVars, public key: string) {} getAnimStart = () => { @@ -67,7 +69,7 @@ class ChildrenPlugin { if (l) { Array(l) .fill(0) - .forEach((num) => { + .forEach(num => { decimal += `${num}`; }); } From 6f45c84fbda9bb068e49000fb23d0dcb720e3a66 Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 20:32:07 +0800 Subject: [PATCH 07/69] update prepublishOnly --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 51a4916a..63f39041 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"", "test": "umi-test test", "test:coverage": "umi-test --coverage", - "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish", + "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish --any-branch", "lint": "eslint src/ --fix --ext .tsx,.ts", "lint:tsc": "tsc -p tsconfig.json --noEmit", "now-build": "npm run docs:build" From 6a195180072c7c3225d7732c490a691ff79aa8c5 Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 20:32:50 +0800 Subject: [PATCH 08/69] 3.0.0-beta.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 63f39041..a7411039 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-tween-one", - "version": "3.0.0-beta.0", + "version": "3.0.0-beta.1", "description": "tween-one anim component for react", "typings": "es/index.d.ts", "engines": { From 9c6ccf717de494876d49aaf9844805434e6b7000 Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 20:35:15 +0800 Subject: [PATCH 09/69] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a7411039..63f39041 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-tween-one", - "version": "3.0.0-beta.1", + "version": "3.0.0-beta.0", "description": "tween-one anim component for react", "typings": "es/index.d.ts", "engines": { From 70f7a7bc9dcf343cbe628b77365496ee5ea3a81a Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 20:35:32 +0800 Subject: [PATCH 10/69] 3.0.0-beta.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 63f39041..a7411039 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-tween-one", - "version": "3.0.0-beta.0", + "version": "3.0.0-beta.1", "description": "tween-one anim component for react", "typings": "es/index.d.ts", "engines": { From e7859fdc3e25584593523cd35ad76667b31622ed Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 20:36:22 +0800 Subject: [PATCH 11/69] 3.0.0-beta.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a7411039..35a0d175 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-tween-one", - "version": "3.0.0-beta.1", + "version": "3.0.0-beta.2", "description": "tween-one anim component for react", "typings": "es/index.d.ts", "engines": { From af80998e614df22f8594657bf5223592c0b8c1b4 Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 27 Nov 2020 22:01:30 +0800 Subject: [PATCH 12/69] add husky --- package.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/package.json b/package.json index 35a0d175..22c44a7e 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "father": "^2.22.6", "father-build": "^1.18.6", "gh-pages": "^3.1.0", + "husky": "^4.3.0", "np": "^6.0.3", "prettier": "^2.1.2", "rc-scroll-anim": "^2.7.6", @@ -89,5 +90,12 @@ "@babel/runtime": "^7.11.1", "style-utils": "^0.3.4", "tween-one": "^1.0.9" + }, + "husky": { + "hooks": { + "pre-commit": [ + "npm run lint" + ] + } } } From 85aad99b438d5a77fde0d42032141aa2c2ead184 Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 1 Dec 2020 19:39:30 +0800 Subject: [PATCH 13/69] add declaration --- index.js | 1 - tsconfig.json | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 index.js diff --git a/index.js b/index.js deleted file mode 100644 index fd4d7e5c..00000000 --- a/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./src/'); diff --git a/tsconfig.json b/tsconfig.json index c0eb7c0d..3d0aeab3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "importHelpers": true, "jsx": "react", "typeRoots": ["./typings"], + "declaration": true, "esModuleInterop": true, "sourceMap": true, "baseUrl": "./", From cb6ce1e427477a04cc6acbbc9a2242c1d1801c7f Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 1 Dec 2020 19:40:25 +0800 Subject: [PATCH 14/69] 3.0.0-beta.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 22c44a7e..396e9d56 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-tween-one", - "version": "3.0.0-beta.2", + "version": "3.0.0-beta.3", "description": "tween-one anim component for react", "typings": "es/index.d.ts", "engines": { From 1e8ca01b636f971b6e1675d77deaff654f56a8c9 Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 1 Dec 2020 20:27:10 +0800 Subject: [PATCH 15/69] update tween-one --- .umirc.ts | 3 ++- docs/demo/group.md | 6 +++--- docs/examples/animParam.tsx | 10 +++++----- docs/examples/group.tsx | 2 +- docs/examples/numberDance.tsx | 2 +- docs/examples/pathMotion.tsx | 2 +- docs/examples/simple.tsx | 2 +- docs/examples/svg.tsx | 2 +- docs/examples/svgDraw.tsx | 2 +- docs/index.md | 6 +++--- package.json | 2 +- src/plugin/PathMotionPlugin.ts | 2 +- src/plugin/SvgDrawPlugin.ts | 2 +- src/plugin/SvgMorphPlugin.ts | 2 +- typings/global/index.d.ts | 10 +++++----- 15 files changed, 28 insertions(+), 27 deletions(-) diff --git a/.umirc.ts b/.umirc.ts index fe9937d3..ce31db61 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -10,6 +10,7 @@ export default defineConfig({ 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', outputPath: '.doc', alias: { - 'rc-tween-one/src': path.join(__dirname, 'src'), + 'rc-tween-one/es': path.join(__dirname, 'src'), + 'rc-tween-one/lib': path.join(__dirname, 'src'), }, }); \ No newline at end of file diff --git a/docs/demo/group.md b/docs/demo/group.md index d79f3afc..5b518d65 100644 --- a/docs/demo/group.md +++ b/docs/demo/group.md @@ -6,7 +6,7 @@ order: 8 ### appear = false ```jsx -import TweenOneGroup from 'rc-tween-one/src/TweenOneGroup'; +import TweenOneGroup from 'rc-tween-one/es/TweenOneGroup'; import React from 'react'; import { Button } from 'antd'; import 'antd/dist/antd.css'; @@ -48,7 +48,7 @@ export default () => { ### exclusive = true ```jsx -import TweenOneGroup from 'rc-tween-one/src/TweenOneGroup'; +import TweenOneGroup from 'rc-tween-one/es/TweenOneGroup'; import React from 'react'; import { Button } from 'antd'; import 'antd/dist/antd.css'; @@ -86,7 +86,7 @@ export default () => { ### children change ```jsx -import TweenOneGroup from 'rc-tween-one/src/TweenOneGroup'; +import TweenOneGroup from 'rc-tween-one/es/TweenOneGroup'; import React from 'react'; import { Button } from 'antd'; import 'antd/dist/antd.css'; diff --git a/docs/examples/animParam.tsx b/docs/examples/animParam.tsx index 665baee7..f0c46d57 100644 --- a/docs/examples/animParam.tsx +++ b/docs/examples/animParam.tsx @@ -5,13 +5,13 @@ import 'antd/dist/antd.css'; const { Option } = Select; -const ValueComp = props => { +const ValueComp = (props: any) => { const { value, onChange } = props; const [name, setName] = React.useState(value.name || 'x'); const [param, setParam] = React.useState(parseFloat(value.value) || 300); const [uint, setUint] = React.useState(value.uint || 'px'); - const onNameChange = e => { + const onNameChange = (e: any) => { setName(e); const v: any = { name: e, @@ -40,11 +40,11 @@ const ValueComp = props => { } onChange(v); }; - const onValueChange = e => { + const onValueChange = (e: any) => { setParam(e); onChange({ ...value, value: e }); }; - const onUintChange = e => { + const onUintChange = (e: any) => { setUint(e); onChange({ ...value, uint: e }); }; @@ -74,7 +74,7 @@ export default () => { const [anim, setAnim] = React.useState(); const [paused, setPaused] = React.useState(true); - const onFinish = values => { + const onFinish = (values: any) => { console.log('Received values from form: ', values); setPaused(false); const { value, ...v } = values; diff --git a/docs/examples/group.tsx b/docs/examples/group.tsx index f11fe1ef..98ce73fd 100644 --- a/docs/examples/group.tsx +++ b/docs/examples/group.tsx @@ -1,4 +1,4 @@ -import TweenOneGroup from 'rc-tween-one/src/TweenOneGroup'; +import TweenOneGroup from 'rc-tween-one/es/TweenOneGroup'; import React from 'react'; import { Button } from 'antd'; import 'antd/dist/antd.css'; diff --git a/docs/examples/numberDance.tsx b/docs/examples/numberDance.tsx index f3330e4f..bba86631 100644 --- a/docs/examples/numberDance.tsx +++ b/docs/examples/numberDance.tsx @@ -1,6 +1,6 @@ import Tween from 'rc-tween-one'; import React from 'react'; -import ChildrenPlugin from 'rc-tween-one/src/plugin/ChildrenPlugin'; +import ChildrenPlugin from 'rc-tween-one/es/plugin/ChildrenPlugin'; Tween.plugins.push(ChildrenPlugin); diff --git a/docs/examples/pathMotion.tsx b/docs/examples/pathMotion.tsx index 5d38fed5..1ad82812 100644 --- a/docs/examples/pathMotion.tsx +++ b/docs/examples/pathMotion.tsx @@ -1,6 +1,6 @@ import Tween from 'rc-tween-one'; import React from 'react'; -import PathPlugin from 'rc-tween-one/src/plugin/PathMotionPlugin'; +import PathPlugin from 'rc-tween-one/es/plugin/PathMotionPlugin'; Tween.plugins.push(PathPlugin); diff --git a/docs/examples/simple.tsx b/docs/examples/simple.tsx index 4ef7a616..5902e662 100644 --- a/docs/examples/simple.tsx +++ b/docs/examples/simple.tsx @@ -8,7 +8,7 @@ export default () => { return (
执行动效
diff --git a/docs/examples/svg.tsx b/docs/examples/svg.tsx index e174b3d0..9c77332b 100644 --- a/docs/examples/svg.tsx +++ b/docs/examples/svg.tsx @@ -1,6 +1,6 @@ import Tween, { Plugins } from 'rc-tween-one'; import React from 'react'; -import SvgMorphPlugin from 'rc-tween-one/src/plugin/SvgMorphPlugin'; +import SvgMorphPlugin from 'rc-tween-one/es/plugin/SvgMorphPlugin'; // Tween.plugins.push(SvgMorphPlugin); Plugins.push(SvgMorphPlugin); diff --git a/docs/examples/svgDraw.tsx b/docs/examples/svgDraw.tsx index 05d0cd7d..f0cc5afa 100644 --- a/docs/examples/svgDraw.tsx +++ b/docs/examples/svgDraw.tsx @@ -1,6 +1,6 @@ import Tween, { Plugins } from 'rc-tween-one'; import React from 'react'; -import SvgDrawPlugin from 'rc-tween-one/src/plugin/SvgDrawPlugin'; +import SvgDrawPlugin from 'rc-tween-one/es/plugin/SvgDrawPlugin'; Plugins.push(SvgDrawPlugin); diff --git a/docs/index.md b/docs/index.md index a16ba9ef..7cd7e4b0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -145,7 +145,7 @@ React.render( ```js | pure import { Plugins } from 'rc-tween-one'; -import SvgDrawPlugin from 'rc-tween-one/src/plugin/SvgDrawPlugin'; +import SvgDrawPlugin from 'rc-tween-one/es/plugin/SvgDrawPlugin'; Plugins.push(SvgDrawPlugin); @@ -159,7 +159,7 @@ SVGDraw = string or number; ```js | pure import { Plugins } from 'rc-tween-one'; -import SvgMorphPlugin from 'rc-tween-one/src/plugin/SvgMorphPlugin'; +import SvgMorphPlugin from 'rc-tween-one/es/plugin/SvgMorphPlugin'; Plugins.push(SvgMorphPlugin); @@ -177,7 +177,7 @@ Plugins.push(SvgMorphPlugin); ```js | pure import { Plugins } from 'rc-tween-one'; -import PathMotionPlugin from 'rc-tween-one/src/plugin/PathMotionPlugin'; +import PathMotionPlugin from 'rc-tween-one/es/plugin/PathMotionPlugin'; Plugins.push(PathMotionPlugin); diff --git a/package.json b/package.json index 396e9d56..b035ddc7 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dependencies": { "@babel/runtime": "^7.11.1", "style-utils": "^0.3.4", - "tween-one": "^1.0.9" + "tween-one": "^1.0.18" }, "husky": { "hooks": { diff --git a/src/plugin/PathMotionPlugin.ts b/src/plugin/PathMotionPlugin.ts index bb3021ae..ac4a2d00 100644 --- a/src/plugin/PathMotionPlugin.ts +++ b/src/plugin/PathMotionPlugin.ts @@ -1,3 +1,3 @@ -import PathMotionPlugin from 'tween-one/src/plugins/PathMotionPlugin'; +import PathMotionPlugin from 'tween-one/es/plugins/PathMotionPlugin'; export default PathMotionPlugin; diff --git a/src/plugin/SvgDrawPlugin.ts b/src/plugin/SvgDrawPlugin.ts index 42e6e57c..d2998b72 100644 --- a/src/plugin/SvgDrawPlugin.ts +++ b/src/plugin/SvgDrawPlugin.ts @@ -1,3 +1,3 @@ -import SvgDrawPlugin from 'tween-one/src/plugins/SvgDrawPlugin'; +import SvgDrawPlugin from 'tween-one/es/plugins/SvgDrawPlugin'; export default SvgDrawPlugin; diff --git a/src/plugin/SvgMorphPlugin.ts b/src/plugin/SvgMorphPlugin.ts index 665014ee..0057d36b 100644 --- a/src/plugin/SvgMorphPlugin.ts +++ b/src/plugin/SvgMorphPlugin.ts @@ -1,3 +1,3 @@ -import SvgMorph from 'tween-one/src/plugins/SvgMorphPlugin'; +import SvgMorph from 'tween-one/es/plugins/SvgMorphPlugin'; export default SvgMorph; diff --git a/typings/global/index.d.ts b/typings/global/index.d.ts index 070295c4..1fbeaa9a 100644 --- a/typings/global/index.d.ts +++ b/typings/global/index.d.ts @@ -8,11 +8,11 @@ declare module 'flubber'; declare module 'rc-tween-one'; -declare module 'rc-tween-one/src/plugin/ChildrenPlugin'; -declare module 'rc-tween-one/src/plugin/PathMotionPlugin'; -declare module 'rc-tween-one/src/plugin/SvgDrawPlugin'; -declare module 'rc-tween-one/src/plugin/SvgMorphPlugin'; -declare module 'rc-tween-one/src/TweenOneGroup'; +declare module 'rc-tween-one/es/plugin/ChildrenPlugin'; +declare module 'rc-tween-one/es/plugin/PathMotionPlugin'; +declare module 'rc-tween-one/es/plugin/SvgDrawPlugin'; +declare module 'rc-tween-one/es/plugin/SvgMorphPlugin'; +declare module 'rc-tween-one/es/TweenOneGroup'; interface Element { From 496d4ac14a1962554f6128c561bd11eef670cb21 Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 1 Dec 2020 20:29:35 +0800 Subject: [PATCH 16/69] update np --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b035ddc7..1e787af7 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"", "test": "umi-test test", "test:coverage": "umi-test --coverage", - "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish --any-branch", + "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish --any-branch --tag=beta", "lint": "eslint src/ --fix --ext .tsx,.ts", "lint:tsc": "tsc -p tsconfig.json --noEmit", "now-build": "npm run docs:build" From e3b09a5314bbdba882341fe3ce1e924b695bb150 Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 1 Dec 2020 20:30:07 +0800 Subject: [PATCH 17/69] 3.0.0-beta.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1e787af7..8ea97a22 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-tween-one", - "version": "3.0.0-beta.3", + "version": "3.0.0-beta.4", "description": "tween-one anim component for react", "typings": "es/index.d.ts", "engines": { From 8feeb70de8b22e3a90213df345581b4a552c8932 Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 1 Dec 2020 21:29:55 +0800 Subject: [PATCH 18/69] update type --- src/type.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/type.ts b/src/type.ts index d010f235..f2369739 100644 --- a/src/type.ts +++ b/src/type.ts @@ -1,9 +1,8 @@ import React from 'react'; -import { IAnimObject as AnimObject, IMode, ITimelineCallBack } from 'tween-one'; - +import { IAnimObject as Anim, IMode, ITimelineCallBack } from 'tween-one'; export interface IObject { - [key: string]: any + [key: string]: any; } export interface ICallBack { mode?: IMode; @@ -16,6 +15,14 @@ export interface ICallBack { targets?: IObject | IObject[]; } +interface AnimObject extends Anim { + Children?: { + value?: number; + floatLength?: number; + formatMoney?: true | { thousand?: string; decimal?: string }; + }; +} + export type AnimObjectOrArray = AnimObject | AnimObject[]; export type IAnimObject = AnimObjectOrArray | ((key: string, index: number) => AnimObject); @@ -60,13 +67,13 @@ export interface IGroupProps extends Omit, 'onChange'> componentProps?: IObject; } -export interface TweenOneRef extends React.ForwardRefExoticComponent { +export interface TweenOneRef extends React.ForwardRefExoticComponent { isTweenOne?: boolean; plugins?: any; ticker?: any; easing?: any; } -export interface TweenOneGroupRef extends React.ForwardRefExoticComponent { +export interface TweenOneGroupRef extends React.ForwardRefExoticComponent { isTweenOneGroup?: boolean; } From 94564537682a994e3c69a66f65e7417145b91a26 Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 1 Dec 2020 21:32:45 +0800 Subject: [PATCH 19/69] update np --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8ea97a22..67df602a 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"", "test": "umi-test test", "test:coverage": "umi-test --coverage", - "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish --any-branch --tag=beta", + "prepublishOnly": "npm run compile && np --tag=beta --no-cleanup --yolo --no-publish --any-branch", "lint": "eslint src/ --fix --ext .tsx,.ts", "lint:tsc": "tsc -p tsconfig.json --noEmit", "now-build": "npm run docs:build" From 1d19cad036d361ba518aa2268fb915f30f0c2d1a Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 1 Dec 2020 21:33:07 +0800 Subject: [PATCH 20/69] 3.0.0-beta.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 67df602a..c9005f18 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-tween-one", - "version": "3.0.0-beta.4", + "version": "3.0.0-beta.5", "description": "tween-one anim component for react", "typings": "es/index.d.ts", "engines": { From 172031176d86b7545c349e86627f0a16c89f1df8 Mon Sep 17 00:00:00 2001 From: jljsj Date: Wed, 2 Dec 2020 17:28:16 +0800 Subject: [PATCH 21/69] test now --- now.json | 1 + 1 file changed, 1 insertion(+) diff --git a/now.json b/now.json index 196bc225..15630cb5 100644 --- a/now.json +++ b/now.json @@ -4,6 +4,7 @@ "builds": [ { "src": "package.json", + "use": "@now/static-build", "config": { "distDir": ".doc" } } From ad0546ee87d6bb7cbdbf9ec4b7aef3b8553cfc16 Mon Sep 17 00:00:00 2001 From: jljsj Date: Wed, 2 Dec 2020 17:53:46 +0800 Subject: [PATCH 22/69] update alias --- .umirc.ts | 1 + now.json | 1 - typings/global/index.d.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.umirc.ts b/.umirc.ts index ce31db61..c2578655 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -10,6 +10,7 @@ export default defineConfig({ 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', outputPath: '.doc', alias: { + 'rc-tween-one':path.join(__dirname, 'src'), 'rc-tween-one/es': path.join(__dirname, 'src'), 'rc-tween-one/lib': path.join(__dirname, 'src'), }, diff --git a/now.json b/now.json index 15630cb5..196bc225 100644 --- a/now.json +++ b/now.json @@ -4,7 +4,6 @@ "builds": [ { "src": "package.json", - "use": "@now/static-build", "config": { "distDir": ".doc" } } diff --git a/typings/global/index.d.ts b/typings/global/index.d.ts index 1fbeaa9a..b58f3e31 100644 --- a/typings/global/index.d.ts +++ b/typings/global/index.d.ts @@ -7,7 +7,7 @@ declare module 'raf'; declare module 'flubber'; -declare module 'rc-tween-one'; +// declare module 'rc-tween-one'; declare module 'rc-tween-one/es/plugin/ChildrenPlugin'; declare module 'rc-tween-one/es/plugin/PathMotionPlugin'; declare module 'rc-tween-one/es/plugin/SvgDrawPlugin'; From bd5e7dbd28df21d31aee504a980e7d2041224e83 Mon Sep 17 00:00:00 2001 From: jljsj Date: Wed, 2 Dec 2020 17:58:24 +0800 Subject: [PATCH 23/69] update now-build --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c9005f18..20b4232d 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "prepublishOnly": "npm run compile && np --tag=beta --no-cleanup --yolo --no-publish --any-branch", "lint": "eslint src/ --fix --ext .tsx,.ts", "lint:tsc": "tsc -p tsconfig.json --noEmit", - "now-build": "npm run docs:build" + "now-build": "npm run compile && npm run docs:build" }, "devDependencies": { "@ant-design/icons": "^4.3.0", From 4cde8cb67f61fc39c5e97b0bf9b7afc72d0ab55f Mon Sep 17 00:00:00 2001 From: jljsj Date: Wed, 2 Dec 2020 19:46:49 +0800 Subject: [PATCH 24/69] rm scroll-anim demo --- .umirc.ts | 1 - docs/demo/scrollAnim.md | 8 -------- docs/examples/scrollAnim.tsx | 35 ----------------------------------- package.json | 3 +-- 4 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 docs/demo/scrollAnim.md delete mode 100644 docs/examples/scrollAnim.tsx diff --git a/.umirc.ts b/.umirc.ts index c2578655..ce31db61 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -10,7 +10,6 @@ export default defineConfig({ 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', outputPath: '.doc', alias: { - 'rc-tween-one':path.join(__dirname, 'src'), 'rc-tween-one/es': path.join(__dirname, 'src'), 'rc-tween-one/lib': path.join(__dirname, 'src'), }, diff --git a/docs/demo/scrollAnim.md b/docs/demo/scrollAnim.md deleted file mode 100644 index 3c96a899..00000000 --- a/docs/demo/scrollAnim.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: in rc-scroll-anim -order: 6 ---- - -## in rc-scroll-anim - - diff --git a/docs/examples/scrollAnim.tsx b/docs/examples/scrollAnim.tsx deleted file mode 100644 index 7041ea76..00000000 --- a/docs/examples/scrollAnim.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import Tween from 'rc-tween-one'; -import React from 'react'; -import ScrollOverPack from 'rc-scroll-anim/lib/ScrollOverPack'; - -export default function Demo() { - return ( -
-
往下滚动
- - - 执行动画 - - - 执行动画 - - -
- ); -} diff --git a/package.json b/package.json index 20b4232d..57183588 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "prepublishOnly": "npm run compile && np --tag=beta --no-cleanup --yolo --no-publish --any-branch", "lint": "eslint src/ --fix --ext .tsx,.ts", "lint:tsc": "tsc -p tsconfig.json --noEmit", - "now-build": "npm run compile && npm run docs:build" + "now-build": "npm run docs:build" }, "devDependencies": { "@ant-design/icons": "^4.3.0", @@ -76,7 +76,6 @@ "husky": "^4.3.0", "np": "^6.0.3", "prettier": "^2.1.2", - "rc-scroll-anim": "^2.7.6", "react": "^16.9.0", "react-dom": "^16.9.0", "regenerator-runtime": "^0.13.7", From 89b0adf7e8246f999ba23220f52c48d44ff00180 Mon Sep 17 00:00:00 2001 From: jljsj Date: Thu, 3 Dec 2020 17:00:49 +0800 Subject: [PATCH 25/69] update tween-one version --- docs/examples/pathMotion.tsx | 56 ++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/docs/examples/pathMotion.tsx b/docs/examples/pathMotion.tsx index 1ad82812..644046bd 100644 --- a/docs/examples/pathMotion.tsx +++ b/docs/examples/pathMotion.tsx @@ -4,6 +4,16 @@ import PathPlugin from 'rc-tween-one/es/plugin/PathMotionPlugin'; Tween.plugins.push(PathPlugin); +const array = [ + { x: 50, y: 50 }, + { x: 200, y: 250 }, + { x: 350, y: 50 }, + { x: 500, y: 250 }, + { x: 650, y: 50 } /* + { x: 800, y: 250 }, + { x: 950, y: 50 }, */, +]; + export default function Demo() { const p = `M50.952,85.619C31.729,84.841,23.557,73.62,24.095,42.952 c0.381-21.714,6.667-33.714,30.286-34.476 @@ -53,6 +63,52 @@ export default function Demo() {
+
+ {array.map((item, i) => { + return ( +
+ ); + })} + c +
); } diff --git a/package.json b/package.json index 57183588..b56aa488 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "dependencies": { "@babel/runtime": "^7.11.1", "style-utils": "^0.3.4", - "tween-one": "^1.0.18" + "tween-one": "^1.0.23" }, "husky": { "hooks": { From 5728bb66af95e5367b8ec4ee9a7658d1a94ec5ce Mon Sep 17 00:00:00 2001 From: jljsj Date: Thu, 3 Dec 2020 17:01:59 +0800 Subject: [PATCH 26/69] 3.0.0-beta.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b56aa488..cc9782ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-tween-one", - "version": "3.0.0-beta.5", + "version": "3.0.0-beta.6", "description": "tween-one anim component for react", "typings": "es/index.d.ts", "engines": { From 7461274246f6123d87281e1d16d3f343c8e88ec4 Mon Sep 17 00:00:00 2001 From: jljsj Date: Thu, 3 Dec 2020 17:27:37 +0800 Subject: [PATCH 27/69] update api --- docs/changeLog.md | 4 ++-- docs/index.md | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/changeLog.md b/docs/changeLog.md index 103e7e7d..5480a769 100644 --- a/docs/changeLog.md +++ b/docs/changeLog.md @@ -7,7 +7,7 @@ order: 2 --- -## 3.0.0-beta.0 +## 3.0.0-beta.x - hooks 重构 rc-tween-one; - 拆离动画库与组件, 动画库 https://docs.antfin-inc.com/tween-one-js-update_1/ @@ -20,7 +20,7 @@ order: 2 - `attr` 改为 `boolean` 类型; - 更新 `onChange` 回调,cb: { moment, targets, index, mode, ratio, vars, index, repeat } - 新增 `onChangeTimeline`, cb: { mode, targets, vars, moment, totalTime, repeat } -- 删除 `BezierPlugin`; +- 删除 `BezierPlugin`,合进 PathMotionPlugin;; - `PathMotionPlugin` 更改用法,使用 `PathMotion: { path, center, x, y, rotate }`, 详细参考 pathMotion demo; - `SvgMorph` 依赖更改为使用 `flubber`; - 滤境使用,改成 `import { Plugins } from 'rc-tween-one'; Plugins.push()`, 保留 `TweenOne.plugins.push()`; diff --git a/docs/index.md b/docs/index.md index 7cd7e4b0..6d0b6aa2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -170,7 +170,7 @@ Plugins.push(SvgMorphPlugin); |------------------|--------|---------|----------------| | path | string | null | svg path, ref: `M0,0L100,0`;| | attr | string | null | Svg tag attributes, example: `polygon` is ` points`, `path` is `d`. | -| maxSegmentLength | number | 0.5 | 该值越小,生成的动画将越平滑,但会牺牲性能;| +| maxSegmentLength | number | 0.5 | The lower the value, the smoother the generated animation will be, but at the expense of performance;| ### PathPlugin @@ -187,11 +187,18 @@ Plugins.push(PathMotionPlugin); | name | type | default | description | | ------ | ------------------- | --------------- | ----------------------------- | | path | string | null | svg path, ref: `M0,0L100,0`; | +| pathVars | IPathVars | null | Only valid if path is array '[{x, y}, {x, y}]' | | center | `number \ string[]` | `['50%','50%']` | center point, ref: `[50px, 50px]`; | | x | boolean | true | x follow the path. | | y | boolean | true | y follow the path. | | rotate | boolean | true | rotate follow the path. | +##### IPathVars +| name | type | default | description | +| ------ | ------------------- | --------------- | ----------------------------- | +| type | `thru \ soft \ cubic` | `thru` | path type. `thru` same as the path; `soft` with the curve of attraction facing them, but not through the point; `cubic` allows you to define standard Cubic Bezier, example: `[start, control, control, end]`. | +| curviness | 0-2 | 1 | This determines how "curvy" the resulting path is. `0` is lines, `1` is curved path, `2` would make it much more curvy. It can be `1.5`. | +| relative | boolean | false | Increase relative to current value. example: if the target's x starts at 100 and the path is `[{x:5}, {x:10}, {x:-2}]` , it would first move to `105`, then `115`, and finally end at `113`. | ### ChildrenPlugin From 7f8fefa153915adebfde39f0c220c2d1447822d1 Mon Sep 17 00:00:00 2001 From: jljsj Date: Fri, 16 Apr 2021 16:04:23 +0800 Subject: [PATCH 28/69] fix group, add region play --- .eslintrc.js | 1 + docs/changeLog.md | 2 +- docs/demo/group.md | 91 +----------------------------------- docs/index.md | 6 ++- package.json | 4 +- src/TweenOne.tsx | 6 +-- src/TweenOneGroup.tsx | 33 ++++++++----- src/plugin/ChildrenPlugin.ts | 11 +++-- src/type.ts | 10 ++-- src/utils/group.ts | 5 +- 10 files changed, 50 insertions(+), 119 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index ff35abf2..6ade1bbb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,5 +15,6 @@ module.exports = { '@typescript-eslint/no-explicit-any': 0, 'jsx-a11y/label-has-associated-control': 0, 'jsx-a11y/label-has-for': 0, + 'no-param-reassign': 0 }, }; \ No newline at end of file diff --git a/docs/changeLog.md b/docs/changeLog.md index 5480a769..28dfe5e8 100644 --- a/docs/changeLog.md +++ b/docs/changeLog.md @@ -25,7 +25,7 @@ order: 2 - `SvgMorph` 依赖更改为使用 `flubber`; - 滤境使用,改成 `import { Plugins } from 'rc-tween-one'; Plugins.push()`, 保留 `TweenOne.plugins.push()`; - 删除 `TweenOne.easing.path(path)` 使用,直接用 `ease: 'M0,0L100,100'`; - +- 增加动画区域播放 `regionStartTime`, `regionEndTime`; --- ## 2.2.0 diff --git a/docs/demo/group.md b/docs/demo/group.md index 5b518d65..bd3a8fef 100644 --- a/docs/demo/group.md +++ b/docs/demo/group.md @@ -5,45 +5,6 @@ order: 8 ### appear = false -```jsx -import TweenOneGroup from 'rc-tween-one/es/TweenOneGroup'; -import React from 'react'; -import { Button } from 'antd'; -import 'antd/dist/antd.css'; - -const imgArray = [ - 'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg', - 'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg', -]; -export default () => { - const [int, setInt] = React.useState(0); - return ( -
- - -
- img -
-
-
- ); -}; -``` - -## basic - - ### exclusive = true @@ -83,59 +44,11 @@ export default () => { }; ``` -### children change - -```jsx -import TweenOneGroup from 'rc-tween-one/es/TweenOneGroup'; -import React from 'react'; -import { Button } from 'antd'; -import 'antd/dist/antd.css'; - -const imgArray = [ - 'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg', - 'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg', -]; -export default () => { - const [children, setChildren] = React.useState( - [
- img -
] - ) - return ( -
- - - - {children} - -
- ); -}; -``` 出场交叉样式 ```css -.demo-group.tween-one-leaving { +.demo-group .tween-one-leaving { position: absolute; top: 0; left: 0; @@ -143,7 +56,7 @@ export default () => { ```` diff --git a/docs/demo/plugin:number-dance.md b/docs/demo/plugin-number-dance.md similarity index 100% rename from docs/demo/plugin:number-dance.md rename to docs/demo/plugin-number-dance.md diff --git a/docs/demo/plugin:path-motion.md b/docs/demo/plugin-path-motion.md similarity index 100% rename from docs/demo/plugin:path-motion.md rename to docs/demo/plugin-path-motion.md diff --git a/docs/demo/plugin:svg-draw.md b/docs/demo/plugin-svg-draw.md similarity index 100% rename from docs/demo/plugin:svg-draw.md rename to docs/demo/plugin-svg-draw.md diff --git a/docs/demo/plugin:svg-morph.md b/docs/demo/plugin-svg-morph.md similarity index 100% rename from docs/demo/plugin:svg-morph.md rename to docs/demo/plugin-svg-morph.md diff --git a/docs/examples/component.tsx b/docs/examples/component.tsx index 7398556e..2ba9def1 100644 --- a/docs/examples/component.tsx +++ b/docs/examples/component.tsx @@ -55,17 +55,20 @@ export default () => {
}} key="1" - icon={} > Option 1 @@ -79,8 +82,7 @@ export default () => { component={SubMenu} animation={{ ...anim, opacity: 0, type: 'from', delay: 200 }} key="sub1" - icon={} - title="Navigation One" + componentProps={{ icon: , title: 'Navigation One' }} > Option 5 Option 6 diff --git a/docs/examples/control.tsx b/docs/examples/control.tsx index 7d927d19..7291b172 100644 --- a/docs/examples/control.tsx +++ b/docs/examples/control.tsx @@ -7,7 +7,7 @@ const animation = [{ translateX: '500px', duration: 1000 }, { y: 100 }]; export default () => { const [paused, setPaused] = React.useState(true); const [reverse, setReverse] = React.useState(false); - const [moment, setMoment] = React.useState(0); + const [moment, setMoment] = React.useState(0); return (
@@ -49,7 +49,7 @@ export default () => {