Skip to content

Commit f492a5f

Browse files
committed
fix #75
1 parent f1dc745 commit f492a5f

File tree

3 files changed

+54
-65
lines changed

3 files changed

+54
-65
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rc-queue-anim",
3-
"version": "1.6.11",
3+
"version": "1.6.12",
44
"description": "Queue animation component for react",
55
"keywords": [
66
"react",

src/QueueAnim.jsx

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ class QueueAnim extends React.Component {
5656
};
5757
constructor(props) {
5858
super(props);
59-
/**
60-
* @param oneEnter
61-
* 记录第一次进入;
62-
*/
63-
this.oneEnter = false;
6459
/**
6560
* @param tweenToEnter;
6661
* 记录强制切换时是否需要添加 animation;
@@ -77,6 +72,11 @@ class QueueAnim extends React.Component {
7772
* 记录 TweenOne 标签,在 leaveUnfinishedChild 里使用,残留的元素不需要考虑 props 的变更。
7873
*/
7974
this.saveTweenOneTag = {};
75+
/**
76+
* @param enterAnimation;
77+
* 记录进场的动画, 在没进场完成, 将进场的动画保存,免得重新生成。
78+
*/
79+
this.enterAnimation = {};
8080
/**
8181
* @param childrenShow;
8282
* 记录 animation 里是否需要 startAnim;
@@ -115,6 +115,7 @@ class QueueAnim extends React.Component {
115115
this.keysToEnter.push(child.key);
116116
} else {
117117
childrenShow[child.key] = true;
118+
this.tweenToEnter[child.key] = true;
118119
}
119120
});
120121
this.keysToEnterToCallback = [...this.keysToEnter];
@@ -129,7 +130,6 @@ class QueueAnim extends React.Component {
129130
if (this.props.appear) {
130131
this.componentDidUpdate();
131132
}
132-
this.oneEnter = true;
133133
}
134134

135135
componentWillReceiveProps(nextProps) {
@@ -275,10 +275,11 @@ class QueueAnim extends React.Component {
275275
const enterOrLeave = type === 'enter' ? 0 : 1;
276276
const start = type === 'enter' ? 1 : 0;
277277
const end = type === 'enter' ? 0 : 1;
278-
let startAnim = this.getAnimData(props, key, i, enterOrLeave, start);
279278
const animate = this.getAnimData(props, key, i, enterOrLeave, end);
280-
startAnim =
281-
type === 'enter' && (props.forcedReplay || !this.childrenShow[key]) ? startAnim : null;
279+
const startAnim =
280+
type === 'enter' && (props.forcedReplay || !this.childrenShow[key]) ?
281+
this.getAnimData(props, key, i, enterOrLeave, start)
282+
: null;
282283
let ease = transformArguments(props.ease, key, i)[enterOrLeave];
283284
const duration = transformArguments(props.duration, key, i)[enterOrLeave];
284285
if (Array.isArray(ease)) {
@@ -345,11 +346,6 @@ class QueueAnim extends React.Component {
345346
return [animateData.startAnimate, animateData.animation].filter(item => item);
346347
};
347348

348-
getTweenAppearData = (key, i) => ({
349-
...this.getAnimData(this.props, key, i, 0, 0),
350-
duration: 0,
351-
});
352-
353349
getAnimData = (props, key, i, enterOrLeave, startOrEnd) => {
354350
/**
355351
* transformArguments 第一个为 enter, 第二个为 leave;
@@ -358,15 +354,15 @@ class QueueAnim extends React.Component {
358354
*/
359355
return props.animConfig
360356
? this.getTweenAnimConfig(
361-
transformArguments(props.animConfig, key, i)[enterOrLeave],
362-
startOrEnd,
363-
enterOrLeave,
364-
)
357+
transformArguments(props.animConfig, key, i)[enterOrLeave],
358+
startOrEnd,
359+
enterOrLeave,
360+
)
365361
: this.getTweenType(transformArguments(props.type, key, i)[enterOrLeave], startOrEnd);
366362
};
367363

368364
getChildrenToRender = child => {
369-
const { forcedReplay, leaveReverse, appear, delay, interval } = this.props;
365+
const { forcedReplay, leaveReverse, delay, interval } = this.props;
370366
if (!child || !child.key) {
371367
return child;
372368
}
@@ -400,11 +396,7 @@ class QueueAnim extends React.Component {
400396
} else {
401397
// 处理进场;
402398
i = this.keysToEnterToCallback.indexOf(key);
403-
if (!this.oneEnter && !appear) {
404-
animation = this.getTweenAppearData(key, i);
405-
} else {
406-
animation = this.getTweenEnterOrLeaveData(key, i, 0, 'enter');
407-
}
399+
// appear=false 时,设定 childrenShow 和 tweenToEnter 都为 true, 这里不渲染 animation;
408400
if (this.tweenToEnter[key] && !forcedReplay) {
409401
// 如果是已进入的,将直接返回标签。。
410402
return createElement(TweenOne, {
@@ -413,6 +405,9 @@ class QueueAnim extends React.Component {
413405
forcedJudg,
414406
componentProps: child.props,
415407
});
408+
} else if (!this.tweenToEnter[key]) {
409+
animation = this.enterAnimation[key] || this.getTweenEnterOrLeaveData(key, i, 0, 'enter');
410+
this.enterAnimation[key] = animation;
416411
}
417412
}
418413
const paused = this.keysToEnterPaused[key] && this.keysToLeave.indexOf(key) === -1;
@@ -471,6 +466,7 @@ class QueueAnim extends React.Component {
471466
const elem = e.target;
472467
elem.className = elem.className.replace(this.props.animatingClassName[0], '').trim();
473468
this.tweenToEnter[key] = true;
469+
delete this.enterAnimation[key];
474470
this.props.onEnd({ key, type: 'enter', target: elem });
475471
};
476472

tests/index.js

Lines changed: 33 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import React from 'react';
55
import ReactDom from 'react-dom';
66
import expect from 'expect.js';
77
import TestUtils from 'react-dom/test-utils';
8-
import ticker from 'rc-tween-one/lib/ticker';
98
import QueueAnim from '../src';
109

1110
const defaultInterval = 100;
@@ -15,21 +14,21 @@ describe('rc-queue-anim', () => {
1514

1615
function getOpacity(node) {
1716
if (!node) {
18-
return null;
17+
return NaN;
1918
}
2019
return parseFloat(window.getComputedStyle(node).opacity);
2120
}
2221

2322
function getLeft(node) {
2423
if (!node) {
25-
return null;
24+
return NaN;
2625
}
2726
return parseFloat(node.style.left);
2827
}
2928

3029
function getTop(node) {
3130
if (!node) {
32-
return null;
31+
return NaN;
3332
}
3433
return parseFloat(node.style.top);
3534
}
@@ -262,42 +261,36 @@ describe('rc-queue-anim', () => {
262261
let index = 0;
263262
let maxOpacity;
264263
const opacityArray = [];
265-
//
266-
setTimeout(() => {
267-
const interval = ticker.interval(() => {
268-
index += 1;
269-
// 取第一个, 时间为 450 加间隔 100 ,,应该 550 为最高点。10不是最高点
270-
const children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div')[1];
271-
const opacity = getOpacity(children);
272-
if (!isNaN(opacity)) {
273-
opacityArray.push(opacity);
274-
}
275-
console.log(
276-
'time: ',
277-
index * 50,
278-
'opacity: ',
279-
opacity || 0,
280-
'children is remove:',
281-
!children,
282-
);
283-
if (index === 10) {
284-
instance.toggle();
285-
console.log('toggle');
286-
}
287-
if (index === 11) {
288-
// tweenOne 在改变动画后是在下一帧再启动改变后的动画,,
289-
maxOpacity = opacity;
290-
}
291-
if (opacity >= 1 || opacity <= 0 || isNaN(opacity)) {
292-
ticker.clear(interval);
293-
console.log(maxOpacity);
294-
opacityArray.forEach(o => {
295-
expect(maxOpacity >= o).to.be.ok();
296-
});
297-
done();
298-
}
299-
}, 18);
300-
}, 18);
264+
const interval = setInterval(() => {
265+
index += 1;
266+
// 取第一个, 时间为 450 加间隔 100 ,,应该 550 为最高点。10不是最高点
267+
const children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div')[1];
268+
const opacity = getOpacity(children);
269+
if (!isNaN(opacity)) {
270+
opacityArray.push(opacity);
271+
}
272+
console.log(
273+
'time: ',
274+
index * 50,
275+
'opacity: ',
276+
opacity || 0,
277+
'children is remove:',
278+
!children,
279+
);
280+
if (index === 9) {
281+
instance.toggle();
282+
maxOpacity = opacity;
283+
console.log('toggle');
284+
}
285+
if (opacity >= 1 || opacity <= 0 || isNaN(opacity)) {
286+
clearInterval(interval);
287+
console.log(maxOpacity);
288+
opacityArray.forEach(o => {
289+
expect(maxOpacity >= o).to.be.ok();
290+
});
291+
done();
292+
}
293+
}, 50);
301294
});
302295

303296
it('should has animating className', done => {

0 commit comments

Comments
 (0)