Skip to content

Commit 0395f2f

Browse files
committed
fix ant-design/ant-motion#323, opacity start value, svgDraw start loop bug
1 parent b3a0c14 commit 0395f2f

File tree

8 files changed

+129
-69
lines changed

8 files changed

+129
-69
lines changed

examples/groupInStrict.html

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

examples/groupInStrict.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { TweenOneGroup } from 'rc-tween-one';
2+
import React from 'react';
3+
import ReactDom from 'react-dom';
4+
import '../assets/index.less';
5+
6+
class Demo extends React.Component {
7+
constructor(props) {
8+
super(props);
9+
this.imgArray = [
10+
'https://os.alipayobjects.com/rmsportal/IhCNTqPpLeTNnwr.jpg',
11+
'https://os.alipayobjects.com/rmsportal/uaQVvDrCwryVlbb.jpg',
12+
];
13+
this.state = {
14+
int: 0,
15+
};
16+
}
17+
18+
onClick = () => {
19+
let int = this.state.int;
20+
int++;
21+
if (int >= this.imgArray.length) {
22+
int = 0;
23+
}
24+
this.setState({ int });
25+
}
26+
27+
render() {
28+
return (
29+
<React.StrictMode>
30+
<div>
31+
<button onClick={this.onClick}>切换</button>
32+
<TweenOneGroup style={{ position: 'relative' }}>
33+
<div key={this.state.int}>
34+
<img src={this.imgArray[this.state.int]} height="200" alt="img"/>
35+
</div>
36+
</TweenOneGroup>
37+
</div>
38+
</React.StrictMode>
39+
);
40+
}
41+
}
42+
ReactDom.render(<Demo />, document.getElementById('__react-content'));

examples/simple.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ import React from 'react';
33
import ReactDom from 'react-dom';
44
import '../assets/index.less';
55

6-
class Demo extends React.Component {
7-
bbb = (e) => {
6+
function Demo() {
7+
const bbb = (e) => {
88
console.log(e);// eslint-disable-line no-console
99
}
1010

11-
render() {
12-
return (<Tween
11+
return (
12+
<Tween
1313
animation={{ x: 300 }}
14-
onChange={this.bbb}
14+
onChange={bbb}
1515
style={{ opacity: 1, height: 100, display: 'inline-block' }}
1616
>
1717
<div>执行动效</div>
18-
</Tween>);
19-
}
18+
</Tween>
19+
);
2020
}
2121
ReactDom.render(<Demo />, document.getElementById('__react-content'));

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rc-tween-one",
3-
"version": "2.6.8",
3+
"version": "2.7.0",
44
"description": "tween-one anim component for react",
55
"keywords": [
66
"react",

src/Tween.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,8 @@ p.getAnimStartData = function (item) {
202202
if (this.attr === 'attr') {
203203
// 除了d和这points外的标签动画;
204204
const attribute = this.getValue(_key);
205-
let data = attribute === 'null' || !attribute ? 0 : attribute;
205+
const s = _key.match(/opacity/ig) ? 1 : 0
206+
let data = attribute === 'null' || !attribute ? s : attribute;
206207
if (_key.match(/color/i) || _key === 'stroke' || _key === 'fill') {
207208
data = !data && _key === 'stroke' ? 'rgba(255, 255, 255, 0)' : data;
208209
data = parseColor(data);

src/TweenOne.jsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -125,24 +125,19 @@ class TweenOne extends Component {
125125
this.updateAnim = false;
126126
this.repeatNum = 0;
127127
this.forced = {};
128-
this.currentRef = null;
129128
this.setForcedJudg(props);
130129
this.state = {
131130
$self: this,
132131
};
133132
}
134133

135134
componentDidMount() {
136-
this.dom = ReactDom.findDOMNode(this);
137135
if (this.dom && this.dom.nodeName !== '#text') {
138136
this.start();
139137
}
140138
}
141139

142140
componentDidUpdate() {
143-
if (!this.dom) {
144-
this.dom = ReactDom.findDOMNode(this);
145-
}
146141
// 样式更新了后再执行动画;
147142
if (this.updateAnim && this.dom && this.dom.nodeName !== '#text') {
148143
if (this.tween) {
@@ -338,6 +333,9 @@ class TweenOne extends Component {
338333
});
339334
// component 为空时调用子级的。。
340335
const { className, children } = props;
336+
const ref = (c) => {
337+
this.dom = c && c.props ? ReactDom.findDOMNode(c) : c;
338+
};
341339
if (!component && typeof children !== 'string') {
342340
if (!children) {
343341
return children;
@@ -347,12 +345,14 @@ class TweenOne extends Component {
347345
// 合并 style 与 className。
348346
const newStyle = { ...childStyle, ...props.style };
349347
const newClassName = className ? `${className} ${childClass}` : childClass;
350-
return React.cloneElement(children, { style: newStyle, className: newClassName });
348+
return React.cloneElement(children, {
349+
style: newStyle,
350+
ref,
351+
className: newClassName,
352+
});
351353
}
352354
return React.createElement(component, {
353-
ref: (c) => {
354-
this.currentRef = c;
355-
},
355+
ref,
356356
...props,
357357
...componentProps
358358
});

src/TweenOneGroup.jsx

Lines changed: 64 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import {
1212
findChildInChildrenByKey,
1313
} from './util';
1414

15-
function noop() {
16-
}
15+
function noop() {}
1716

1817
class TweenOneGroup extends Component {
1918
static getDerivedStateFromProps(props, { prevProps, $self }) {
@@ -68,10 +67,12 @@ class TweenOneGroup extends Component {
6867
delete this.isTween[key];
6968
if (classIsSvg) {
7069
tag.className.baseVal = tag.className.baseVal
71-
.replace(this.props.animatingClassName[isEnter ? 0 : 1], '').trim();
70+
.replace(this.props.animatingClassName[isEnter ? 0 : 1], '')
71+
.trim();
7272
} else {
7373
tag.className = tag.className
74-
.replace(this.props.animatingClassName[isEnter ? 0 : 1], '').trim();
74+
.replace(this.props.animatingClassName[isEnter ? 0 : 1], '')
75+
.trim();
7576
}
7677
if (type === 'enter') {
7778
this.keysToEnter.splice(this.keysToEnter.indexOf(key), 1);
@@ -88,40 +89,47 @@ class TweenOneGroup extends Component {
8889
delete this.saveTweenTag[$key];
8990
}
9091
});
91-
this.setState({
92-
children: this.currentChildren,
93-
}, this.reAnimQueue);
92+
this.setState(
93+
{
94+
children: this.currentChildren,
95+
},
96+
this.reAnimQueue,
97+
);
9498
}
9599
}
96100
const _obj = { key, type };
97101
this.props.onEnd(_obj);
98102
}
99-
}
103+
};
100104

101105
setClassName = (name, isEnter) => {
102106
let className = name.replace(this.props.animatingClassName[isEnter ? 1 : 0], '').trim();
103107
if (className.indexOf(this.props.animatingClassName[isEnter ? 0 : 1]) === -1) {
104108
className = `${className} ${this.props.animatingClassName[isEnter ? 0 : 1]}`.trim();
105109
}
106110
return className;
107-
}
111+
};
108112

109113
getTweenChild = (child, props = {}) => {
110114
const key = child.key;
111-
this.saveTweenTag[key] = React.createElement(TweenOne, {
112-
...props,
113-
key,
114-
component: null,
115-
}, child);
115+
this.saveTweenTag[key] = React.createElement(
116+
TweenOne,
117+
{
118+
...props,
119+
key,
120+
component: null,
121+
},
122+
child,
123+
);
116124
return this.saveTweenTag[key];
117-
}
125+
};
118126

119127
getCoverAnimation = (child, i, type) => {
120128
let animation;
121129
animation = type === 'leave' ? this.props.leave : this.props.enter;
122130
if (type === 'appear') {
123131
const appear = transformArguments(this.props.appear, child.key, i);
124-
animation = appear && this.props.enter || null;
132+
animation = (appear && this.props.enter) || null;
125133
}
126134
const animate = transformArguments(animation, child.key, i);
127135
const onChange = this.onChange.bind(this, animate, child.key, type);
@@ -131,56 +139,62 @@ class TweenOneGroup extends Component {
131139
onChange,
132140
resetStyle: this.props.resetStyle,
133141
};
134-
if (this.keysToEnter.concat(this.keysToLeave).indexOf(child.key) >= 0
135-
|| !this.onEnterBool && animation) {
142+
if (
143+
this.keysToEnter.concat(this.keysToLeave).indexOf(child.key) >= 0 ||
144+
(!this.onEnterBool && animation)
145+
) {
136146
if (!this.saveTweenTag[child.key]) {
137147
this.isTween[child.key] = type;
138148
}
139149
}
140150
const children = this.getTweenChild(child, props);
141151
return children;
142-
}
152+
};
143153

144154
getChildrenToRender = children => {
145155
return children.map((child, i) => {
146156
if (!child || !child.key) {
147157
return child;
148158
}
149159
const key = child.key;
150-
151160
if (this.keysToLeave.indexOf(key) >= 0) {
152161
return this.getCoverAnimation(child, i, 'leave');
153-
} else if (((this.keysToEnter.indexOf(key) >= 0) ||
154-
(this.isTween[key] && this.keysToLeave.indexOf(key) === -1)) &&
155-
!(this.isTween[key] === 'enter' && this.saveTweenTag[key])) {
162+
} else if (
163+
(this.keysToEnter.indexOf(key) >= 0 ||
164+
(this.isTween[key] && this.keysToLeave.indexOf(key) === -1)) &&
165+
!(this.isTween[key] === 'enter' && this.saveTweenTag[key])
166+
) {
156167
/**
157-
* 1. 在 key 在 enter 里。
158-
* 2. 出场未结束,触发进场, this.isTween[key] 为 leave, key 在 enter 里。
159-
* 3. 状态为 enter 且 tweenTag 里有值时,不执行重载动画属性,直接调用 tweenTag 里的。
160-
*/
168+
* 1. 在 key 在 enter 里。
169+
* 2. 出场未结束,触发进场, this.isTween[key] 为 leave, key 在 enter 里。
170+
* 3. 状态为 enter 且 tweenTag 里有值时,不执行重载动画属性,直接调用 tweenTag 里的。
171+
*/
161172
return this.getCoverAnimation(child, i, 'enter');
162173
} else if (!this.onEnterBool) {
163174
return this.getCoverAnimation(child, i, 'appear');
164175
}
165176
return this.saveTweenTag[key];
166177
});
167-
}
178+
};
168179

169180
reAnimQueue = () => {
170181
if (!Object.keys(this.isTween).length && this.animQueue.length) {
171-
const children = this.changeChildren(this.animQueue[this.animQueue.length - 1], this.state.children);
182+
const children = this.changeChildren(
183+
this.animQueue[this.animQueue.length - 1],
184+
this.state.children,
185+
);
172186
this.setState({
173187
children,
174188
});
175189
this.animQueue = [];
176190
}
177-
}
191+
};
178192

179193
changeChildren(nextChildren, currentChildren) {
180194
const newChildren = mergeChildren(currentChildren, nextChildren);
181195
this.keysToEnter = [];
182196
this.keysToLeave = [];
183-
nextChildren.forEach((c) => {
197+
nextChildren.forEach(c => {
184198
if (!c) {
185199
return;
186200
}
@@ -195,7 +209,7 @@ class TweenOneGroup extends Component {
195209
}
196210
});
197211

198-
currentChildren.forEach((c) => {
212+
currentChildren.forEach(c => {
199213
if (!c) {
200214
return;
201215
}
@@ -206,31 +220,30 @@ class TweenOneGroup extends Component {
206220
delete this.saveTweenTag[key];
207221
}
208222
});
209-
this.currentChildren = newChildren;
210223
return newChildren;
211224
}
212225

213226
render() {
214-
const childrenToRender = this.getChildrenToRender(this.state.children);
215-
if (!this.props.component) {
227+
const { children } = this.state;
228+
// fix in strict mode https://github.com/ant-design/ant-motion/issues/323;
229+
this.currentChildren = children;
230+
const childrenToRender = this.getChildrenToRender(children);
231+
const {
232+
component,
233+
componentProps,
234+
appear,
235+
enter,
236+
leave,
237+
animatingClassName,
238+
onEnd,
239+
exclusive,
240+
resetStyle,
241+
...props
242+
} = this.props;
243+
if (!component) {
216244
return childrenToRender[0] || null;
217245
}
218-
const componentProps = { ...this.props };
219-
[
220-
'component',
221-
'componentProps',
222-
'appear',
223-
'enter',
224-
'leave',
225-
'animatingClassName',
226-
'onEnd',
227-
'exclusive',
228-
'resetStyle',
229-
].forEach(key => delete componentProps[key]);
230-
return createElement(this.props.component,
231-
{ ...componentProps, ...this.props.componentProps },
232-
childrenToRender
233-
);
246+
return createElement(component, { ...props, ...componentProps }, childrenToRender);
234247
}
235248
}
236249

src/plugin/SvgDrawPlugin.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ SvgDrawPlugin.prototype = {
6565
return Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (3 * ry + rx)));
6666
},
6767
getAnimStart(computedStyle) {
68+
if (Object.keys(this.start).length) {
69+
return;
70+
}
6871
const getAttribute = (str) => (this.target.getAttribute(str));
6972
switch (this.tagName) {
7073
case 'circle':

0 commit comments

Comments
 (0)