@kids-reporter/draft-renderer 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/lib/block-render-map.js +183 -0
  2. package/lib/block-renderer-fn.js +15 -74
  3. package/lib/block-renderers/embedded-code-block.js +16 -20
  4. package/lib/block-renderers/image-block.js +90 -46
  5. package/lib/block-renderers/index.js +2 -31
  6. package/lib/block-renderers/info-box-block.js +2 -115
  7. package/lib/block-renderers/multimedia.js +127 -0
  8. package/lib/block-renderers/slideshow-block.js +574 -199
  9. package/lib/draft-renderer.js +10 -194
  10. package/lib/entity-decorators/annotation-decorator.js +58 -100
  11. package/lib/entity-decorators/index.js +17 -6
  12. package/lib/entity-decorators/link-decorator.js +4 -7
  13. package/lib/index.js +39 -14
  14. package/lib/theme/index.js +0 -11
  15. package/package.json +10 -6
  16. package/lib/assets/annotation-arrow.png +0 -0
  17. package/lib/assets/audio-pause.png +0 -0
  18. package/lib/assets/audio-play.png +0 -0
  19. package/lib/assets/citation-download.png +0 -0
  20. package/lib/assets/default-og-img.png +0 -0
  21. package/lib/assets/slideshow-arrow-down-dark.png +0 -0
  22. package/lib/assets/slideshow-arrow-down.png +0 -0
  23. package/lib/assets/slideshow-arrow-up.png +0 -0
  24. package/lib/assets/slideshow-close-cross.png +0 -0
  25. package/lib/block-renderers/audio-block.js +0 -162
  26. package/lib/block-renderers/background-image-block.js +0 -257
  27. package/lib/block-renderers/background-video-block.js +0 -272
  28. package/lib/block-renderers/color-box-block.js +0 -94
  29. package/lib/block-renderers/divider-block.js +0 -27
  30. package/lib/block-renderers/media-block.js +0 -65
  31. package/lib/block-renderers/related-post-block.js +0 -73
  32. package/lib/block-renderers/side-index-block.js +0 -49
  33. package/lib/block-renderers/table-block.js +0 -455
  34. package/lib/block-renderers/video-block.js +0 -37
  35. package/lib/components/slideshow-lightbox.js +0 -134
  36. package/lib/components/slideshow-sidebar.js +0 -148
  37. package/lib/const.js +0 -10
  38. package/lib/entity-decorator.js +0 -18
  39. package/lib/public/07d1287fd390346af0c15b930148a5e4.png +0 -0
  40. package/lib/public/5b3cb1a908786c8750f1041860699cc1.png +0 -0
  41. package/lib/public/679d63b1846e81ada28c2f76edbd2931.png +0 -0
  42. package/lib/public/722f90c535fa64c27555ec6ee5f22393.png +0 -0
  43. package/lib/public/903cf84ef5c5ad76634c30bdc0ff8c49.png +0 -0
  44. package/lib/public/dc249b3412c5af890a004508287a3c3d.png +0 -0
  45. package/lib/public/dd45f0788d9c70cabe72430bf08e7413.png +0 -0
  46. package/lib/public/f96d4b486ba2061c460962ae694f4670.png +0 -0
  47. package/lib/shared-style/content-type.js +0 -163
  48. package/lib/shared-style/index.js +0 -108
  49. package/lib/types/index.js +0 -32
  50. package/lib/utils/common.js +0 -44
  51. package/lib/utils/post.js +0 -147
@@ -1,162 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.AudioBlock = AudioBlock;
7
-
8
- var _react = _interopRequireWildcard(require("react"));
9
-
10
- var _styledComponents = _interopRequireWildcard(require("styled-components"));
11
-
12
- 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); }
13
-
14
- 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; }
15
-
16
- const audioPlay = "https://unpkg.com/@kids-reporter/draft-renderer@0.1.0/lib/public/dc249b3412c5af890a004508287a3c3d.png";
17
- const audioPause = "https://unpkg.com/@kids-reporter/draft-renderer@0.1.0/lib/public/5b3cb1a908786c8750f1041860699cc1.png";
18
- const buttonShareStyle = (0, _styledComponents.css)`
19
- width: 64px;
20
- height: 64px;
21
- border-radius: 50%;
22
- background-repeat: no-repeat;
23
- background-position: center center;
24
- background-size: 22px;
25
-
26
- &:hover {
27
- opacity: 0.8;
28
- }
29
- `;
30
- const audioTimeShareStyle = (0, _styledComponents.css)`
31
- color: rgba(0, 9, 40, 0.5);
32
- font-weight: 400;
33
- font-size: 11px;
34
- line-height: 1em;
35
- position: absolute;
36
- bottom: 0px;
37
-
38
- ${({
39
- theme
40
- }) => theme.breakpoint.md} {
41
- font-size: 13px;
42
- }
43
- `;
44
- const AudioWrapper = _styledComponents.default.div`
45
- position: relative;
46
- outline: 1px solid rgba(0, 9, 40, 0.1);
47
- padding: 16px 0px 16px 16px;
48
- display: flex;
49
- align-items: center;
50
- justify-content: space-between;
51
- max-width: 480px;
52
- ${({
53
- theme
54
- }) => theme.margin.default}
55
-
56
- ${({
57
- theme
58
- }) => theme.breakpoint.md} {
59
- padding: 24px 0px 28px 24px;
60
- }
61
-
62
- audio {
63
- max-height: 40px;
64
- width: 100%;
65
- position: relative;
66
- pointer-events: none;
67
- }
68
-
69
- audio::-webkit-media-controls-panel {
70
- background: #ffffff;
71
- }
72
-
73
- //remove default audio style: volume, mute, play
74
- audio::-webkit-media-controls-volume-slider,
75
- audio::-webkit-media-controls-mute-button,
76
- audio::-webkit-media-controls-play-button {
77
- display: none;
78
- }
79
-
80
- //時間進度條
81
- audio::-webkit-media-controls-timeline {
82
- height: 4px;
83
- opacity: 0.3;
84
- padding: 0;
85
- margin-bottom: 10px;
86
- }
87
-
88
- //目前播放時間
89
- audio::-webkit-media-controls-current-time-display {
90
- ${audioTimeShareStyle}
91
- left: 5px;
92
- }
93
-
94
- //總時長
95
- audio::-webkit-media-controls-time-remaining-display {
96
- ${audioTimeShareStyle}
97
- left: 36px;
98
- }
99
- `;
100
- const AudioInfo = _styledComponents.default.div`
101
- width: calc(100% - 70px);
102
- `;
103
- const AudioTitle = _styledComponents.default.div`
104
- font-family: 'Noto Sans TC';
105
- font-style: normal;
106
- font-weight: 400;
107
- font-size: 14px;
108
- line-height: 1.4em;
109
- color: rgba(0, 9, 40, 0.87);
110
- padding: 0 40px 0px 10px;
111
-
112
- ${({
113
- theme
114
- }) => theme.breakpoint.md} {
115
- font-size: 16px;
116
- }
117
- `;
118
- const PlayButton = _styledComponents.default.button`
119
- ${buttonShareStyle}
120
- background-color: #f6f6fb;
121
- background-image: url(${audioPlay});
122
-
123
- &:hover {
124
- opacity: 0.66;
125
- }
126
- `;
127
- const PauseButton = _styledComponents.default.button`
128
- ${buttonShareStyle}
129
- background-color: rgba(0, 9, 40, 0.87);
130
- background-image: url(${audioPause});
131
- `;
132
-
133
- function AudioBlock(entity) {
134
- const {
135
- audio
136
- } = entity.getData();
137
- const audioRef = (0, _react.useRef)(null);
138
- const [isPlaying, setIsPlaying] = (0, _react.useState)(false);
139
-
140
- const handlePlay = () => {
141
- audioRef === null || audioRef === void 0 ? void 0 : audioRef.current.play();
142
- setIsPlaying(true);
143
- };
144
-
145
- const handlePause = () => {
146
- audioRef === null || audioRef === void 0 ? void 0 : audioRef.current.pause();
147
- setIsPlaying(false);
148
- };
149
-
150
- return /*#__PURE__*/_react.default.createElement(AudioWrapper, null, isPlaying ? /*#__PURE__*/_react.default.createElement(PauseButton, {
151
- onClick: handlePause
152
- }) : /*#__PURE__*/_react.default.createElement(PlayButton, {
153
- onClick: handlePlay
154
- }), /*#__PURE__*/_react.default.createElement(AudioInfo, null, /*#__PURE__*/_react.default.createElement(AudioTitle, null, audio === null || audio === void 0 ? void 0 : audio.name), /*#__PURE__*/_react.default.createElement("audio", {
155
- controls: true,
156
- id: "player",
157
- ref: audioRef,
158
- src: audio === null || audio === void 0 ? void 0 : audio.url,
159
- controlsList: "nodownload noremoteplayback noplaybackrate nofullscreen",
160
- preload: "auto"
161
- })));
162
- }
@@ -1,257 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.BGImageBlock = BGImageBlock;
7
-
8
- var _react = _interopRequireWildcard(require("react"));
9
-
10
- var _styledComponents = _interopRequireDefault(require("styled-components"));
11
-
12
- var _reactImage = _interopRequireDefault(require("@readr-media/react-image"));
13
-
14
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
-
16
- 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); }
17
-
18
- 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; }
19
-
20
- const BackgroundContainer = _styledComponents.default.section`
21
- clear: both;
22
- position: relative;
23
- margin: 32px calc(50% - 50vw) 0 !important;
24
- width: 100vw;
25
- min-height: 100vh;
26
- `;
27
- const BackgroundImage = _styledComponents.default.div`
28
- position: absolute;
29
- z-index: 1;
30
- top: 0;
31
- bottom: unset;
32
- left: 0;
33
- width: 100%;
34
- height: 100vh;
35
- `;
36
- const BackgroundContentRow = _styledComponents.default.div``;
37
- const BackgroundContent = _styledComponents.default.div`
38
- position: relative;
39
- z-index: 1;
40
- &.static {
41
- height: 100vh;
42
- ${BackgroundContentRow} {
43
- position: absolute;
44
- bottom: 20px;
45
- left: 20px;
46
- right: 20px;
47
- text-shadow: 0px 0px 1px #000000;
48
- ${({
49
- theme
50
- }) => theme.breakpoint.sm} {
51
- bottom: 40px;
52
- }
53
- }
54
- }
55
- &.parallax {
56
- ${BackgroundContentRow} {
57
- > div {
58
- background: rgba(169, 118, 118, 0.1);
59
- border-radius: 8px;
60
- padding: 20px;
61
- ${({
62
- theme
63
- }) => theme.breakpoint.xl} {
64
- width: 480px;
65
- }
66
-
67
- > * + * {
68
- margin: 27px 0 0;
69
- }
70
- h2 {
71
- font-size: 1.44em;
72
- ${({
73
- theme
74
- }) => theme.breakpoint.md} {
75
- font-size: 1.77em;
76
- }
77
- }
78
- h3 {
79
- font-size: 1.33em;
80
- ${({
81
- theme
82
- }) => theme.breakpoint.md} {
83
- font-size: 1.55em;
84
- }
85
- }
86
- h4 {
87
- font-size: 1.11em;
88
- ${({
89
- theme
90
- }) => theme.breakpoint.md} {
91
- font-size: 1.33em;
92
- }
93
- }
94
- ul {
95
- list-style-type: disc;
96
- list-style-position: inside;
97
- }
98
- ol {
99
- list-style-type: decimal;
100
- list-style-position: inside;
101
- }
102
- }
103
- &.left {
104
- padding: 0 20px 97px;
105
- ${({
106
- theme
107
- }) => theme.breakpoint.md} {
108
- padding: 0 40px 335px;
109
- }
110
- ${({
111
- theme
112
- }) => theme.breakpoint.xl} {
113
- padding: 0 80px 169px;
114
- padding-right: calc(100% - 480px - 80px);
115
- }
116
- ${({
117
- theme
118
- }) => theme.breakpoint.xxl} {
119
- padding-bottom: 296px;
120
- }
121
- }
122
- &.right {
123
- padding: 0 20px 97px;
124
- ${({
125
- theme
126
- }) => theme.breakpoint.md} {
127
- padding: 0 40px 335px;
128
- }
129
- ${({
130
- theme
131
- }) => theme.breakpoint.xl} {
132
- padding: 0 80px 169px;
133
- padding-left: calc(100% - 480px - 80px);
134
- }
135
- ${({
136
- theme
137
- }) => theme.breakpoint.xxl} {
138
- padding-bottom: 296px;
139
- }
140
- }
141
- &.bottom {
142
- padding: 0 20px 20px;
143
- ${({
144
- theme
145
- }) => theme.breakpoint.md} {
146
- padding: 0 40px 40px;
147
- }
148
- ${({
149
- theme
150
- }) => theme.breakpoint.xl} {
151
- padding: 0 calc(50% - 240px) 40px;
152
- }
153
- ${({
154
- theme
155
- }) => theme.breakpoint.xxl} {
156
- padding-bottom: 80px;
157
- }
158
- }
159
- }
160
- }
161
- `;
162
- const BackgroundEmptyRow = _styledComponents.default.div`
163
- height: 100vh;
164
- `;
165
-
166
- function BGImageBlock(props) {
167
- const {
168
- block,
169
- contentState
170
- } = props;
171
- const entityKey = block.getEntityAt(0);
172
- const entity = contentState.getEntity(entityKey);
173
- const {
174
- textBlockAlign,
175
- image,
176
- body
177
- } = entity.getData();
178
- const {
179
- resized,
180
- name
181
- } = image; // 滾動視差
182
-
183
- const isParallax = textBlockAlign !== 'fixed';
184
- const [bgImageCss, setBgImageCss] = (0, _react.useState)({});
185
- const bgRef = (0, _react.useRef)(null);
186
- const topRef = (0, _react.useRef)(null);
187
- const bottomRef = (0, _react.useRef)(null);
188
- (0, _react.useEffect)(() => {
189
- if (bgRef.current && topRef.current && bottomRef.current) {
190
- const intersectionObserver = new IntersectionObserver(entries => {
191
- entries.forEach(({
192
- boundingClientRect
193
- }) => {
194
- if (!boundingClientRect.width || !bgRef.current) {
195
- return;
196
- }
197
-
198
- const bounding = bgRef.current.getBoundingClientRect();
199
-
200
- if (bounding.height) {
201
- if (bounding.y > 0) {
202
- setBgImageCss({
203
- position: 'absolute',
204
- top: 0,
205
- bottom: 'unset'
206
- });
207
- } else if (bounding.y + bounding.height > window.innerHeight) {
208
- setBgImageCss({
209
- position: 'fixed',
210
- top: 0,
211
- bottom: 'unset'
212
- });
213
- } else {
214
- setBgImageCss({
215
- position: 'absolute',
216
- top: 'unset',
217
- bottom: 0
218
- });
219
- }
220
- }
221
- });
222
- });
223
- intersectionObserver.observe(topRef.current);
224
- intersectionObserver.observe(bottomRef.current);
225
- return () => {
226
- intersectionObserver.disconnect();
227
- };
228
- }
229
- }, []);
230
- return /*#__PURE__*/_react.default.createElement(BackgroundContainer, {
231
- ref: bgRef,
232
- className: "bg"
233
- }, /*#__PURE__*/_react.default.createElement("div", {
234
- ref: topRef
235
- }), /*#__PURE__*/_react.default.createElement(BackgroundImage, {
236
- style: bgImageCss
237
- }, /*#__PURE__*/_react.default.createElement(_reactImage.default, {
238
- images: resized,
239
- alt: name,
240
- rwd: {
241
- mobile: '100vw',
242
- tablet: '640px',
243
- default: '100%'
244
- },
245
- priority: true
246
- })), /*#__PURE__*/_react.default.createElement(BackgroundContent, {
247
- className: isParallax ? 'parallax' : 'static'
248
- }, isParallax && /*#__PURE__*/_react.default.createElement(BackgroundEmptyRow, null), /*#__PURE__*/_react.default.createElement(BackgroundContentRow, {
249
- className: textBlockAlign
250
- }, /*#__PURE__*/_react.default.createElement("div", {
251
- dangerouslySetInnerHTML: {
252
- __html: body
253
- }
254
- }))), /*#__PURE__*/_react.default.createElement("div", {
255
- ref: bottomRef
256
- }));
257
- }
@@ -1,272 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.BGVideoBlock = BGVideoBlock;
7
-
8
- var _react = _interopRequireWildcard(require("react"));
9
-
10
- var _styledComponents = _interopRequireDefault(require("styled-components"));
11
-
12
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
-
14
- 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); }
15
-
16
- 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; }
17
-
18
- const BackgroundContainer = _styledComponents.default.section`
19
- clear: both;
20
- position: relative;
21
- margin: 32px calc(50% - 50vw) 0 !important;
22
- width: 100vw;
23
- min-height: 100vh;
24
- `;
25
- const BackgroundVideo = _styledComponents.default.div`
26
- position: absolute;
27
- z-index: 1;
28
- top: 0;
29
- bottom: unset;
30
- left: 0;
31
- width: 100%;
32
- height: 100vh;
33
- `;
34
- const BackgroundContentRow = _styledComponents.default.div``;
35
- const BackgroundContent = _styledComponents.default.div`
36
- position: relative;
37
- z-index: 1;
38
- &.static {
39
- height: 100vh;
40
- ${BackgroundContentRow} {
41
- position: absolute;
42
- bottom: 20px;
43
- left: 20px;
44
- right: 20px;
45
- text-shadow: 0px 0px 1px #000000;
46
- ${({
47
- theme
48
- }) => theme.breakpoint.sm} {
49
- bottom: 40px;
50
- }
51
- }
52
- }
53
- &.parallax {
54
- ${BackgroundContentRow} {
55
- > div {
56
- background: rgba(169, 118, 118, 0.1);
57
- border-radius: 8px;
58
- padding: 20px;
59
- ${({
60
- theme
61
- }) => theme.breakpoint.xl} {
62
- width: 480px;
63
- }
64
-
65
- > * + * {
66
- margin: 27px 0 0;
67
- }
68
- h2 {
69
- font-size: 1.44em;
70
- ${({
71
- theme
72
- }) => theme.breakpoint.md} {
73
- font-size: 1.77em;
74
- }
75
- }
76
- h3 {
77
- font-size: 1.33em;
78
- ${({
79
- theme
80
- }) => theme.breakpoint.md} {
81
- font-size: 1.55em;
82
- }
83
- }
84
- h4 {
85
- font-size: 1.11em;
86
- ${({
87
- theme
88
- }) => theme.breakpoint.md} {
89
- font-size: 1.33em;
90
- }
91
- }
92
- ul {
93
- list-style-type: disc;
94
- list-style-position: inside;
95
- }
96
- ol {
97
- list-style-type: decimal;
98
- list-style-position: inside;
99
- }
100
- }
101
- &.left {
102
- padding: 0 20px 97px;
103
- ${({
104
- theme
105
- }) => theme.breakpoint.md} {
106
- padding: 0 40px 335px;
107
- }
108
- ${({
109
- theme
110
- }) => theme.breakpoint.xl} {
111
- padding: 0 80px 169px;
112
- padding-right: calc(100% - 480px - 80px);
113
- }
114
- ${({
115
- theme
116
- }) => theme.breakpoint.xxl} {
117
- padding-bottom: 296px;
118
- }
119
- }
120
- &.right {
121
- padding: 0 20px 97px;
122
- ${({
123
- theme
124
- }) => theme.breakpoint.md} {
125
- padding: 0 40px 335px;
126
- }
127
- ${({
128
- theme
129
- }) => theme.breakpoint.xl} {
130
- padding: 0 80px 169px;
131
- padding-left: calc(100% - 480px - 80px);
132
- }
133
- ${({
134
- theme
135
- }) => theme.breakpoint.xxl} {
136
- padding-bottom: 296px;
137
- }
138
- }
139
- &.bottom {
140
- padding: 0 20px 20px;
141
- ${({
142
- theme
143
- }) => theme.breakpoint.md} {
144
- padding: 0 40px 40px;
145
- }
146
- ${({
147
- theme
148
- }) => theme.breakpoint.xl} {
149
- padding: 0 calc(50% - 240px) 40px;
150
- }
151
- ${({
152
- theme
153
- }) => theme.breakpoint.xxl} {
154
- padding-bottom: 80px;
155
- }
156
- }
157
- }
158
- }
159
- `;
160
- const BackgroundEmptyRow = _styledComponents.default.div`
161
- height: 100vh;
162
- `;
163
-
164
- function BGVideoBlock(props) {
165
- const {
166
- block,
167
- contentState
168
- } = props;
169
- const entityKey = block.getEntityAt(0);
170
- const entity = contentState.getEntity(entityKey);
171
- const {
172
- textBlockAlign,
173
- video,
174
- body
175
- } = entity.getData(); // 滾動視差
176
-
177
- const isParallax = textBlockAlign !== 'fixed';
178
- const [bgVideoCss, setBgVideoCss] = (0, _react.useState)({});
179
- const bgRef = (0, _react.useRef)(null);
180
- const videoRef = (0, _react.useRef)(null);
181
- const topRef = (0, _react.useRef)(null);
182
- const bottomRef = (0, _react.useRef)(null);
183
- (0, _react.useEffect)(() => {
184
- if (bgRef.current && topRef.current && bottomRef.current) {
185
- const intersectionObserver = new IntersectionObserver(entries => {
186
- entries.forEach(({
187
- boundingClientRect
188
- }) => {
189
- if (!boundingClientRect.width || !videoRef.current || !bgRef.current) {
190
- return;
191
- }
192
-
193
- const bounding = bgRef.current.getBoundingClientRect();
194
-
195
- if (isParallax) {
196
- if (bounding.y > 0) {
197
- // before block top touch viewport top, set the video to the top of block
198
- setBgVideoCss({
199
- position: 'absolute',
200
- top: 0,
201
- bottom: 'unset'
202
- });
203
- videoRef.current.pause();
204
- } else if (bounding.y + bounding.height >= window.innerHeight) {
205
- // after block top touch viewport top, fix the video to viewport
206
- setBgVideoCss({
207
- position: 'fixed',
208
- top: 0,
209
- bottom: 'unset'
210
- });
211
- videoRef.current.play();
212
- } else {
213
- // after block bottom leave viewport bottom, set the video to the bottom of block
214
- setBgVideoCss({
215
- position: 'absolute',
216
- top: 'unset',
217
- bottom: 0
218
- });
219
- videoRef.current.pause();
220
- }
221
- }
222
-
223
- if (!isParallax) {
224
- if (bounding.y > window.innerHeight * 0.3 || bounding.y < -window.innerHeight * 0.3) {
225
- videoRef.current.pause();
226
- } else {
227
- videoRef.current.play();
228
- }
229
- }
230
- });
231
- }, {
232
- threshold: [0, 0.4, 0.7, 1.0]
233
- });
234
-
235
- if (!isParallax) {
236
- intersectionObserver.observe(bgRef.current);
237
- } else {
238
- intersectionObserver.observe(topRef.current);
239
- intersectionObserver.observe(bottomRef.current);
240
- }
241
-
242
- return () => {
243
- intersectionObserver.disconnect();
244
- };
245
- }
246
- }, [isParallax]);
247
- return /*#__PURE__*/_react.default.createElement(BackgroundContainer, {
248
- ref: bgRef,
249
- className: "bg"
250
- }, /*#__PURE__*/_react.default.createElement("div", {
251
- ref: topRef
252
- }), /*#__PURE__*/_react.default.createElement(BackgroundVideo, {
253
- style: bgVideoCss
254
- }, /*#__PURE__*/_react.default.createElement("video", {
255
- ref: videoRef,
256
- src: video === null || video === void 0 ? void 0 : video.url,
257
- muted: true,
258
- preload: "auto",
259
- loop: true,
260
- playsInline: true
261
- })), /*#__PURE__*/_react.default.createElement(BackgroundContent, {
262
- className: isParallax ? 'parallax' : 'static'
263
- }, isParallax && /*#__PURE__*/_react.default.createElement(BackgroundEmptyRow, null), /*#__PURE__*/_react.default.createElement(BackgroundContentRow, {
264
- className: textBlockAlign
265
- }, /*#__PURE__*/_react.default.createElement("div", {
266
- dangerouslySetInnerHTML: {
267
- __html: body
268
- }
269
- }))), /*#__PURE__*/_react.default.createElement("div", {
270
- ref: bottomRef
271
- }));
272
- }