From 444166f67848e1612b8e8c2a600f9a0287a2667b Mon Sep 17 00:00:00 2001 From: superwf Date: Mon, 12 Dec 2016 11:07:13 +0800 Subject: [PATCH 1/2] feat add shouldPlay prop some times the anime should not play such as when pagination, no item added or removed, prev page items dispear, next page items show the anime will make an confuse like the prev page items were removed and the next page items were added --- src/QueueAnim.jsx | 34 ++++++++++++++++++++++------------ tests/index.js | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/QueueAnim.jsx b/src/QueueAnim.jsx index feef975..f617e07 100644 --- a/src/QueueAnim.jsx +++ b/src/QueueAnim.jsx @@ -202,6 +202,9 @@ class QueueAnim extends React.Component { } componentDidUpdate() { + if (!this.props.shouldPlay) { + return + } this.originalChildren = toArrayChildren(getChildrenFromProps(this.props)); const keysToEnter = Array.prototype.slice.call(this.keysToEnter); const keysToLeave = Array.prototype.slice.call(this.keysToLeave); @@ -410,18 +413,6 @@ class QueueAnim extends React.Component { } render() { - const childrenToRender = toArrayChildren(this.state.children).map(child => { - if (!child || !child.key) { - return child; - } - return this.state.childrenShow[child.key] ? cloneElement(child, { - ref: child.key, - key: child.key, - }) : createElement('div', { - ref: placeholderKeyPrefix + child.key, - key: placeholderKeyPrefix + child.key, - }); - }); const { ...tagProps } = this.props; [ 'component', @@ -435,7 +426,23 @@ class QueueAnim extends React.Component { 'animatingClassName', 'enterForcedRePlay', 'onEnd', + 'shouldPlay', ].forEach(key => delete tagProps[key]); + if (!this.props.shouldPlay) { + return createElement(this.props.component, { ...tagProps }, this.props.children); + } + const childrenToRender = toArrayChildren(this.state.children).map(child => { + if (!child || !child.key) { + return child; + } + return this.state.childrenShow[child.key] ? cloneElement(child, { + ref: child.key, + key: child.key, + }) : createElement('div', { + ref: placeholderKeyPrefix + child.key, + key: placeholderKeyPrefix + child.key, + }); + }); return createElement(this.props.component, { ...tagProps }, childrenToRender); } } @@ -460,6 +467,8 @@ QueueAnim.propTypes = { enterForcedRePlay: React.PropTypes.bool, animatingClassName: React.PropTypes.array, onEnd: React.PropTypes.func, + shouldPlay: React.PropTypes.bool, + children: React.PropTypes.array, }; QueueAnim.defaultProps = { @@ -474,6 +483,7 @@ QueueAnim.defaultProps = { enterForcedRePlay: false, animatingClassName: ['queue-anim-entering', 'queue-anim-leaving'], onEnd: noop, + shouldPlay: true, }; export default QueueAnim; diff --git a/tests/index.js b/tests/index.js index cd0fde5..8bc98e5 100644 --- a/tests/index.js +++ b/tests/index.js @@ -351,4 +351,45 @@ describe('rc-queue-anim', () => { }, 17); }, 1000); }); + + it('when shouldPlay is false, do not play anime', (done) => { + const interval = defaultInterval; + const instance = createQueueAnimInstance({ + shouldPlay: false, + animConfig(e) { + if (e.index === 1) { + return { top: [100, 0] }; + } + return { left: [100, 0] }; + }, + }); + let children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div'); + expect(isNaN(getLeft(children[1]))).to.be.ok(); + expect(isNaN(getTop(children[2]))).to.be.ok(); + setTimeout(() => { + children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div'); + expect(isNaN(getLeft(children[1]))).to.be.ok(); + expect(isNaN(getTop(children[1]))).to.be.ok(); + console.log('left:', getLeft(children[1])); + setTimeout(() => { + children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div'); + expect(isNaN(getTop(children[2]))).to.be.ok(); + expect(isNaN(getLeft(children[2]))).to.be.ok(); + console.log('top:', getTop(children[2])); + setTimeout(() => { + children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div'); + expect(isNaN(getTop(children[2]))).to.be.ok(); + expect(isNaN(getLeft(children[2]))).to.be.ok(); + console.log('top_end:', getTop(children[2])); + done(); + }, 500); + }, interval); + setTimeout(() => { + children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div'); + expect(isNaN(getLeft(children[1]))).to.be.ok(); + expect(isNaN(getTop(children[1]))).to.be.ok(); + console.log('left_end:', getLeft(children[1])); + }, 500); + }, 17); + }); }); From 3c37aa0d30b43bb3f9756a594c17c2d2eac2d636 Mon Sep 17 00:00:00 2001 From: superwf Date: Wed, 21 Dec 2016 11:44:25 +0800 Subject: [PATCH 2/2] fix change shoudPlay to appear MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 参照animation, 修改了appear的检测点, 使onEnd在重新加载数据时能被调用 --- src/QueueAnim.jsx | 54 ++++++++++++++++++++++++++--------------------- tests/index.js | 4 ++-- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/QueueAnim.jsx b/src/QueueAnim.jsx index f617e07..5c7947f 100644 --- a/src/QueueAnim.jsx +++ b/src/QueueAnim.jsx @@ -202,9 +202,6 @@ class QueueAnim extends React.Component { } componentDidUpdate() { - if (!this.props.shouldPlay) { - return - } this.originalChildren = toArrayChildren(getChildrenFromProps(this.props)); const keysToEnter = Array.prototype.slice.call(this.keysToEnter); const keysToLeave = Array.prototype.slice.call(this.keysToLeave); @@ -301,7 +298,7 @@ class QueueAnim extends React.Component { const delay = transformArguments(this.props.delay, key, i)[0]; this.placeholderTimeoutIds[key] = setTimeout( this.performEnterBegin.bind(this, key, i), - interval * i + delay + this.props.appear ? interval * i + delay : 0 ); if (this.keysToEnter.indexOf(key) >= 0) { this.keysToEnter.splice(this.keysToEnter.indexOf(key), 1); @@ -319,6 +316,10 @@ class QueueAnim extends React.Component { if (!node) { return; } + if (!this.props.appear) { + this.props.onEnd({ key, type: 'enter' }); + return; + } const duration = transformArguments(this.props.duration, key, i)[0]; velocity(node, 'stop'); const data = this.props.enterForcedRePlay ? this.getVelocityEnterConfig(key, i) : @@ -342,11 +343,20 @@ class QueueAnim extends React.Component { if (!node) { return; } + velocity(node, 'stop'); + if (!this.props.appear) { + this.state.childrenShow[key] = true + this.setState({ + children: this.props.children, + childrenShow: this.state.childrenShow, + }) + this.props.onEnd({ key, type: 'leave' }); + return + } const interval = transformArguments(this.props.interval, key, i)[1]; const delay = transformArguments(this.props.delay, key, i)[1]; const duration = transformArguments(this.props.duration, key, i)[1]; const order = this.props.leaveReverse ? (this.keysToLeave.length - i - 1) : i; - velocity(node, 'stop'); node.style.visibility = 'visible'; const data = this.getInitAnimType(node, this.getVelocityLeaveConfig(key, i)); velocity(node, data, { @@ -413,6 +423,18 @@ class QueueAnim extends React.Component { } render() { + const childrenToRender = toArrayChildren(this.state.children).map(child => { + if (!child || !child.key) { + return child; + } + return this.state.childrenShow[child.key] ? cloneElement(child, { + ref: child.key, + key: child.key, + }) : createElement('div', { + ref: placeholderKeyPrefix + child.key, + key: placeholderKeyPrefix + child.key, + }); + }); const { ...tagProps } = this.props; [ 'component', @@ -426,23 +448,8 @@ class QueueAnim extends React.Component { 'animatingClassName', 'enterForcedRePlay', 'onEnd', - 'shouldPlay', + 'appear', ].forEach(key => delete tagProps[key]); - if (!this.props.shouldPlay) { - return createElement(this.props.component, { ...tagProps }, this.props.children); - } - const childrenToRender = toArrayChildren(this.state.children).map(child => { - if (!child || !child.key) { - return child; - } - return this.state.childrenShow[child.key] ? cloneElement(child, { - ref: child.key, - key: child.key, - }) : createElement('div', { - ref: placeholderKeyPrefix + child.key, - key: placeholderKeyPrefix + child.key, - }); - }); return createElement(this.props.component, { ...tagProps }, childrenToRender); } } @@ -467,8 +474,7 @@ QueueAnim.propTypes = { enterForcedRePlay: React.PropTypes.bool, animatingClassName: React.PropTypes.array, onEnd: React.PropTypes.func, - shouldPlay: React.PropTypes.bool, - children: React.PropTypes.array, + appear: React.PropTypes.bool, }; QueueAnim.defaultProps = { @@ -483,7 +489,7 @@ QueueAnim.defaultProps = { enterForcedRePlay: false, animatingClassName: ['queue-anim-entering', 'queue-anim-leaving'], onEnd: noop, - shouldPlay: true, + appear: true, }; export default QueueAnim; diff --git a/tests/index.js b/tests/index.js index 8bc98e5..9fc5f3a 100644 --- a/tests/index.js +++ b/tests/index.js @@ -352,10 +352,10 @@ describe('rc-queue-anim', () => { }, 1000); }); - it('when shouldPlay is false, do not play anime', (done) => { + it('when appear is false, do not play anime', (done) => { const interval = defaultInterval; const instance = createQueueAnimInstance({ - shouldPlay: false, + appear: false, animConfig(e) { if (e.index === 1) { return { top: [100, 0] };