1 | import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
|
2 | import _extends from 'babel-runtime/helpers/extends';
|
3 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
4 | import _createClass from 'babel-runtime/helpers/createClass';
|
5 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
6 | import _inherits from 'babel-runtime/helpers/inherits';
|
7 | import React, { Component } from 'react';
|
8 | import PropTypes from 'prop-types';
|
9 | import ReactDOM from 'react-dom';
|
10 | import TweenOne from 'rc-tween-one';
|
11 | import ticker from 'rc-tween-one/es/ticker';
|
12 | import easeTween from 'tween-functions';
|
13 | import { getGsapType, isConvert, stylesToCss, checkStyleName } from 'style-utils';
|
14 |
|
15 | import BgElement from './BgElement';
|
16 | import { currentScrollTop, currentScrollLeft, dataToArray, toArrayChildren } from './utils';
|
17 |
|
18 | function noop() {}
|
19 |
|
20 | var Element = function (_Component) {
|
21 | _inherits(Element, _Component);
|
22 |
|
23 | function Element(props) {
|
24 | _classCallCheck(this, Element);
|
25 |
|
26 | var _this = _possibleConstructorReturn(this, (Element.__proto__ || Object.getPrototypeOf(Element)).call(this, props));
|
27 |
|
28 | _initialiseProps.call(_this);
|
29 |
|
30 | _this.state = {
|
31 | show: _this.props.show
|
32 | };
|
33 | _this.tickerId = -1;
|
34 | _this.enterMouse = null;
|
35 | _this.delayTimeout = null;
|
36 | _this.show = _this.state.show;
|
37 | _this.followParallax = _this.props.followParallax;
|
38 | _this.transform = checkStyleName('transform');
|
39 | return _this;
|
40 | }
|
41 |
|
42 | _createClass(Element, [{
|
43 | key: 'componentDidMount',
|
44 | value: function componentDidMount() {
|
45 | this.dom = ReactDOM.findDOMNode(this);
|
46 | }
|
47 | }, {
|
48 | key: 'componentWillReceiveProps',
|
49 | value: function componentWillReceiveProps(nextProps) {
|
50 | var show = nextProps.show;
|
51 | if (this.tickerId !== -1) {
|
52 | ticker.clear(this.tickerId);
|
53 | this.tickerId = -1;
|
54 | }
|
55 | var followParallax = nextProps.followParallax;
|
56 | if (this.followParallax && !followParallax) {
|
57 | this.reFollowParallax();
|
58 | } else {
|
59 | this.followParallax = followParallax;
|
60 | }
|
61 | this.setState({ show: show, mouseMoveType: nextProps.mouseMoveType });
|
62 | }
|
63 | }, {
|
64 | key: 'componentDidUpdate',
|
65 | value: function componentDidUpdate() {
|
66 | if (this.followParallax) {
|
67 | this.doms = this.followParallax.data.map(function (item) {
|
68 | return document.getElementById(item.id);
|
69 | });
|
70 | }
|
71 | }
|
72 | }, {
|
73 | key: 'componentWillUnmount',
|
74 | value: function componentWillUnmount() {
|
75 | ticker.clear(this.timeoutID);
|
76 | ticker.clear(this.delayTimeout);
|
77 | this.delayTimeout = -1;
|
78 | this.timeoutID = -1;
|
79 | }
|
80 | }, {
|
81 | key: 'render',
|
82 | value: function render() {
|
83 | var _this2 = this;
|
84 |
|
85 | var props = _extends({}, this.props, this.props.componentProps);
|
86 | var style = _extends({}, props.style);
|
87 | style.display = props.show ? 'block' : 'none';
|
88 | style.position = 'absolute';
|
89 | style.width = '100%';
|
90 | if (this.props.mouseMoveType !== 'end') {
|
91 | style[this.transform] = '';
|
92 | }
|
93 | props.style = style;
|
94 | props.className = ('banner-anim-elem ' + (this.props.prefixCls || '')).trim();
|
95 | var bgElem = toArrayChildren(this.props.children).filter(function (item) {
|
96 | return item && item.type.isBannerAnimBgElement;
|
97 | }).map(function (item) {
|
98 | return React.cloneElement(item, { show: _this2.state.show });
|
99 | });
|
100 | ['prefixCls', 'callBack', 'animType', 'duration', 'delay', 'ease', 'elemOffset', 'followParallax', 'show', 'type', 'direction', 'leaveChildHide', 'sync', 'ratio', 'mouseMoveType'].forEach(function (key) {
|
101 | return delete props[key];
|
102 | });
|
103 | if (this.show === this.state.show && !this.state.mouseMoveType || this.state.mouseMoveType === 'reChild') {
|
104 | if (!this.state.show) {
|
105 | this.enterMouse = null;
|
106 | return React.createElement(TweenOne, props, bgElem);
|
107 | }
|
108 | if (this.props.followParallax) {
|
109 | props.onMouseMove = this.getFollowMouseMove();
|
110 | }
|
111 | return React.createElement(TweenOne, props, this.props.mouseMoveType === 'update' ? bgElem : this.getChildren());
|
112 | }
|
113 | return this.animChildren(props, style, bgElem);
|
114 | }
|
115 | }]);
|
116 |
|
117 | return Element;
|
118 | }(Component);
|
119 |
|
120 | var _initialiseProps = function _initialiseProps() {
|
121 | var _this3 = this;
|
122 |
|
123 | this.onMouseMove = function (e) {
|
124 | _this3.domRect = _this3.dom.getBoundingClientRect();
|
125 | _this3.enterMouse = _this3.enterMouse || { x: _this3.domRect.width / 2, y: _this3.domRect.height / 2 };
|
126 | _this3.domWH = {
|
127 | w: _this3.domRect.width,
|
128 | h: _this3.domRect.height
|
129 | };
|
130 | _this3.offsetTop = _this3.domRect.top + currentScrollTop();
|
131 | _this3.offsetLeft = _this3.domRect.left + currentScrollLeft();
|
132 | var mouseXY = {
|
133 | x: e.pageX - _this3.offsetLeft,
|
134 | y: e.pageY - _this3.offsetTop
|
135 | };
|
136 | _this3.setTicker(_this3.followParallax, mouseXY);
|
137 | };
|
138 |
|
139 | this.setTicker = function (followParallax, mouseXY) {
|
140 | var callback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop;
|
141 |
|
142 | ticker.clear(_this3.tickerId);
|
143 | _this3.tickerId = 'bannerElementTicker' + (Date.now() + Math.random());
|
144 | var startFrame = ticker.frame;
|
145 | var startX = _this3.enterMouse.x;
|
146 | var startY = _this3.enterMouse.y;
|
147 | var duration = followParallax.duration || 450;
|
148 | var easeFunc = easeTween[followParallax.ease || 'easeOutQuad'];
|
149 | var start = typeof followParallax.minMove === 'number' ? followParallax.minMove : 0.08;
|
150 | ticker.wake(_this3.tickerId, function () {
|
151 | var moment = (ticker.frame - startFrame) * ticker.perFrame;
|
152 | var ratio = easeFunc(moment, start, 1, duration);
|
153 | _this3.enterMouse.x = startX + (mouseXY.x - startX) * ratio;
|
154 | _this3.enterMouse.y = startY + (mouseXY.y - startY) * ratio;
|
155 | _this3.setFollowStyle(_this3.domWH);
|
156 | if (moment >= duration) {
|
157 | ticker.clear(_this3.tickerId);
|
158 | callback();
|
159 | }
|
160 | });
|
161 | };
|
162 |
|
163 | this.getFollowMouseMove = function () {
|
164 | var onMouseMove = void 0;
|
165 | if (_this3.followParallax) {
|
166 | if (_this3.followParallax.delay) {
|
167 | onMouseMove = !_this3.delayTimeout ? null : _this3.state.onMouseMove;
|
168 | _this3.delayTimeout = _this3.delayTimeout || ticker.timeout(function () {
|
169 | _this3.setState({
|
170 | onMouseMove: _this3.onMouseMove
|
171 | });
|
172 | }, _this3.followParallax.delay);
|
173 | } else {
|
174 | onMouseMove = _this3.onMouseMove;
|
175 | }
|
176 | }
|
177 | return onMouseMove;
|
178 | };
|
179 |
|
180 | this.getFollowStyle = function (data, domWH) {
|
181 | var style = {};
|
182 | dataToArray(data.type).forEach(function (type) {
|
183 | var mouseData = _this3.enterMouse.x;
|
184 | var domData = domWH.w;
|
185 | var value = data.value;
|
186 | if ((type.indexOf('y') >= 0 || type.indexOf('Y') >= 0) && type !== 'opacity') {
|
187 | mouseData = _this3.enterMouse.y;
|
188 | domData = domWH.h;
|
189 | }
|
190 | var d = (mouseData - domData / 2) / (domData / 2) * value;
|
191 | var _type = getGsapType(type);
|
192 | var cssName = isConvert(_type);
|
193 | if (cssName === 'transform') {
|
194 | var transform = checkStyleName('transform');
|
195 | style[transform] = style[transform] || {};
|
196 | style[transform][_type] = stylesToCss(_type, d).trim();
|
197 | } else if (cssName === 'filter') {
|
198 | var filter = checkStyleName('filter');
|
199 | style[filter] = style[filter] || {};
|
200 | style[filter][_type] = stylesToCss(_type, d).trim();
|
201 | } else {
|
202 | style[cssName] = stylesToCss(_type, d).trim();
|
203 | }
|
204 | });
|
205 | return style;
|
206 | };
|
207 |
|
208 | this.setFollowStyle = function (domWH) {
|
209 | _this3.doms.forEach(function (item, i) {
|
210 | if (!item) {
|
211 | return;
|
212 | }
|
213 | var data = _this3.followParallax.data[i];
|
214 | var style = _this3.getFollowStyle(data, domWH);
|
215 | Object.keys(style).forEach(function (key) {
|
216 | if (typeof style[key] === 'object') {
|
217 | var styleStr = '';
|
218 | Object.keys(style[key]).forEach(function (_key) {
|
219 | styleStr += (' ' + _key + '(' + style[key][_key] + ')').trim();
|
220 | });
|
221 | item.style[key] = styleStr;
|
222 | return;
|
223 | }
|
224 | item.style[key] = key.indexOf('backgroundPosition') >= 0 ? 'calc(' + (data.bgPosition || '0%') + ' + ' + style[key] + ' )' : style[key];
|
225 | });
|
226 | });
|
227 | };
|
228 |
|
229 | this.getChildren = function () {
|
230 | return toArrayChildren(_this3.props.children).map(function (item) {
|
231 | if (item && item.type === BgElement) {
|
232 | return React.cloneElement(item, { show: _this3.state.show });
|
233 | }
|
234 | return item;
|
235 | });
|
236 | };
|
237 |
|
238 | this.reFollowParallax = function () {
|
239 | _this3.setTicker(_this3.followParallax, {
|
240 | x: _this3.domRect.width / 2 - _this3.offsetLeft,
|
241 | y: _this3.domRect.height / 2 - _this3.offsetTop
|
242 | }, function () {
|
243 | _this3.followParallax = null;
|
244 | });
|
245 | };
|
246 |
|
247 | this.animEnd = function () {
|
248 | var type = _this3.state.show ? 'enter' : 'leave';
|
249 | _this3.props.callBack(type);
|
250 | _this3.setState(function (_, props) {
|
251 | return { show: props.show, mouseMoveType: null };
|
252 | });
|
253 | };
|
254 |
|
255 | this.animChildren = function (props, style, bgElem) {
|
256 | var _props = _this3.props,
|
257 | elemOffset = _props.elemOffset,
|
258 | leaveChildHide = _props.leaveChildHide,
|
259 | ratio = _props.ratio,
|
260 | animType = _props.animType,
|
261 | direction = _props.direction,
|
262 | mouseMoveType = _props.mouseMoveType,
|
263 | ease = _props.ease,
|
264 | duration = _props.duration,
|
265 | delay = _props.delay,
|
266 | show = _props.show,
|
267 | sync = _props.sync,
|
268 | component = _props.component;
|
269 |
|
270 | if (_this3.tickerId) {
|
271 | ticker.clear(_this3.tickerId);
|
272 | }
|
273 | if (_this3.delayTimeout) {
|
274 | ticker.clear(_this3.delayTimeout);
|
275 | _this3.delayTimeout = null;
|
276 | }
|
277 | style.display = 'block';
|
278 |
|
279 | props.component = component;
|
280 | _this3.show = _this3.state.show;
|
281 | style.zIndex = _this3.state.show ? 1 : 0;
|
282 | props.children = show && !sync ? bgElem : _this3.getChildren();
|
283 | var childrenToRender = React.createElement(TweenOne, props);
|
284 | var type = _this3.state.show ? 'enter' : 'leave';
|
285 | var $ratio = mouseMoveType === 'end' && ratio <= 0.3 ? 1 - ratio : ratio;
|
286 | var tag = animType(childrenToRender, type, direction, {
|
287 | ease: ease,
|
288 | duration: duration,
|
289 | delay: delay,
|
290 | onComplete: _this3.animEnd
|
291 | }, elemOffset, leaveChildHide, $ratio, _this3.state.mouseMoveType === 'update');
|
292 |
|
293 | var tagProps = _objectWithoutProperties(tag.props, []);
|
294 |
|
295 | if (tagProps.animation) {
|
296 | tagProps.moment = (tagProps.animation.duration + tagProps.animation.delay) * $ratio || 0;
|
297 | tagProps.paused = _this3.state.mouseMoveType === 'update' || $ratio === 1;
|
298 | }
|
299 | return React.cloneElement(tag, tagProps);
|
300 | };
|
301 | };
|
302 |
|
303 | Element.propTypes = {
|
304 | children: PropTypes.any,
|
305 | style: PropTypes.object,
|
306 | prefixCls: PropTypes.string,
|
307 | component: PropTypes.any,
|
308 | elemOffset: PropTypes.object,
|
309 | type: PropTypes.string,
|
310 | animType: PropTypes.func,
|
311 | ease: PropTypes.string,
|
312 | duration: PropTypes.number,
|
313 | delay: PropTypes.number,
|
314 | direction: PropTypes.string,
|
315 | callBack: PropTypes.func,
|
316 | followParallax: PropTypes.any,
|
317 | show: PropTypes.bool,
|
318 | leaveChildHide: PropTypes.bool,
|
319 | sync: PropTypes.bool,
|
320 | ratio: PropTypes.number,
|
321 | mouseMoveType: PropTypes.string,
|
322 | componentProps: PropTypes.object
|
323 | };
|
324 | Element.defaultProps = {
|
325 | component: 'div',
|
326 | componentProps: {},
|
327 | callBack: noop,
|
328 | delay: 0
|
329 | };
|
330 |
|
331 | Element.BgElement = BgElement;
|
332 | Element.isBannerAnimElement = true;
|
333 | export default Element; |
\ | No newline at end of file |