UNPKG

yunjiwong-slider

Version:
311 lines (288 loc) 10.3 kB
import _extends from 'babel-runtime/helpers/extends'; import _classCallCheck from 'babel-runtime/helpers/classCallCheck'; import _createClass from 'babel-runtime/helpers/createClass'; import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn'; import _inherits from 'babel-runtime/helpers/inherits'; import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import Arrow from './Arrow'; import Thumb from './Thumb'; import ticker from 'rc-tween-one/es/ticker'; import { toArrayChildren, dataToArray } from './utils'; import animType from './anim'; var BannerAnim = function (_Component) { _inherits(BannerAnim, _Component); function BannerAnim() { _classCallCheck(this, BannerAnim); var _this = _possibleConstructorReturn(this, (BannerAnim.__proto__ || Object.getPrototypeOf(BannerAnim)).apply(this, arguments)); _this.onMouseEnter = function () { _this.props.onMouseEnter(); if (_this.props.autoPlay) { ticker.clear(_this.autoPlayId); } }; _this.onMouseLeave = function () { _this.props.onMouseLeave(); if (_this.props.autoPlay) { _this.autoPlay(); } }; _this.onTouchStart = function (e) { _this.mouseXY = { startX: e.touches === undefined ? e.clientX : e.touches[0].clientX, startY: e.touches === undefined ? e.clientY : e.touches[0].clientY }; }; _this.onTouchMove = function (e) { if (!_this.mouseXY) { return; } _this.mouseXY.currentX = e.touches === undefined ? e.clientX : e.touches[0].clientX; _this.mouseXY.currentY = e.touches === undefined ? e.clientY : e.touches[0].clientY; }; _this.onTouchEnd = function () { if (!_this.mouseXY) { return; } var differX = _this.mouseXY.currentX - _this.mouseXY.startX; var differY = _this.mouseXY.currentY - _this.mouseXY.startY; var r = Math.atan2(differY, differX); var angle = Math.round(r * 180 / Math.PI); angle = angle < 0 ? 360 - Math.abs(angle) : angle; if ((angle >= 0 && angle <= 45 || angle >= 315) && differX > _this.state.domRect.width * 0.1) { _this.prev(); } else if (angle >= 135 && angle <= 225 && differX < -_this.state.domRect.width * 0.1) { _this.next(); } delete _this.mouseXY; }; _this.getRenderChildren = function (children) { var elem = []; var arrow = []; var thumb = void 0; var _animType = _this.getAnimType(_this.props.type); toArrayChildren(children).forEach(function (item, i) { if (!item.key) { throw new Error('Please add key, key is required'); } var itemProps = _extends({}, item.props); if (item.type.isBannerAnimElement) { itemProps.key = item.key; itemProps.callBack = _this.animEnd; itemProps.show = _this.state.currentShow === i; itemProps.animType = _animType; itemProps.duration = _this.props.duration; itemProps.delay = _this.props.delay; itemProps.ease = _this.props.ease; itemProps.sync = _this.props.sync || itemProps.sync; itemProps.elemOffset = { top: _this.state.domRect.top, width: _this.state.domRect.width, height: _this.state.wrapperHeight }; itemProps.direction = _this.state.direction; elem.push(React.cloneElement(item, itemProps)); } else if (item.type.isBannerAnimArrow) { itemProps.next = _this.next; itemProps.prev = _this.prev; itemProps.elemHeight = _this.state.wrapperHeight; arrow.push(React.cloneElement(item, itemProps)); } else if (item.type.isBannerAnimThumb) { itemProps.thumbClick = _this.slickGoTo; itemProps.active = _this.state.currentShow; thumb = React.cloneElement(item, itemProps); } }); if (elem.length > 1) { if (!arrow.length && _this.props.arrow) { arrow.push(React.createElement(Arrow, { arrowType: 'prev', key: 'arrowPrev', next: _this.next, prev: _this.prev, 'default': true, elemHeight: _this.state.wrapperHeight }), React.createElement(Arrow, { arrowType: 'next', key: 'arrowNext', next: _this.next, prev: _this.prev, 'default': true, elemHeight: _this.state.wrapperHeight })); } if (!thumb && _this.props.thumb) { thumb = React.createElement(Thumb, { length: elem.length, key: 'thumb', thumbClick: _this.slickGoTo, active: _this.state.currentShow, 'default': true }); } } _this.elemWrapper = elem; return elem.concat(arrow, thumb); }; _this.getDomDataSetToState = function () { _this.dom = ReactDOM.findDOMNode(_this); var domRect = _this.dom.getBoundingClientRect(); var wrapperHeight = _this.getElementHeight(_this.dom.getElementsByClassName('banner-anim-elem')); _this.setState({ wrapperHeight: wrapperHeight, domRect: domRect }); _this.tweenBool = false; }; _this.getElementHeight = function (children) { var height = 0; for (var i = 0; i < children.length; i++) { var dom = children[i]; var _height = dom.getBoundingClientRect().height; height = height > _height ? height : _height; } return height; }; _this.getAnimType = function (type) { var typeArray = type ? dataToArray(type) : Object.keys(animType); var random = Math.round(Math.random() * (typeArray.length - 1)); return animType[typeArray[random]]; }; _this.autoPlay = function () { _this.autoPlayId = ticker.interval(_this.next, _this.props.autoPlaySpeed); }; _this.animTweenStart = function (show, type) { _this.props.onChange('before', show); _this.setState({ currentShow: show, direction: type }); }; _this.animEnd = function (type) { if (type === 'enter') { _this.tweenBool = false; _this.props.onChange('after', _this.state.currentShow); } }; _this.next = function () { if (!_this.tweenBool) { _this.tweenBool = true; var newShow = _this.state.currentShow; newShow++; if (newShow >= _this.elemWrapper.length) { newShow = 0; } _this.animTweenStart(newShow, 'next'); } }; _this.prev = function () { if (!_this.tweenBool) { _this.tweenBool = true; var newShow = _this.state.currentShow; newShow--; if (newShow < 0) { newShow = _this.elemWrapper.length - 1; } _this.animTweenStart(newShow, 'prev'); } }; _this.slickGoTo = function (i) { if (!_this.tweenBool && i !== _this.state.currentShow) { _this.tweenBool = true; var type = i > _this.state.currentShow ? 'next' : 'prev'; _this.animTweenStart(i, type); } }; _this.state = { currentShow: _this.props.initShow, direction: null, wrapperHeight: 0, domRect: {} }; _this.tweenBool = false; return _this; } _createClass(BannerAnim, [{ key: 'componentDidMount', value: function componentDidMount() { this.getDomDataSetToState(); if (window.addEventListener) { window.addEventListener('resize', this.getDomDataSetToState); } else { window.attachEvent('onresize', this.getDomDataSetToState); } if (this.props.autoPlay) { this.autoPlay(); } } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps() { this.tweenBool = false; } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { if (this.autoPlayId) { ticker.clear(this.autoPlayId); this.autoPlayId = 0; } if (window.addEventListener) { window.removeEventListener('resize', this.getDomDataSetToState); } else { window.detachEvent('onresize', this.getDomDataSetToState); } } }, { key: 'render', value: function render() { var prefixCls = this.props.prefixCls; var props = _extends({}, this.props); ['type', 'prefixCls', 'component', 'initShow', 'duration', 'delay', 'ease', 'arrow', 'thumb', 'autoPlaySpeed', 'autoPlay', 'thumbFloat', 'sync', 'dragPlay'].forEach(function (key) { return delete props[key]; }); var childrenToRender = this.getRenderChildren(props.children); props.className = (props.className + ' ' + (prefixCls || '')).trim(); props.style = _extends({}, props.style); if (childrenToRender.length > 1 && this.props.dragPlay) { props.onMouseEnter = this.onMouseEnter; props.onMouseLeave = this.onMouseLeave; props.onTouchStart = this.onTouchStart; props.onMouseDown = this.onTouchStart; props.onTouchMove = this.onTouchMove; props.onMouseMove = this.onTouchMove; props.onTouchEnd = this.onTouchEnd; props.onMouseUp = this.onTouchEnd; } return React.createElement(this.props.component, props, childrenToRender); } }]); return BannerAnim; }(Component); BannerAnim.propTypes = { children: PropTypes.any, style: PropTypes.object, className: PropTypes.string, prefixCls: PropTypes.string, component: PropTypes.any, arrow: PropTypes.bool, thumb: PropTypes.bool, initShow: PropTypes.number, type: PropTypes.any, duration: PropTypes.number, delay: PropTypes.number, ease: PropTypes.string, autoPlay: PropTypes.bool, autoPlaySpeed: PropTypes.number, onChange: PropTypes.func, onMouseEnter: PropTypes.func, onMouseLeave: PropTypes.func, sync: PropTypes.bool, dragPlay: PropTypes.bool }; BannerAnim.defaultProps = { component: 'div', className: 'banner-anim', initShow: 0, duration: 450, delay: 0, ease: 'easeInOutQuad', arrow: true, thumb: true, autoPlaySpeed: 5000, dragPlay: true, onChange: function onChange() {}, onMouseEnter: function onMouseEnter() {}, onMouseLeave: function onMouseLeave() {} }; BannerAnim.isBannerAnim = true; export default BannerAnim;