@mirrormedia/lilith-draft-renderer
Version:
## Introduction
272 lines (257 loc) • 8 kB
JavaScript
;
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
}));
}