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 from 'react';
|
7 | import ReactDOM from 'react-dom';
|
8 | import PropTypes from 'prop-types';
|
9 | import Tween from 'rc-tween-one/es/Tween';
|
10 | import { stylesToCss } from 'style-utils';
|
11 | import { currentScrollTop, toArrayChildren, windowHeight } from './utils';
|
12 | import animType from './anim';
|
13 |
|
14 | var BgElement = function (_React$Component) {
|
15 | _inherits(BgElement, _React$Component);
|
16 |
|
17 | function BgElement(props) {
|
18 | _classCallCheck(this, BgElement);
|
19 |
|
20 | var _this = _possibleConstructorReturn(this, (BgElement.__proto__ || Object.getPrototypeOf(BgElement)).call(this, props));
|
21 |
|
22 | _this.onScroll = function () {
|
23 | var scrollTop = currentScrollTop();
|
24 | var domRect = _this.dom.parentNode.getBoundingClientRect();
|
25 | var offsetTop = domRect.top + scrollTop;
|
26 | var height = Math.max(domRect.height, windowHeight());
|
27 | var elementShowHeight = scrollTop - offsetTop + height;
|
28 | var scale = elementShowHeight / (height + domRect.height);
|
29 | scale = scale || 0;
|
30 | scale = scale >= 1 ? 1 : scale;
|
31 | _this.tween.frame(scale * _this.scrollParallaxDuration);
|
32 | };
|
33 |
|
34 | _this.onResize = function () {
|
35 | if (!_this.props.show) {
|
36 | return;
|
37 | }
|
38 | var domRect = _this.dom.getBoundingClientRect();
|
39 | var videoDomRect = _this.video.getBoundingClientRect();
|
40 | _this.videoLoad = true;
|
41 | var scale = void 0;
|
42 | var videoRect = {
|
43 | display: 'block',
|
44 | position: 'relative',
|
45 | top: 0,
|
46 | left: 0
|
47 | };
|
48 | if (domRect.width / domRect.height > videoDomRect.width / videoDomRect.height) {
|
49 | scale = domRect.width / videoDomRect.width;
|
50 | videoRect.width = domRect.width;
|
51 | videoRect.height = videoDomRect.height * scale;
|
52 | videoRect.top = -(videoRect.height - domRect.height) / 2;
|
53 | } else {
|
54 | scale = domRect.height / videoDomRect.height;
|
55 | videoRect.height = domRect.height;
|
56 | videoRect.width = videoDomRect.width * scale;
|
57 | videoRect.left = -(videoRect.width - domRect.width) / 2;
|
58 | }
|
59 |
|
60 | Object.keys(videoRect).forEach(function (key) {
|
61 | _this.video.style[key] = stylesToCss(key, videoRect[key]);
|
62 | });
|
63 | };
|
64 |
|
65 | _this.videoLoadedData = function () {
|
66 | _this.onResize();
|
67 | if (window.addEventListener) {
|
68 | window.addEventListener('resize', _this.onResize);
|
69 | } else {
|
70 | window.attachEvent('onresize', _this.onResize);
|
71 | }
|
72 | };
|
73 |
|
74 | _this.isVideo = toArrayChildren(_this.props.children).some(function (item) {
|
75 | return item.type === 'video';
|
76 | });
|
77 | if (_this.isVideo) {
|
78 |
|
79 | delete animType.grid;
|
80 | delete animType.gridBar;
|
81 | }
|
82 | if (_this.props.scrollParallax) {
|
83 | _this.scrollParallaxDuration = _this.props.scrollParallax.duration || 450;
|
84 | }
|
85 | _this.video = null;
|
86 | _this.videoLoad = false;
|
87 | return _this;
|
88 | }
|
89 |
|
90 | _createClass(BgElement, [{
|
91 | key: 'componentDidMount',
|
92 | value: function componentDidMount() {
|
93 | this.dom = ReactDOM.findDOMNode(this);
|
94 | if (!this.videoLoad) {
|
95 | if (this.video && this.props.videoResize) {
|
96 | this.video.onloadeddata = this.videoLoadedData;
|
97 | }
|
98 | }
|
99 | if (this.props.scrollParallax) {
|
100 | this.tween = new Tween(this.dom, [_extends({
|
101 | ease: 'linear' }, this.props.scrollParallax)], { attr: 'style' });
|
102 | this.tween.frame(0);
|
103 | this.onScroll();
|
104 | if (window.addEventListener) {
|
105 | window.addEventListener('scroll', this.onScroll);
|
106 | } else {
|
107 | window.attachEvent('onscroll', this.onScroll);
|
108 | }
|
109 | }
|
110 | }
|
111 | }, {
|
112 | key: 'componentWillReceiveProps',
|
113 | value: function componentWillReceiveProps(nextProps) {
|
114 | var _this2 = this;
|
115 |
|
116 | if (nextProps.show) {
|
117 |
|
118 | setTimeout(function () {
|
119 | if (_this2.video && _this2.props.videoResize && _this2.videoLoad) {
|
120 | _this2.onResize();
|
121 | }
|
122 | if (_this2.props.scrollParallax) {
|
123 | _this2.onScroll();
|
124 | }
|
125 | });
|
126 | }
|
127 | }
|
128 | }, {
|
129 | key: 'componentWillUnmount',
|
130 | value: function componentWillUnmount() {
|
131 | if (window.addEventListener) {
|
132 | window.removeEventListener('resize', this.onResize);
|
133 | window.removeEventListener('scroll', this.onScroll);
|
134 | } else {
|
135 | window.detachEvent('onresize', this.onResize);
|
136 | window.detachEvent('onscroll', this.onScroll);
|
137 | }
|
138 | }
|
139 | }, {
|
140 | key: 'render',
|
141 | value: function render() {
|
142 | var _this3 = this;
|
143 |
|
144 | var props = _extends({}, this.props, this.props.componentProps);
|
145 | ['videoResize', 'scrollParallax', 'scrollParallaxDuration', 'show', 'component', 'componentProps'].forEach(function (key) {
|
146 | return delete props[key];
|
147 | });
|
148 | if (this.isVideo && this.props.videoResize) {
|
149 | var children = toArrayChildren(props.children).map(function (item, i) {
|
150 | return React.cloneElement(item, _extends({}, item.props, { key: item.key || 'bg-video-' + i, ref: function ref(c) {
|
151 | _this3.video = c;
|
152 | if (typeof item.ref === 'function') {
|
153 | item.ref(c);
|
154 | }
|
155 | }
|
156 | }));
|
157 | });
|
158 | props.children = children.length === 1 ? children[0] : children;
|
159 | }
|
160 | return React.createElement(this.props.component, props);
|
161 | }
|
162 | }]);
|
163 |
|
164 | return BgElement;
|
165 | }(React.Component);
|
166 |
|
167 | export default BgElement;
|
168 |
|
169 |
|
170 | BgElement.propTypes = {
|
171 | className: PropTypes.string,
|
172 | style: PropTypes.object,
|
173 | children: PropTypes.any,
|
174 | component: PropTypes.any,
|
175 | videoResize: PropTypes.bool,
|
176 | scrollParallax: PropTypes.object,
|
177 | show: PropTypes.bool,
|
178 | componentProps: PropTypes.object
|
179 | };
|
180 |
|
181 | BgElement.defaultProps = {
|
182 | component: 'div',
|
183 | videoResize: true,
|
184 | componentProps: {}
|
185 | };
|
186 |
|
187 | BgElement.isBannerAnimBgElement = true; |
\ | No newline at end of file |