rc-banner-anim
Version:
banner-anim animation component for react
431 lines (379 loc) • 14.4 kB
JavaScript
;
exports.__esModule = true;
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _ticker = require('rc-tween-one/lib/ticker');
var _ticker2 = _interopRequireDefault(_ticker);
var _Arrow = require('./Arrow');
var _Arrow2 = _interopRequireDefault(_Arrow);
var _Thumb = require('./Thumb');
var _Thumb2 = _interopRequireDefault(_Thumb);
var _utils = require('./utils');
var _anim = require('./anim');
var _anim2 = _interopRequireDefault(_anim);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var BannerAnim = function (_Component) {
(0, _inherits3['default'])(BannerAnim, _Component);
function BannerAnim(props) {
(0, _classCallCheck3['default'])(this, BannerAnim);
var _this = (0, _possibleConstructorReturn3['default'])(this, _Component.call(this, props));
_this.onMouseEnter = function () {
_this.props.onMouseEnter();
if (_this.props.autoPlay) {
_ticker2['default'].clear(_this.autoPlayId);
_this.autoPlayId = -1;
}
};
_this.onMouseLeave = function () {
_this.props.onMouseLeave();
if (_this.props.autoPlay) {
_this.autoPlay();
}
};
_this.onTouchStart = function (e) {
if (e.touches && e.touches.length > 1 || _this.elemWrapper.length <= 1 || _this.getDomIsArrowOrThumb(e) || e.button === 2) {
return;
}
if (_this.props.autoPlay) {
_ticker2['default'].clear(_this.autoPlayId);
_this.autoPlayId = -1;
}
_this.animType = _this.getAnimType(_this.props.type);
_this.currentShow = _this.state.currentShow;
// this.mouseMoveType = 'start';
_this.mouseStartXY = {
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.mouseStartXY || e.touches && e.touches.length > 1) {
return;
}
var currentX = e.touches === undefined ? e.clientX : e.touches[0].clientX;
var differX = currentX - _this.mouseStartXY.startX;
if (!differX) {
return;
}
var ratio = differX / _this.state.domRect.width * 2;
var ratioType = _this.ratioType;
var currentShow = _this.currentShow;
if (ratio > 0) {
ratioType = '+';
} else {
ratioType = '-';
}
_this.mouseMoveType = 'update';
if (_this.ratioType !== ratioType) {
_this.ratioType = ratioType;
_this.mouseMoveType = 'reChild';
_this.setState({
currentShow: currentShow
});
return;
}
_this.ratio = ratio;
if (_this.ratio) {
var type = void 0;
if (_this.ratio > 0) {
currentShow += 1;
type = 'next';
} else {
currentShow -= 1;
type = 'prev';
}
_this.ratio = Math.abs(_this.ratio);
_this.ratio = _this.ratio > 1 ? 1 : _this.ratio;
currentShow = currentShow >= _this.elemWrapper.length ? 0 : currentShow;
currentShow = currentShow < 0 ? _this.elemWrapper.length - 1 : currentShow;
_this.setState({
currentShow: currentShow,
direction: type
});
}
};
_this.onTouchEnd = function (e) {
if (!_this.mouseStartXY || e.changedTouches && e.changedTouches.length > 1) {
return;
}
if (_this.props.autoPlay && _this.autoPlayId === -1) {
_this.autoPlay();
}
var currentX = e.changedTouches === undefined ? e.clientX : e.changedTouches[0].clientX;
var differX = currentX - _this.mouseStartXY.startX;
delete _this.mouseStartXY;
_this.mouseMoveType = 'end';
if (!differX) {
_this.mouseMoveType = '';
return;
}
if (_this.ratio > 0.3) {
_this.forceUpdate(function () {
_this.ratio = 0;
_this.mouseMoveType = '';
});
} else {
_this.setState({
currentShow: _this.currentShow,
direction: _this.ratioType === '+' ? 'prev' : 'next'
}, function () {
_this.ratio = 0;
_this.mouseMoveType = '';
});
}
};
_this.getDomIsArrowOrThumb = function (e) {
var arrowClassName = e.target.className;
var thumbClassName = e.target.parentNode.className;
if (arrowClassName.indexOf('banner-anim-arrow') >= 0 || thumbClassName.indexOf('banner-anim-thumb') >= 0) {
return true;
}
return false;
};
_this.getRenderChildren = function (children) {
var elem = [];
var arrow = [];
var thumb = void 0;
(0, _utils.toArrayChildren)(children).forEach(function (item, i) {
if (!item) {
return;
}
if (!item.key) {
throw new Error('Please add key, key is required');
}
var itemProps = (0, _extends3['default'])({}, item.props);
if (item.type.isBannerAnimElement) {
itemProps.key = item.key;
itemProps.callBack = _this.animEnd;
itemProps.show = _this.state.currentShow === i;
itemProps.animType = _this.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;
itemProps.ratio = _this.ratio;
itemProps.mouseMoveType = _this.mouseMoveType;
elem.push(_react2['default'].cloneElement(item, itemProps));
} else if (item.type.isBannerAnimArrow) {
itemProps.next = _this.next;
itemProps.prev = _this.prev;
itemProps.elemHeight = _this.state.wrapperHeight;
arrow.push(_react2['default'].cloneElement(item, itemProps));
} else if (item.type.isBannerAnimThumb) {
itemProps.thumbClick = _this.slickGoTo;
itemProps.active = _this.state.currentShow;
thumb = _react2['default'].cloneElement(item, itemProps);
}
});
if (elem.length > 1) {
if (!arrow.length && _this.props.arrow) {
arrow.push(_react2['default'].createElement(_Arrow2['default'], { arrowType: 'prev', key: 'arrowPrev', next: _this.next, prev: _this.prev, 'default': true,
elemHeight: _this.state.wrapperHeight
}), _react2['default'].createElement(_Arrow2['default'], { arrowType: 'next', key: 'arrowNext', next: _this.next, prev: _this.prev, 'default': true,
elemHeight: _this.state.wrapperHeight
}));
}
if (!thumb && _this.props.thumb) {
thumb = _react2['default'].createElement(_Thumb2['default'], { 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 = _reactDom2['default'].findDOMNode(_this);
var domRect = _this.dom.getBoundingClientRect();
// 获取宽度与定位,setState刷新;
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 ? (0, _utils.dataToArray)(type) : Object.keys(_anim2['default']);
var random = Math.round(Math.random() * (typeArray.length - 1));
return _anim2['default'][typeArray[random]];
};
_this.autoPlay = function () {
_this.autoPlayId = _ticker2['default'].interval(_this.next, _this.props.autoPlaySpeed);
};
_this.animTweenStart = function (show, type) {
_this.animType = _this.getAnimType(_this.props.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;
}
BannerAnim.prototype.componentDidMount = function componentDidMount() {
this.getDomDataSetToState();
if (window.addEventListener) {
window.addEventListener('touchend', this.onTouchEnd);
window.addEventListener('mouseup', this.onTouchEnd);
window.addEventListener('resize', this.getDomDataSetToState);
} else {
window.attachEvent('ontouchend', this.onTouchEnd);
window.attachEvent('onmouseup', this.onTouchEnd);
window.attachEvent('onresize', this.getDomDataSetToState);
}
if (this.props.autoPlay) {
this.autoPlay();
}
};
BannerAnim.prototype.componentWillReceiveProps = function componentWillReceiveProps() {
this.tweenBool = false;
};
BannerAnim.prototype.componentWillUnmount = function componentWillUnmount() {
if (this.autoPlayId) {
_ticker2['default'].clear(this.autoPlayId);
this.autoPlayId = 0;
}
if (window.addEventListener) {
window.removeEventListener('touchend', this.onTouchEnd);
window.removeEventListener('mouseup', this.onTouchEnd);
window.removeEventListener('resize', this.getDomDataSetToState);
} else {
window.detachEvent('ontouchend', this.onTouchEnd);
window.attachEvent('onmouseup', this.onTouchEnd);
window.detachEvent('onresize', this.getDomDataSetToState);
}
};
BannerAnim.prototype.render = function render() {
var prefixCls = this.props.prefixCls;
var props = (0, _extends3['default'])({}, 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 = (0, _extends3['default'])({}, props.style);
props.onMouseEnter = this.onMouseEnter;
props.onMouseLeave = this.onMouseLeave;
if (childrenToRender.length > 1 && this.props.dragPlay) {
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 _react2['default'].createElement(this.props.component, props, childrenToRender);
};
return BannerAnim;
}(_react.Component);
BannerAnim.propTypes = {
children: _propTypes2['default'].any,
style: _propTypes2['default'].object,
className: _propTypes2['default'].string,
prefixCls: _propTypes2['default'].string,
component: _propTypes2['default'].any,
arrow: _propTypes2['default'].bool,
thumb: _propTypes2['default'].bool,
initShow: _propTypes2['default'].number,
type: _propTypes2['default'].any,
duration: _propTypes2['default'].number,
delay: _propTypes2['default'].number,
ease: _propTypes2['default'].string,
autoPlay: _propTypes2['default'].bool,
autoPlaySpeed: _propTypes2['default'].number,
onChange: _propTypes2['default'].func,
onMouseEnter: _propTypes2['default'].func,
onMouseLeave: _propTypes2['default'].func,
sync: _propTypes2['default'].bool,
dragPlay: _propTypes2['default'].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;
exports['default'] = BannerAnim;
module.exports = exports['default'];