rc-banner-anim
Version:
banner-anim animation component for react
363 lines (306 loc) • 12.8 kB
JavaScript
'use strict';
exports.__esModule = true;
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
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 _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _rcTweenOne = require('rc-tween-one');
var _rcTweenOne2 = _interopRequireDefault(_rcTweenOne);
var _ticker = require('rc-tween-one/lib/ticker');
var _ticker2 = _interopRequireDefault(_ticker);
var _tweenFunctions = require('tween-functions');
var _tweenFunctions2 = _interopRequireDefault(_tweenFunctions);
var _styleUtils = require('style-utils');
var _BgElement = require('./BgElement');
var _BgElement2 = _interopRequireDefault(_BgElement);
var _utils = require('./utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function noop() {}
var Element = function (_Component) {
(0, _inherits3['default'])(Element, _Component);
function Element(props) {
(0, _classCallCheck3['default'])(this, Element);
var _this = (0, _possibleConstructorReturn3['default'])(this, _Component.call(this, props));
_initialiseProps.call(_this);
_this.state = {
show: _this.props.show
};
_this.tickerId = -1;
_this.enterMouse = null;
_this.delayTimeout = null;
_this.show = _this.state.show;
_this.followParallax = _this.props.followParallax;
_this.transform = (0, _styleUtils.checkStyleName)('transform');
return _this;
}
Element.prototype.componentDidMount = function componentDidMount() {
this.dom = _reactDom2['default'].findDOMNode(this);
};
Element.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
var show = nextProps.show;
if (this.tickerId !== -1) {
_ticker2['default'].clear(this.tickerId);
this.tickerId = -1;
}
var followParallax = nextProps.followParallax;
if (this.followParallax && !followParallax) {
this.reFollowParallax();
} else {
this.followParallax = followParallax;
}
this.setState({ show: show, mouseMoveType: nextProps.mouseMoveType });
};
Element.prototype.componentDidUpdate = function componentDidUpdate() {
if (this.followParallax) {
this.doms = this.followParallax.data.map(function (item) {
return document.getElementById(item.id);
});
}
};
Element.prototype.componentWillUnmount = function componentWillUnmount() {
_ticker2['default'].clear(this.timeoutID);
_ticker2['default'].clear(this.delayTimeout);
this.delayTimeout = -1;
this.timeoutID = -1;
};
Element.prototype.render = function render() {
var _this2 = this;
var props = (0, _extends3['default'])({}, this.props);
var style = (0, _extends3['default'])({}, props.style);
style.display = props.show ? 'block' : 'none';
style.position = 'absolute';
style.width = '100%';
if (this.props.mouseMoveType !== 'end') {
style[this.transform] = '';
}
props.style = style;
props.className = ('banner-anim-elem ' + (this.props.prefixCls || '')).trim();
var bgElem = (0, _utils.toArrayChildren)(this.props.children).filter(function (item) {
return item.type.isBannerAnimBgElement;
}).map(function (item) {
return _react2['default'].cloneElement(item, { show: _this2.state.show });
});
['prefixCls', 'callBack', 'animType', 'duration', 'delay', 'ease', 'elemOffset', 'followParallax', 'show', 'type', 'direction', 'leaveChildHide', 'sync', 'ratio', 'mouseMoveType'].forEach(function (key) {
return delete props[key];
});
if (this.show === this.state.show && !this.state.mouseMoveType || this.state.mouseMoveType === 'reChild') {
if (!this.state.show) {
this.enterMouse = null;
return _react2['default'].createElement(_rcTweenOne2['default'], props, bgElem);
}
if (this.props.followParallax) {
props.onMouseMove = this.getFollowMouseMove();
}
return _react2['default'].createElement(_rcTweenOne2['default'], props, this.props.mouseMoveType === 'update' ? bgElem : this.getChildren());
}
return this.animChildren(props, style, bgElem);
};
return Element;
}(_react.Component);
var _initialiseProps = function _initialiseProps() {
var _this3 = this;
this.onMouseMove = function (e) {
_this3.domRect = _this3.dom.getBoundingClientRect();
_this3.enterMouse = _this3.enterMouse || { x: _this3.domRect.width / 2, y: _this3.domRect.height / 2 };
_this3.domWH = {
w: _this3.domRect.width,
h: _this3.domRect.height
};
_this3.offsetTop = _this3.domRect.top + (0, _utils.currentScrollTop)();
_this3.offsetLeft = _this3.domRect.left + (0, _utils.currentScrollLeft)();
var mouseXY = {
x: e.pageX - _this3.offsetLeft,
y: e.pageY - _this3.offsetTop
};
_this3.setTicker(_this3.followParallax, mouseXY);
};
this.setTicker = function (followParallax, mouseXY) {
var callback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop;
_ticker2['default'].clear(_this3.tickerId);
_this3.tickerId = 'bannerElementTicker' + (Date.now() + Math.random());
var startFrame = _ticker2['default'].frame;
var startX = _this3.enterMouse.x;
var startY = _this3.enterMouse.y;
var duration = followParallax.duration || 450;
var easeFunc = _tweenFunctions2['default'][followParallax.ease || 'easeOutQuad'];
var start = typeof followParallax.minMove === 'number' ? followParallax.minMove : 0.08;
_ticker2['default'].wake(_this3.tickerId, function () {
var moment = (_ticker2['default'].frame - startFrame) * _ticker2['default'].perFrame;
var ratio = easeFunc(moment, start, 1, duration);
_this3.enterMouse.x = startX + (mouseXY.x - startX) * ratio;
_this3.enterMouse.y = startY + (mouseXY.y - startY) * ratio;
_this3.setFollowStyle(_this3.domWH);
if (moment >= duration) {
_ticker2['default'].clear(_this3.tickerId);
callback();
}
});
};
this.getFollowMouseMove = function () {
var onMouseMove = void 0;
if (_this3.followParallax) {
if (_this3.followParallax.delay) {
onMouseMove = !_this3.delayTimeout ? null : _this3.state.onMouseMove;
_this3.delayTimeout = _this3.delayTimeout || _ticker2['default'].timeout(function () {
_this3.setState({
onMouseMove: _this3.onMouseMove
});
}, _this3.followParallax.delay);
} else {
onMouseMove = _this3.onMouseMove;
}
}
return onMouseMove;
};
this.getFollowStyle = function (data, domWH) {
var style = {};
(0, _utils.dataToArray)(data.type).forEach(function (type) {
var mouseData = _this3.enterMouse.x;
var domData = domWH.w;
var value = data.value;
if ((type.indexOf('y') >= 0 || type.indexOf('Y') >= 0) && type !== 'opacity') {
mouseData = _this3.enterMouse.y;
domData = domWH.h;
}
var d = (mouseData - domData / 2) / (domData / 2) * value;
var _type = (0, _styleUtils.getGsapType)(type);
var cssName = (0, _styleUtils.isConvert)(_type);
if (cssName === 'transform') {
var transform = (0, _styleUtils.checkStyleName)('transform');
style[transform] = style[transform] || {};
style[transform][_type] = (0, _styleUtils.stylesToCss)(_type, d).trim();
} else if (cssName === 'filter') {
var filter = (0, _styleUtils.checkStyleName)('filter');
style[filter] = style[filter] || {};
style[filter][_type] = (0, _styleUtils.stylesToCss)(_type, d).trim();
} else {
style[cssName] = (0, _styleUtils.stylesToCss)(_type, d).trim();
}
});
return style;
};
this.setFollowStyle = function (domWH) {
_this3.doms.forEach(function (item, i) {
if (!item) {
return;
}
var data = _this3.followParallax.data[i];
var style = _this3.getFollowStyle(data, domWH);
Object.keys(style).forEach(function (key) {
if (typeof style[key] === 'object') {
var styleStr = '';
Object.keys(style[key]).forEach(function (_key) {
styleStr += (' ' + _key + '(' + style[key][_key] + ')').trim();
});
item.style[key] = styleStr;
return;
}
item.style[key] = key.indexOf('backgroundPosition') >= 0 ? 'calc(' + (data.bgPosition || '0%') + ' + ' + style[key] + ' )' : style[key];
});
});
};
this.getChildren = function () {
return (0, _utils.toArrayChildren)(_this3.props.children).map(function (item) {
if (item.type === _BgElement2['default']) {
return _react2['default'].cloneElement(item, { show: _this3.state.show });
}
return item;
});
};
this.reFollowParallax = function () {
_this3.setTicker(_this3.followParallax, {
x: _this3.domRect.width / 2 - _this3.offsetLeft,
y: _this3.domRect.height / 2 - _this3.offsetTop
}, function () {
_this3.followParallax = null;
});
};
this.animEnd = function () {
var type = _this3.state.show ? 'enter' : 'leave';
_this3.props.callBack(type);
_this3.setState({ show: _this3.props.show, mouseMoveType: null });
};
this.animChildren = function (props, style, bgElem) {
var _props = _this3.props,
elemOffset = _props.elemOffset,
leaveChildHide = _props.leaveChildHide,
ratio = _props.ratio,
animType = _props.animType,
direction = _props.direction,
mouseMoveType = _props.mouseMoveType,
ease = _props.ease,
duration = _props.duration,
delay = _props.delay,
show = _props.show,
sync = _props.sync,
component = _props.component;
if (_this3.tickerId) {
_ticker2['default'].clear(_this3.tickerId);
}
if (_this3.delayTimeout) {
_ticker2['default'].clear(_this3.delayTimeout);
_this3.delayTimeout = null;
}
style.display = 'block';
props.component = component;
_this3.show = _this3.state.show;
style.zIndex = _this3.state.show ? 1 : 0;
props.children = show && !sync ? bgElem : _this3.getChildren();
var childrenToRender = _react2['default'].createElement(_rcTweenOne2['default'], props);
var type = _this3.state.show ? 'enter' : 'leave';
var $ratio = mouseMoveType === 'end' && ratio <= 0.3 ? 1 - ratio : ratio;
var tag = animType(childrenToRender, type, direction, {
ease: ease,
duration: duration,
delay: delay,
onComplete: _this3.animEnd
}, elemOffset, leaveChildHide, $ratio, _this3.state.mouseMoveType === 'update');
var tagProps = (0, _objectWithoutProperties3['default'])(tag.props, []);
if (tagProps.animation) {
tagProps.moment = (tagProps.animation.duration + tagProps.animation.delay) * $ratio || 0;
tagProps.paused = _this3.state.mouseMoveType === 'update' || $ratio === 1;
}
return _react2['default'].cloneElement(tag, tagProps);
};
};
Element.propTypes = {
children: _propTypes2['default'].any,
style: _propTypes2['default'].object,
prefixCls: _propTypes2['default'].string,
component: _propTypes2['default'].any,
elemOffset: _propTypes2['default'].object,
type: _propTypes2['default'].string,
animType: _propTypes2['default'].func,
ease: _propTypes2['default'].string,
duration: _propTypes2['default'].number,
delay: _propTypes2['default'].number,
direction: _propTypes2['default'].string,
callBack: _propTypes2['default'].func,
followParallax: _propTypes2['default'].any,
show: _propTypes2['default'].bool,
leaveChildHide: _propTypes2['default'].bool,
sync: _propTypes2['default'].bool,
ratio: _propTypes2['default'].number,
mouseMoveType: _propTypes2['default'].string
};
Element.defaultProps = {
component: 'div',
callBack: noop,
delay: 0
};
Element.BgElement = _BgElement2['default'];
Element.isBannerAnimElement = true;
exports['default'] = Element;
module.exports = exports['default'];