1 | import _extends from 'babel-runtime/helpers/extends';
|
2 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
3 | import _createClass from 'babel-runtime/helpers/createClass';
|
4 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
5 | import _inherits from 'babel-runtime/helpers/inherits';
|
6 | import React, { Component } from 'react';
|
7 | import ReactDOM from 'react-dom';
|
8 | import PropTypes from 'prop-types';
|
9 | import ticker from 'rc-tween-one/es/ticker';
|
10 | import Arrow from './Arrow';
|
11 | import Thumb from './Thumb';
|
12 | import { toArrayChildren, dataToArray } from './utils';
|
13 | import animType from './anim';
|
14 |
|
15 | var BannerAnim = function (_Component) {
|
16 | _inherits(BannerAnim, _Component);
|
17 |
|
18 | function BannerAnim(props) {
|
19 | _classCallCheck(this, BannerAnim);
|
20 |
|
21 | var _this = _possibleConstructorReturn(this, (BannerAnim.__proto__ || Object.getPrototypeOf(BannerAnim)).call(this, props));
|
22 |
|
23 | _this.onMouseEnter = function (e) {
|
24 | _this.props.onMouseEnter(e);
|
25 | if (_this.props.autoPlay && _this.props.autoPlayEffect) {
|
26 | ticker.clear(_this.autoPlayId);
|
27 | _this.autoPlayId = -1;
|
28 | }
|
29 | };
|
30 |
|
31 | _this.onMouseLeave = function (e) {
|
32 | _this.props.onMouseLeave(e);
|
33 | if (_this.props.autoPlay && _this.props.autoPlayEffect) {
|
34 | _this.autoPlay();
|
35 | }
|
36 | };
|
37 |
|
38 | _this.onTouchStart = function (e) {
|
39 | if (e.touches && e.touches.length > 1 || _this.elemWrapper.length <= 1 || _this.getDomIsArrowOrThumb(e) || e.button === 2 || _this.tweenBool) {
|
40 | return;
|
41 | }
|
42 | if (_this.props.autoPlay) {
|
43 | ticker.clear(_this.autoPlayId);
|
44 | _this.autoPlayId = -1;
|
45 | }
|
46 | _this.animType = _this.getAnimType(_this.props.type);
|
47 | _this.currentShow = _this.state.currentShow;
|
48 |
|
49 | _this.mouseStartXY = {
|
50 | startX: e.touches === undefined ? e.clientX : e.touches[0].clientX,
|
51 | startY: e.touches === undefined ? e.clientY : e.touches[0].clientY
|
52 | };
|
53 | };
|
54 |
|
55 | _this.onTouchMove = function (e) {
|
56 | if (!_this.mouseStartXY || e.touches && e.touches.length > 1 || _this.tweenBool) {
|
57 | return;
|
58 | }
|
59 |
|
60 | var _this$getDiffer = _this.getDiffer(e, e.touches),
|
61 | differ = _this$getDiffer.differ,
|
62 | rectName = _this$getDiffer.rectName;
|
63 |
|
64 | if (!differ) {
|
65 | return;
|
66 | }
|
67 | var ratio = differ / _this.state.domRect[rectName] * 2;
|
68 | var ratioType = ratio > 0 ? '+' : '-';
|
69 | var currentShow = _this.currentShow;
|
70 | _this.mouseMoveType = 'update';
|
71 | if (_this.ratioType !== ratioType) {
|
72 | _this.ratioType = ratioType;
|
73 | _this.mouseMoveType = 'reChild';
|
74 | _this.setState({
|
75 | currentShow: currentShow
|
76 | });
|
77 | return;
|
78 | }
|
79 | if ((_this.animType === animType.gridBar || _this.animType === animType.grid) && e.touches) {
|
80 | return;
|
81 | }
|
82 | _this.ratio = ratio;
|
83 | if (_this.ratio) {
|
84 | var type = void 0;
|
85 | if (_this.ratio > 0) {
|
86 | currentShow += 1;
|
87 | type = 'next';
|
88 | } else {
|
89 | currentShow -= 1;
|
90 | type = 'prev';
|
91 | }
|
92 | _this.ratio = Math.abs(_this.ratio);
|
93 | _this.ratio = _this.ratio > 0.99 ? 0.99 : _this.ratio;
|
94 | currentShow = currentShow >= _this.elemWrapper.length ? 0 : currentShow;
|
95 | currentShow = currentShow < 0 ? _this.elemWrapper.length - 1 : currentShow;
|
96 | _this.setState({
|
97 | currentShow: currentShow,
|
98 | direction: type
|
99 | });
|
100 | }
|
101 | };
|
102 |
|
103 | _this.onTouchEnd = function (e) {
|
104 | if (!_this.mouseStartXY || e.changedTouches && e.changedTouches.length > 1 || _this.tweenBool) {
|
105 | return;
|
106 | }
|
107 | if (_this.props.autoPlay && _this.autoPlayId === -1) {
|
108 | _this.autoPlay();
|
109 | }
|
110 |
|
111 | var _this$getDiffer2 = _this.getDiffer(e, e.changedTouches),
|
112 | differ = _this$getDiffer2.differ,
|
113 | rectName = _this$getDiffer2.rectName;
|
114 |
|
115 | delete _this.mouseStartXY;
|
116 | _this.mouseMoveType = 'end';
|
117 | if (!differ) {
|
118 | _this.mouseMoveType = '';
|
119 | return;
|
120 | }
|
121 | _this.tweenBool = true;
|
122 | if ((_this.animType === animType.gridBar || _this.animType === animType.grid) && e.changedTouches) {
|
123 | var currentShow = _this.currentShow;
|
124 | var ratio = differ / _this.state.domRect[rectName] * 2;
|
125 | if (ratio > 0) {
|
126 | currentShow += 1;
|
127 | } else {
|
128 | currentShow -= 1;
|
129 | }
|
130 | currentShow = currentShow >= _this.elemWrapper.length ? 0 : currentShow;
|
131 | currentShow = currentShow < 0 ? _this.elemWrapper.length - 1 : currentShow;
|
132 | _this.ratio = 0;
|
133 | _this.mouseMoveType = '';
|
134 | _this.slickGoTo(currentShow, true);
|
135 | return;
|
136 | }
|
137 |
|
138 | if (_this.ratio > 0.3) {
|
139 | _this.forceUpdate(function () {
|
140 | _this.ratio = 0;
|
141 | _this.mouseMoveType = '';
|
142 | });
|
143 | } else {
|
144 | _this.setState({
|
145 | currentShow: _this.currentShow,
|
146 | direction: _this.ratioType === '+' ? 'prev' : 'next'
|
147 | }, function () {
|
148 | _this.ratio = 0;
|
149 | _this.mouseMoveType = '';
|
150 | });
|
151 | }
|
152 | };
|
153 |
|
154 | _this.getDiffer = function (e, touches) {
|
155 | var currentX = touches === undefined ? e.clientX : touches[0].clientX;
|
156 | var currentY = touches === undefined ? e.clientY : touches[0].clientY;
|
157 | var differX = currentX - _this.mouseStartXY.startX;
|
158 | var differY = currentY - _this.mouseStartXY.startY;
|
159 | var differ = Math.max(Math.abs(differX), Math.abs(differY));
|
160 | differ = differ === Math.abs(differX) ? differX : differY;
|
161 | return {
|
162 | differ: differ,
|
163 | rectName: differ === Math.abs(differX) ? 'width' : 'height'
|
164 | };
|
165 | };
|
166 |
|
167 | _this.getDomIsArrowOrThumb = function (e) {
|
168 | var arrowClassName = e.target.className;
|
169 | var thumbClassName = e.target.parentNode.className;
|
170 | if (arrowClassName.indexOf('banner-anim-arrow') >= 0 || thumbClassName.indexOf('banner-anim-thumb') >= 0) {
|
171 | return true;
|
172 | }
|
173 | return false;
|
174 | };
|
175 |
|
176 | _this.getRenderChildren = function (children) {
|
177 | var elem = [];
|
178 | var arrow = [];
|
179 | var thumb = void 0;
|
180 | var elementKeyNum = 0;
|
181 | var thumbKeyNum = 0;
|
182 |
|
183 | toArrayChildren(children).forEach(function (item, i) {
|
184 | if (!item) {
|
185 | return;
|
186 | }
|
187 | var itemProps = _extends({}, item.props);
|
188 | if (item.type.isBannerAnimElement) {
|
189 | itemProps.key = item.key || 'element-' + elementKeyNum;
|
190 | elementKeyNum += 1;
|
191 | itemProps.callBack = _this.animEnd;
|
192 | itemProps.show = _this.state.currentShow === i;
|
193 | itemProps.animType = _this.animType;
|
194 | itemProps.duration = _this.props.duration;
|
195 | itemProps.delay = _this.props.delay;
|
196 | itemProps.ease = _this.props.ease;
|
197 | itemProps.sync = _this.props.sync || itemProps.sync;
|
198 | itemProps.elemOffset = {
|
199 | top: _this.state.domRect.top,
|
200 | width: _this.state.domRect.width,
|
201 | height: _this.state.wrapperHeight
|
202 | };
|
203 | itemProps.direction = _this.state.direction;
|
204 | itemProps.ratio = _this.ratio;
|
205 | itemProps.mouseMoveType = _this.mouseMoveType;
|
206 | elem.push(React.cloneElement(item, itemProps));
|
207 | } else if (item.type.isBannerAnimArrow) {
|
208 | itemProps.next = _this.next;
|
209 | itemProps.prev = _this.prev;
|
210 | itemProps.key = item.key || itemProps.arrowType;
|
211 | itemProps.elemHeight = _this.state.wrapperHeight;
|
212 | arrow.push(React.cloneElement(item, itemProps));
|
213 | } else if (item.type.isBannerAnimThumb) {
|
214 | itemProps.key = item.key || 'thumb-' + thumbKeyNum;
|
215 | thumbKeyNum += 1;
|
216 | itemProps.thumbClick = _this.slickGoTo;
|
217 | itemProps.active = _this.state.currentShow;
|
218 | thumb = React.cloneElement(item, itemProps);
|
219 | }
|
220 | });
|
221 | if (elem.length > 1) {
|
222 | if (!arrow.length && _this.props.arrow) {
|
223 | arrow.push(React.createElement(Arrow, { arrowType: 'prev', key: 'arrowPrev', next: _this.next, prev: _this.prev, 'default': true,
|
224 | elemHeight: _this.state.wrapperHeight
|
225 | }), React.createElement(Arrow, { arrowType: 'next', key: 'arrowNext', next: _this.next, prev: _this.prev, 'default': true,
|
226 | elemHeight: _this.state.wrapperHeight
|
227 | }));
|
228 | }
|
229 | if (!thumb && _this.props.thumb) {
|
230 | thumb = React.createElement(Thumb, { length: elem.length, key: 'thumb',
|
231 | thumbClick: _this.slickGoTo,
|
232 | active: _this.state.currentShow,
|
233 | 'default': true
|
234 | });
|
235 | }
|
236 | }
|
237 | _this.elemWrapper = elem;
|
238 | return elem.concat(arrow, thumb);
|
239 | };
|
240 |
|
241 | _this.getDomDataSetToState = function () {
|
242 | _this.dom = ReactDOM.findDOMNode(_this);
|
243 | var domRect = _this.dom.getBoundingClientRect();
|
244 |
|
245 | var wrapperHeight = _this.getElementHeight(_this.dom.getElementsByClassName('banner-anim-elem'));
|
246 | _this.setState({
|
247 | wrapperHeight: wrapperHeight,
|
248 | domRect: domRect
|
249 | });
|
250 | _this.tweenBool = false;
|
251 | };
|
252 |
|
253 | _this.getElementHeight = function (children) {
|
254 | var height = 0;
|
255 | for (var i = 0; i < children.length; i++) {
|
256 | var dom = children[i];
|
257 | var _height = dom.getBoundingClientRect().height;
|
258 | height = height > _height ? height : _height;
|
259 | }
|
260 | return height;
|
261 | };
|
262 |
|
263 | _this.getAnimType = function (type) {
|
264 | var typeArray = type ? dataToArray(type) : Object.keys(animType);
|
265 | var random = Math.round(Math.random() * (typeArray.length - 1));
|
266 | return animType[typeArray[random]];
|
267 | };
|
268 |
|
269 | _this.autoPlay = function () {
|
270 | _this.autoPlayId = ticker.interval(_this.next, _this.props.autoPlaySpeed);
|
271 | };
|
272 |
|
273 | _this.animTweenStart = function (show, type, noGetAnimType) {
|
274 | if (!noGetAnimType) {
|
275 | _this.animType = _this.getAnimType(_this.props.type);
|
276 | }
|
277 | _this.props.onChange('before', show);
|
278 | _this.setState({
|
279 | currentShow: show,
|
280 | direction: type
|
281 | });
|
282 | };
|
283 |
|
284 | _this.animEnd = function (type) {
|
285 | if (type === 'enter') {
|
286 | _this.tweenBool = false;
|
287 | _this.props.onChange('after', _this.state.currentShow);
|
288 | }
|
289 | };
|
290 |
|
291 | _this.next = function () {
|
292 | if (!_this.tweenBool) {
|
293 | _this.tweenBool = true;
|
294 | var newShow = _this.state.currentShow;
|
295 | newShow++;
|
296 | if (newShow >= _this.elemWrapper.length) {
|
297 | newShow = 0;
|
298 | }
|
299 | _this.animTweenStart(newShow, 'next');
|
300 | }
|
301 | };
|
302 |
|
303 | _this.prev = function () {
|
304 | if (!_this.tweenBool) {
|
305 | _this.tweenBool = true;
|
306 | var newShow = _this.state.currentShow;
|
307 | newShow--;
|
308 | if (newShow < 0) {
|
309 | newShow = _this.elemWrapper.length - 1;
|
310 | }
|
311 | _this.animTweenStart(newShow, 'prev');
|
312 | }
|
313 | };
|
314 |
|
315 | _this.slickGoTo = function (i, noGetAnimType) {
|
316 | if (!_this.tweenBool && i !== _this.state.currentShow) {
|
317 | _this.tweenBool = true;
|
318 | var type = i > _this.state.currentShow ? 'next' : 'prev';
|
319 | _this.animTweenStart(i, type, noGetAnimType);
|
320 | }
|
321 | };
|
322 |
|
323 | _this.state = {
|
324 | currentShow: _this.props.initShow,
|
325 | direction: null,
|
326 | wrapperHeight: 0,
|
327 | domRect: {}
|
328 | };
|
329 | _this.tweenBool = false;
|
330 | return _this;
|
331 | }
|
332 |
|
333 | _createClass(BannerAnim, [{
|
334 | key: 'componentDidMount',
|
335 | value: function componentDidMount() {
|
336 | this.getDomDataSetToState();
|
337 | if (window.addEventListener) {
|
338 | window.addEventListener('resize', this.getDomDataSetToState);
|
339 | } else {
|
340 | window.attachEvent('onresize', this.getDomDataSetToState);
|
341 | }
|
342 | if (this.props.autoPlay) {
|
343 | this.autoPlay();
|
344 | }
|
345 | }
|
346 | }, {
|
347 | key: 'componentWillReceiveProps',
|
348 | value: function componentWillReceiveProps() {
|
349 | this.tweenBool = false;
|
350 | }
|
351 | }, {
|
352 | key: 'componentWillUnmount',
|
353 | value: function componentWillUnmount() {
|
354 | if (this.autoPlayId) {
|
355 | ticker.clear(this.autoPlayId);
|
356 | this.autoPlayId = 0;
|
357 | }
|
358 | if (window.addEventListener) {
|
359 | window.removeEventListener('touchend', this.onTouchEnd);
|
360 | window.removeEventListener('mouseup', this.onTouchEnd);
|
361 | window.removeEventListener('resize', this.getDomDataSetToState);
|
362 | } else {
|
363 | window.detachEvent('ontouchend', this.onTouchEnd);
|
364 | window.attachEvent('onmouseup', this.onTouchEnd);
|
365 | window.detachEvent('onresize', this.getDomDataSetToState);
|
366 | }
|
367 | }
|
368 | }, {
|
369 | key: 'render',
|
370 | value: function render() {
|
371 | var prefixCls = this.props.prefixCls;
|
372 | var props = _extends({}, this.props);
|
373 | ['type', 'prefixCls', 'component', 'initShow', 'duration', 'delay', 'ease', 'arrow', 'thumb', 'autoPlaySpeed', 'autoPlay', 'thumbFloat', 'sync', 'dragPlay', 'autoPlayEffect'].forEach(function (key) {
|
374 | return delete props[key];
|
375 | });
|
376 | var childrenToRender = this.getRenderChildren(props.children);
|
377 | props.className = (props.className + ' ' + (prefixCls || '')).trim();
|
378 | props.style = _extends({}, props.style);
|
379 | props.onMouseEnter = this.onMouseEnter;
|
380 | props.onMouseLeave = this.onMouseLeave;
|
381 | if (childrenToRender.length > 1 && this.props.dragPlay) {
|
382 | props.onTouchStart = this.onTouchStart;
|
383 | props.onMouseDown = this.onTouchStart;
|
384 | props.onTouchMove = this.onTouchMove;
|
385 | props.onMouseMove = this.onTouchMove;
|
386 | props.onTouchEnd = this.onTouchEnd;
|
387 | props.onMouseUp = this.onTouchEnd;
|
388 | }
|
389 | return React.createElement(this.props.component, props, childrenToRender);
|
390 | }
|
391 | }]);
|
392 |
|
393 | return BannerAnim;
|
394 | }(Component);
|
395 |
|
396 | BannerAnim.propTypes = {
|
397 | children: PropTypes.any,
|
398 | style: PropTypes.object,
|
399 | className: PropTypes.string,
|
400 | prefixCls: PropTypes.string,
|
401 | component: PropTypes.any,
|
402 | arrow: PropTypes.bool,
|
403 | thumb: PropTypes.bool,
|
404 | initShow: PropTypes.number,
|
405 | type: PropTypes.any,
|
406 | duration: PropTypes.number,
|
407 | delay: PropTypes.number,
|
408 | ease: PropTypes.string,
|
409 | autoPlay: PropTypes.bool,
|
410 | autoPlaySpeed: PropTypes.number,
|
411 | autoPlayEffect: PropTypes.bool,
|
412 | onChange: PropTypes.func,
|
413 | onMouseEnter: PropTypes.func,
|
414 | onMouseLeave: PropTypes.func,
|
415 | sync: PropTypes.bool,
|
416 | dragPlay: PropTypes.bool
|
417 | };
|
418 | BannerAnim.defaultProps = {
|
419 | component: 'div',
|
420 | className: 'banner-anim',
|
421 | initShow: 0,
|
422 | duration: 450,
|
423 | delay: 0,
|
424 | ease: 'easeInOutQuad',
|
425 | arrow: true,
|
426 | thumb: true,
|
427 | autoPlaySpeed: 5000,
|
428 | autoPlayEffect: true,
|
429 | dragPlay: true,
|
430 | onChange: function onChange() {},
|
431 | onMouseEnter: function onMouseEnter() {},
|
432 | onMouseLeave: function onMouseLeave() {}
|
433 | };
|
434 | BannerAnim.isBannerAnim = true;
|
435 | export default BannerAnim; |
\ | No newline at end of file |