Skip to content

Commit 3ec2b3e

Browse files
committed
some props support function call, ref #2
1 parent 99bbbe3 commit 3ec2b3e

File tree

5 files changed

+185
-30
lines changed

5 files changed

+185
-30
lines changed

examples/param-func.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
placeholder

examples/param-func.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import QueueAnim from 'rc-queue-anim';
2+
import React from 'react';
3+
import ReactDom from 'react-dom';
4+
5+
6+
const Page1 = React.createClass({
7+
getInitialState() {
8+
return {
9+
show: true
10+
};
11+
},
12+
onClick() {
13+
this.setState({
14+
show: !this.state.show
15+
})
16+
},
17+
animConfigFunc(e) {
18+
if (e.key === '3') {
19+
return {opacity: [1, 0], translateX: [0, 30]};
20+
}
21+
return [{opacity: [1, 0], translateX: [0, -30]}, {opacity: [1, 0], translateX: [0, 30]}];
22+
},
23+
durationFunc(e) {
24+
if (e.key === '3') {
25+
return [1500, 4000];
26+
}
27+
return 500;
28+
},
29+
easeFunc(e) {
30+
if (e.key === '3') {
31+
return ['easeOutBack', 'easeInBack'];
32+
}
33+
return 'easeInOutQuart';
34+
},
35+
delayFunc(e) {
36+
if (e.index >= 3) {
37+
return [1500, 0];
38+
}
39+
return 0;
40+
},
41+
render() {
42+
return (<div>
43+
<button onClick={this.onClick}>切换</button>
44+
<QueueAnim interval={300} animConfig={this.animConfigFunc} duration={this.durationFunc} ease={this.easeFunc} delay={this.delayFunc}>
45+
{this.state.show ? [<div key="1">依次进入</div>,
46+
<div key="2">依次进入</div>,
47+
<div key="3">改变type</div>,
48+
<div key="4">依次进入</div>,
49+
<div key="5">依次进入</div>] : null}
50+
</QueueAnim>
51+
</div>
52+
);
53+
}
54+
});
55+
56+
ReactDom.render(<Page1 />, document.getElementById('__react-content'));

src/QueueAnim.jsx

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,19 @@ class QueueAnim extends React.Component {
115115
}
116116
}
117117

118-
getVelocityConfig(index) {
118+
getVelocityConfig(index, ...args) {
119119
if (this.props.animConfig) {
120-
return transformArguments(this.props.animConfig)[index];
120+
return transformArguments(this.props.animConfig, ...args)[index];
121121
}
122-
return AnimTypes[transformArguments(this.props.type)[index]];
122+
return AnimTypes[transformArguments(this.props.type, ...args)[index]];
123123
}
124124

125-
getVelocityEnterConfig() {
126-
return this.getVelocityConfig(0);
125+
getVelocityEnterConfig(...args) {
126+
return this.getVelocityConfig(0, ...args);
127127
}
128128

129-
getVelocityLeaveConfig() {
130-
const config = this.getVelocityConfig(1);
129+
getVelocityLeaveConfig(...args) {
130+
const config = this.getVelocityConfig(1, ...args);
131131
const ret = {};
132132
Object.keys(config).forEach((key) => {
133133
if (Array.isArray(config[key])) {
@@ -139,8 +139,8 @@ class QueueAnim extends React.Component {
139139
return ret;
140140
}
141141

142-
getVelocityEasing() {
143-
return transformArguments(this.props.ease).map((easeName) => {
142+
getVelocityEasing(...args) {
143+
return transformArguments(this.props.ease, ...args).map((easeName) => {
144144
if (typeof easeName === 'string') {
145145
return BackEase[easeName] || easeName;
146146
}
@@ -152,35 +152,35 @@ class QueueAnim extends React.Component {
152152
if (!placeholderNode) {
153153
return;
154154
}
155-
const interval = transformArguments(this.props.interval)[0];
156-
const delay = transformArguments(this.props.delay)[0];
155+
const interval = transformArguments(this.props.interval, key, i)[0];
156+
const delay = transformArguments(this.props.delay, key, i)[0];
157157
placeholderNode.style.visibility = 'hidden';
158158
velocity(placeholderNode, 'stop');
159159
velocity(placeholderNode, { opacity: [0, 0] }, {
160160
delay: interval * i + delay,
161161
duration: 0,
162-
begin: this.performEnterBegin.bind(this, key),
162+
begin: this.performEnterBegin.bind(this, key, i),
163163
});
164164
if (this.keysToEnter.indexOf(key) >= 0) {
165165
this.keysToEnter.splice(this.keysToEnter.indexOf(key), 1);
166166
}
167167
}
168168

169-
performEnterBegin(key) {
169+
performEnterBegin(key, i) {
170170
const childrenShow = this.state.childrenShow;
171171
childrenShow[key] = true;
172-
this.setState({ childrenShow }, this.realPerformEnter.bind(this, key));
172+
this.setState({ childrenShow }, this.realPerformEnter.bind(this, key, i));
173173
}
174174

175-
realPerformEnter(key) {
175+
realPerformEnter(key, i) {
176176
const node = findDOMNode(this.refs[key]);
177177
if (!node) {
178178
return;
179179
}
180-
const duration = transformArguments(this.props.duration)[0];
180+
const duration = transformArguments(this.props.duration, key, i)[0];
181181
node.style.visibility = 'hidden';
182182
velocity(node, 'stop');
183-
velocity(node, this.getVelocityEnterConfig('enter'), {
183+
velocity(node, this.getVelocityEnterConfig(key, i), {
184184
duration: duration,
185185
easing: this.getVelocityEasing()[0],
186186
visibility: 'visible',
@@ -194,12 +194,12 @@ class QueueAnim extends React.Component {
194194
if (!node) {
195195
return;
196196
}
197-
const interval = transformArguments(this.props.interval)[1];
198-
const delay = transformArguments(this.props.delay)[1];
199-
const duration = transformArguments(this.props.duration)[1];
197+
const interval = transformArguments(this.props.interval, key, i)[1];
198+
const delay = transformArguments(this.props.delay, key, i)[1];
199+
const duration = transformArguments(this.props.duration, key, i)[1];
200200
const order = this.props.leaveReverse ? (this.keysToLeave.length - i - 1) : i;
201201
velocity(node, 'stop');
202-
velocity(node, this.getVelocityLeaveConfig('leave'), {
202+
velocity(node, this.getVelocityLeaveConfig(key, i), {
203203
delay: interval * order + delay,
204204
duration: duration,
205205
easing: this.getVelocityEasing()[1],
@@ -271,14 +271,18 @@ class QueueAnim extends React.Component {
271271
const numberOrArray = React.PropTypes.oneOfType([React.PropTypes.number, React.PropTypes.array]);
272272
const stringOrArray = React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.array]);
273273
const objectOrArray = React.PropTypes.oneOfType([React.PropTypes.object, React.PropTypes.array]);
274+
const funcOrStringOrArray = React.PropTypes.oneOfType([React.PropTypes.func, stringOrArray]);
275+
const funcOrObjectOrArray = React.PropTypes.oneOfType([React.PropTypes.func, objectOrArray]);
276+
const funcOrNumberOrArray = React.PropTypes.oneOfType([React.PropTypes.func, numberOrArray]);
277+
274278
QueueAnim.propTypes = {
275279
component: React.PropTypes.string,
276280
interval: numberOrArray,
277-
duration: numberOrArray,
278-
delay: numberOrArray,
279-
type: stringOrArray,
280-
animConfig: objectOrArray,
281-
ease: stringOrArray,
281+
duration: funcOrNumberOrArray,
282+
delay: funcOrNumberOrArray,
283+
type: funcOrStringOrArray,
284+
animConfig: funcOrObjectOrArray,
285+
ease: funcOrStringOrArray,
282286
leaveReverse: React.PropTypes.bool,
283287
animatingClassName: React.PropTypes.array,
284288
};

src/utils.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,20 @@ export function mergeChildren(prev, next) {
6464
return ret;
6565
}
6666

67-
export function transformArguments(arg) {
68-
if (Array.isArray(arg) && arg.length === 2) {
69-
return arg;
67+
export function transformArguments(arg, key, i) {
68+
let result;
69+
if (typeof arg === 'function') {
70+
result = arg({
71+
key: key,
72+
index: i,
73+
});
74+
} else {
75+
result = arg;
76+
}
77+
if (Array.isArray(result) && result.length === 2) {
78+
return result;
7079
}
71-
return [arg, arg];
80+
return [result, result];
7281
}
7382

7483
export function getChildrenFromProps(props) {

tests/index.spec.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ describe('rc-queue-anim', function () {
1919
return parseFloat(node.style.left);
2020
}
2121

22+
function getTop(node) {
23+
return parseFloat(node.style.top);
24+
}
25+
2226
function shouldAnimatingThisOne(instance, index) {
2327
let children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
2428
children.forEach(function(node, i) {
@@ -239,4 +243,85 @@ describe('rc-queue-anim', function () {
239243
}, 550);
240244
});
241245

246+
it('should has animating config is func enter', function (done) {
247+
const interval = defaultInterval;
248+
instance = createQueueAnimInstance({
249+
animConfig(e) {
250+
if (e.index === 1) {
251+
return {top: [100, 0]};
252+
}
253+
return {left: [100, 0]};
254+
}
255+
});
256+
let children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
257+
expect(isNaN(getLeft(children[1]))).to.be.ok();
258+
expect(isNaN(getTop(children[2]))).to.be.ok();
259+
setTimeout(function () {
260+
children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
261+
expect(getLeft(children[1])).to.above(0);
262+
expect(isNaN(getTop(children[1]))).to.be.ok();
263+
console.log('left:', getLeft(children[1]));
264+
setTimeout(function () {
265+
children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
266+
expect(getTop(children[2])).to.above(0);
267+
expect(isNaN(getLeft(children[2]))).to.be.ok();
268+
console.log('top:', getTop(children[2]));
269+
setTimeout(function () {
270+
children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
271+
expect(getTop(children[2])).to.be(100);
272+
expect(isNaN(getLeft(children[2]))).to.be.ok();
273+
console.log('top_end:', getTop(children[2]));
274+
done();
275+
}, 500);
276+
}, interval);
277+
setTimeout(function () {
278+
children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
279+
expect(getLeft(children[1])).to.be(100);
280+
expect(isNaN(getTop(children[1]))).to.be.ok();
281+
console.log('left_end:', getLeft(children[1]));
282+
}, 500);
283+
}, 10);
284+
});
285+
286+
it('should has animating config is func leave', function (done) {
287+
const interval = defaultInterval;
288+
instance = createQueueAnimInstance({
289+
animConfig(e) {
290+
if (e.index === 1) {
291+
return {top: [100, 0]};
292+
}
293+
return {left: [100, 0]};
294+
}
295+
});
296+
let children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
297+
setTimeout(function () {
298+
instance.toggle();
299+
setTimeout(function () {
300+
children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
301+
expect(getLeft(children[1])).to.below(100);
302+
expect(isNaN(getTop(children[1]))).to.be.ok();
303+
console.log('left:', getLeft(children[1]));
304+
setTimeout(function () {
305+
children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
306+
expect(getLeft(children[1])).to.be(0);
307+
expect(isNaN(getTop(children[1]))).to.be.ok();
308+
console.log('left_end:', getLeft(children[1]));
309+
}, 500);
310+
setTimeout(function () {
311+
children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
312+
expect(getTop(children[2])).to.below(100);
313+
expect(isNaN(getLeft(children[2]))).to.be.ok();
314+
console.log('top:', getTop(children[2]));
315+
setTimeout(function () {
316+
children = TestUtils.scryRenderedDOMComponentsWithTag(instance, 'div');
317+
console.log('top_end:', getTop(children[2]));
318+
expect(getTop(children[2])).to.be(0);
319+
expect(isNaN(getLeft(children[2]))).to.be.ok();
320+
done();
321+
}, 500);
322+
}, 110);
323+
}, 10);
324+
}, 1000);
325+
});
326+
242327
});

0 commit comments

Comments
 (0)