UNPKG

@mirrormedia/lilith-draft-renderer

Version:
272 lines (257 loc) 8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BGVideoBlock = BGVideoBlock; var _react = _interopRequireWildcard(require("react")); var _styledComponents = _interopRequireDefault(require("styled-components")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const BackgroundContainer = _styledComponents.default.section` clear: both; position: relative; margin: 32px calc(50% - 50vw) 0 !important; width: 100vw; min-height: 100vh; `; const BackgroundVideo = _styledComponents.default.div` position: absolute; z-index: 1; top: 0; bottom: unset; left: 0; width: 100%; height: 100vh; `; const BackgroundContentRow = _styledComponents.default.div``; const BackgroundContent = _styledComponents.default.div` position: relative; z-index: 1; &.static { height: 100vh; ${BackgroundContentRow} { position: absolute; bottom: 20px; left: 20px; right: 20px; text-shadow: 0px 0px 1px #000000; ${({ theme }) => theme.breakpoint.sm} { bottom: 40px; } } } &.parallax { ${BackgroundContentRow} { > div { background: rgba(169, 118, 118, 0.1); border-radius: 8px; padding: 20px; ${({ theme }) => theme.breakpoint.xl} { width: 480px; } > * + * { margin: 27px 0 0; } h2 { font-size: 1.44em; ${({ theme }) => theme.breakpoint.md} { font-size: 1.77em; } } h3 { font-size: 1.33em; ${({ theme }) => theme.breakpoint.md} { font-size: 1.55em; } } h4 { font-size: 1.11em; ${({ theme }) => theme.breakpoint.md} { font-size: 1.33em; } } ul { list-style-type: disc; list-style-position: inside; } ol { list-style-type: decimal; list-style-position: inside; } } &.left { padding: 0 20px 97px; ${({ theme }) => theme.breakpoint.md} { padding: 0 40px 335px; } ${({ theme }) => theme.breakpoint.xl} { padding: 0 80px 169px; padding-right: calc(100% - 480px - 80px); } ${({ theme }) => theme.breakpoint.xxl} { padding-bottom: 296px; } } &.right { padding: 0 20px 97px; ${({ theme }) => theme.breakpoint.md} { padding: 0 40px 335px; } ${({ theme }) => theme.breakpoint.xl} { padding: 0 80px 169px; padding-left: calc(100% - 480px - 80px); } ${({ theme }) => theme.breakpoint.xxl} { padding-bottom: 296px; } } &.bottom { padding: 0 20px 20px; ${({ theme }) => theme.breakpoint.md} { padding: 0 40px 40px; } ${({ theme }) => theme.breakpoint.xl} { padding: 0 calc(50% - 240px) 40px; } ${({ theme }) => theme.breakpoint.xxl} { padding-bottom: 80px; } } } } `; const BackgroundEmptyRow = _styledComponents.default.div` height: 100vh; `; function BGVideoBlock(props) { const { block, contentState } = props; const entityKey = block.getEntityAt(0); const entity = contentState.getEntity(entityKey); const { textBlockAlign, video, body } = entity.getData(); // 滾動視差 const isParallax = textBlockAlign !== 'fixed'; const [bgVideoCss, setBgVideoCss] = (0, _react.useState)({}); const bgRef = (0, _react.useRef)(null); const videoRef = (0, _react.useRef)(null); const topRef = (0, _react.useRef)(null); const bottomRef = (0, _react.useRef)(null); (0, _react.useEffect)(() => { if (bgRef.current && topRef.current && bottomRef.current) { const intersectionObserver = new IntersectionObserver(entries => { entries.forEach(({ boundingClientRect }) => { if (!boundingClientRect.width || !videoRef.current || !bgRef.current) { return; } const bounding = bgRef.current.getBoundingClientRect(); if (isParallax) { if (bounding.y > 0) { // before block top touch viewport top, set the video to the top of block setBgVideoCss({ position: 'absolute', top: 0, bottom: 'unset' }); videoRef.current.pause(); } else if (bounding.y + bounding.height >= window.innerHeight) { // after block top touch viewport top, fix the video to viewport setBgVideoCss({ position: 'fixed', top: 0, bottom: 'unset' }); videoRef.current.play(); } else { // after block bottom leave viewport bottom, set the video to the bottom of block setBgVideoCss({ position: 'absolute', top: 'unset', bottom: 0 }); videoRef.current.pause(); } } if (!isParallax) { if (bounding.y > window.innerHeight * 0.3 || bounding.y < -window.innerHeight * 0.3) { videoRef.current.pause(); } else { videoRef.current.play(); } } }); }, { threshold: [0, 0.4, 0.7, 1.0] }); if (!isParallax) { intersectionObserver.observe(bgRef.current); } else { intersectionObserver.observe(topRef.current); intersectionObserver.observe(bottomRef.current); } return () => { intersectionObserver.disconnect(); }; } }, [isParallax]); return /*#__PURE__*/_react.default.createElement(BackgroundContainer, { ref: bgRef, className: "bg" }, /*#__PURE__*/_react.default.createElement("div", { ref: topRef }), /*#__PURE__*/_react.default.createElement(BackgroundVideo, { style: bgVideoCss }, /*#__PURE__*/_react.default.createElement("video", { ref: videoRef, src: video === null || video === void 0 ? void 0 : video.url, muted: true, preload: "auto", loop: true, playsInline: true })), /*#__PURE__*/_react.default.createElement(BackgroundContent, { className: isParallax ? 'parallax' : 'static' }, isParallax && /*#__PURE__*/_react.default.createElement(BackgroundEmptyRow, null), /*#__PURE__*/_react.default.createElement(BackgroundContentRow, { className: textBlockAlign }, /*#__PURE__*/_react.default.createElement("div", { dangerouslySetInnerHTML: { __html: body } }))), /*#__PURE__*/_react.default.createElement("div", { ref: bottomRef })); }