Skip to content
This repository was archived by the owner on Apr 11, 2018. It is now read-only.

Commit 12a9a10

Browse files
committed
feat(zoom-animation): add a Zoom animation component
1 parent d616457 commit 12a9a10

File tree

4 files changed

+237
-0
lines changed

4 files changed

+237
-0
lines changed

examples/zoom.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<style>
5+
.container {
6+
border: 1px solid;
7+
}
8+
9+
.content {
10+
width: 100px;
11+
padding: 10px;
12+
color: #787878;
13+
background-color: #fcf7f8;
14+
font-size: 13px;
15+
font-family: Helvetica, Arial, sans-serif;
16+
letter-spacing: 1px;
17+
text-align: center;
18+
border: 1px solid rgba(0,0,0,.05);
19+
}
20+
</style>
21+
</head>
22+
<body>
23+
<div id="app"></div>
24+
<script src="zoom.js"></script>
25+
</body>
26+
</html>

examples/zoom.jsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import * as React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import { Zoom } from '@telerik/kendo-react-animation';
4+
5+
class App extends React.Component {
6+
constructor(props) {
7+
super(props);
8+
9+
this.state = { direction: "in", index: 1 };
10+
}
11+
12+
onClick = () => {
13+
this.setState({
14+
index: this.state.index + 1
15+
});
16+
}
17+
18+
onChange = (e) => {
19+
this.setState({
20+
direction: e.target.value
21+
});
22+
}
23+
24+
render() {
25+
const { direction, index } = this.state;
26+
27+
return (
28+
<div>
29+
<dl>
30+
<dt>
31+
Direction:
32+
</dt>
33+
<dd>
34+
<select onChange={this.onChange} value={direction}>
35+
<option value="in">In</option>
36+
<option value="out">Out</option>
37+
</select>
38+
</dd>
39+
</dl>
40+
<dl>
41+
<dt>
42+
Zoom:
43+
</dt>
44+
<dd>
45+
<button onClick={this.onClick}>Animate</button>
46+
</dd>
47+
</dl>
48+
49+
<Zoom className="container" direction={direction}>
50+
<div className="content" key={index}>{index}</div>
51+
</Zoom>
52+
</div>
53+
);
54+
}
55+
}
56+
57+
ReactDOM.render(
58+
<App />,
59+
document.getElementById('app')
60+
);

src/Zoom.jsx

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import AnimationGroup from './AnimationGroup';
4+
5+
import assign from 'object-assign';
6+
import styles from '@telerik/kendo-theme-default/styles/animation/main';
7+
import util from './util';
8+
9+
/*eslint react/forbid-prop-types:0*/
10+
11+
export default class Zoom extends React.Component {
12+
static propTypes = {
13+
animateOnZoomIn: React.PropTypes.bool,
14+
animateOnZoomOut: React.PropTypes.bool,
15+
children: React.PropTypes.oneOfType([
16+
React.PropTypes.element,
17+
React.PropTypes.node
18+
]),
19+
className: React.PropTypes.string,
20+
componentChildClassName: React.PropTypes.string,
21+
componentDidZoomIn: React.PropTypes.func,
22+
componentWillZoomIn: React.PropTypes.func,
23+
direction: React.PropTypes.oneOf([ 'in', 'out' ]),
24+
fixedContainer: React.PropTypes.bool,
25+
style: React.PropTypes.object,
26+
transitionName: React.PropTypes.oneOfType([
27+
React.PropTypes.string,
28+
React.PropTypes.shape({
29+
zoomIn: React.PropTypes.string,
30+
zoomInActive: React.PropTypes.string,
31+
zoomOut: React.PropTypes.string,
32+
zoomOutActive: React.PropTypes.string
33+
})
34+
]),
35+
zoomInDuration: React.PropTypes.number,
36+
zoomOutDuration: React.PropTypes.number
37+
}
38+
39+
static defaultProps = {
40+
animateOnZoomIn: true,
41+
animateOnZoomOut: true,
42+
zoomInDuration: 300,
43+
zoomOutDuration: 300,
44+
direction: 'out',
45+
fixedContainer: true
46+
}
47+
48+
constructor(props) {
49+
super(props);
50+
51+
this.state = { style: null };
52+
}
53+
54+
componentDidMount() {
55+
this.updateContainerDimensions();
56+
}
57+
58+
componentWillReceiveProps() {
59+
this.updateContainerDimensions();
60+
}
61+
62+
getDefaultTransitionName() {
63+
const { direction } = this.props;
64+
65+
return {
66+
zoomIn: styles[`zoom-${direction}-enter`],
67+
zoomInActive: styles[`zoom-${direction}-enter-active`],
68+
zoomOut: styles[`zoom-${direction}-leave`],
69+
zoomOutActive: styles[`zoom-${direction}-leave-active`]
70+
};
71+
}
72+
73+
updateContainerDimensions() {
74+
const { height, width } = this.state;
75+
const content = ReactDOM.findDOMNode(this).firstChild.firstChild;
76+
77+
let style = null;
78+
79+
if (this.props.fixedContainer && content) {
80+
const newHeight = util.outerHeight(content);
81+
const newWidth = util.outerWidth(content);
82+
83+
if (height !== newHeight || width !== newWidth) {
84+
style = {
85+
height: newHeight,
86+
width: newWidth
87+
};
88+
}
89+
}
90+
91+
this.setState({ style: style });
92+
}
93+
94+
componentDidEnter = () => {
95+
const { componentDidZoomIn } = this.props;
96+
97+
if (componentDidZoomIn) {
98+
componentDidZoomIn();
99+
}
100+
101+
this.updateContainerDimensions();
102+
}
103+
104+
getChildProps() {
105+
const {
106+
animateOnZoomIn,
107+
animateOnZoomOut,
108+
componentChildClassName,
109+
componentWillZoomIn,
110+
zoomInDuration,
111+
zoomOutDuration,
112+
transitionName = this.getDefaultTransitionName()
113+
} = this.props;
114+
115+
let mappedTransitionName = util.mapTransitionClasses(
116+
transitionName,
117+
[ 'zoomIn', 'zoomOut' ],
118+
[ 'enter', 'leave' ]
119+
);
120+
121+
return {
122+
componentChildClassName: componentChildClassName,
123+
componentDidEnter: this.componentDidEnter,
124+
componentWillEnter: componentWillZoomIn,
125+
transitionAppear: false,
126+
transitionEnter: animateOnZoomIn,
127+
transitionEnterTimeout: zoomInDuration,
128+
transitionLeave: animateOnZoomOut,
129+
transitionLeaveTimeout: zoomOutDuration,
130+
transitionName: mappedTransitionName
131+
};
132+
}
133+
134+
render() {
135+
const { children, className, style } = this.props;
136+
137+
const animationProps = {
138+
childFactory: (child) => React.cloneElement(child, this.getChildProps()),
139+
className: className,
140+
style: assign({}, style, this.state.style),
141+
transitionName: ""
142+
};
143+
144+
return (
145+
<AnimationGroup {...animationProps}>
146+
{children}
147+
</AnimationGroup>
148+
);
149+
}
150+
}

src/main.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export Fade from './Fade';
33
export Expand from './Expand';
44
export Push from './Push';
55
export Slide from './Slide';
6+
export Zoom from './Zoom';

0 commit comments

Comments
 (0)