UNPKG

@trap_stevo/legendarybuilderproreact-ui

Version:

The legendary UI & utility API that makes your application a legendary application. ~ Created by Steven Compton

884 lines 41.3 kB
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import _regeneratorRuntime from "@babel/runtime/regenerator"; import * as React from "react"; import { useState, useEffect, useRef, useCallback } from "react"; import { useIdleDetection } from "../HUDManagers/HUDUniversalHUDEventEffectsManager.js"; import { ConvertToVideoTime } from "../HUDManagers/HUDUniversalHUDUtilityManager.js"; function HUDVideoTimelineBar(_ref) { var _ref$videoTimelineBar = _ref.videoTimelineBarTimestampHoverContentConfigurationSettings, videoTimelineBarTimestampHoverContentConfigurationSettings = _ref$videoTimelineBar === void 0 ? {} : _ref$videoTimelineBar, _ref$hotspotThumbnail = _ref.hotspotThumbnailDetailsContainerConfigurationSettings, hotspotThumbnailDetailsContainerConfigurationSettings = _ref$hotspotThumbnail === void 0 ? {} : _ref$hotspotThumbnail, _ref$hotspotThumbnail2 = _ref.hotspotThumbnailTimestampLabelConfigurationSettings, hotspotThumbnailTimestampLabelConfigurationSettings = _ref$hotspotThumbnail2 === void 0 ? {} : _ref$hotspotThumbnail2, _ref$hotspotThumbnail3 = _ref.hotspotThumbnailContainerConfigurationSettings, hotspotThumbnailContainerConfigurationSettings = _ref$hotspotThumbnail3 === void 0 ? {} : _ref$hotspotThumbnail3, _ref$videoTimelineBar2 = _ref.videoTimelineBarContainerConfigurationSettings, videoTimelineBarContainerConfigurationSettings = _ref$videoTimelineBar2 === void 0 ? {} : _ref$videoTimelineBar2, _ref$videoTimelineBar3 = _ref.videoTimelineBarConfigurationSettings, videoTimelineBarConfigurationSettings = _ref$videoTimelineBar3 === void 0 ? {} : _ref$videoTimelineBar3, _ref$hotspotThumbnail4 = _ref.hotspotThumbnailConfigurationSettings, hotspotThumbnailConfigurationSettings = _ref$hotspotThumbnail4 === void 0 ? {} : _ref$hotspotThumbnail4, _ref$hotspotConfigura = _ref.hotspotConfigurationSettings, hotspotConfigurationSettings = _ref$hotspotConfigura === void 0 ? {} : _ref$hotspotConfigura, _ref$videoTimelineBar4 = _ref.videoTimelineBarTimestampHoverContentConfigurations, videoTimelineBarTimestampHoverContentConfigurations = _ref$videoTimelineBar4 === void 0 ? {} : _ref$videoTimelineBar4, _ref$hotspotThumbnail5 = _ref.hotspotThumbnailDetailsContainerConfigurations, hotspotThumbnailDetailsContainerConfigurations = _ref$hotspotThumbnail5 === void 0 ? {} : _ref$hotspotThumbnail5, _ref$hotspotThumbnail6 = _ref.hotspotThumbnailTimestampLabelConfigurations, hotspotThumbnailTimestampLabelConfigurations = _ref$hotspotThumbnail6 === void 0 ? {} : _ref$hotspotThumbnail6, _ref$hotspotThumbnail7 = _ref.hotspotThumbnailContainerConfigurations, hotspotThumbnailContainerConfigurations = _ref$hotspotThumbnail7 === void 0 ? {} : _ref$hotspotThumbnail7, _ref$videoTimelineBar5 = _ref.videoTimelineBarContainerConfigurations, videoTimelineBarContainerConfigurations = _ref$videoTimelineBar5 === void 0 ? {} : _ref$videoTimelineBar5, _ref$hotspotThumbnail8 = _ref.hotspotThumbnailLabelConfigurations, hotspotThumbnailLabelConfigurations = _ref$hotspotThumbnail8 === void 0 ? {} : _ref$hotspotThumbnail8, _ref$videoTimelineBar6 = _ref.videoTimelineBarConfigurations, videoTimelineBarConfigurations = _ref$videoTimelineBar6 === void 0 ? {} : _ref$videoTimelineBar6, _ref$hotspotThumbnail9 = _ref.hotspotThumbnailConfigurations, hotspotThumbnailConfigurations = _ref$hotspotThumbnail9 === void 0 ? {} : _ref$hotspotThumbnail9, _ref$hotspotConfigura2 = _ref.hotspotConfigurations, hotspotConfigurations = _ref$hotspotConfigura2 === void 0 ? {} : _ref$hotspotConfigura2, _ref$videoTimelineBar7 = _ref.videoTimelineBarTimestampHoverUpperContent, videoTimelineBarTimestampHoverUpperContent = _ref$videoTimelineBar7 === void 0 ? null : _ref$videoTimelineBar7, _ref$videoTimelineBar8 = _ref.videoTimelineBarTimestampHoverContent, videoTimelineBarTimestampHoverContent = _ref$videoTimelineBar8 === void 0 ? null : _ref$videoTimelineBar8, onSeek = _ref.onSeek, _ref$disableHotspotIn = _ref.disableHotspotInteractionOnHotspotScrollMode, disableHotspotInteractionOnHotspotScrollMode = _ref$disableHotspotIn === void 0 ? true : _ref$disableHotspotIn, _ref$disableBarHoverO = _ref.disableBarHoverOnHotspotScrollMode, disableBarHoverOnHotspotScrollMode = _ref$disableBarHoverO === void 0 ? false : _ref$disableBarHoverO, _ref$disableBarSeekOn = _ref.disableBarSeekOnHotspotScrollMode, disableBarSeekOnHotspotScrollMode = _ref$disableBarSeekOn === void 0 ? true : _ref$disableBarSeekOn, _ref$hotspotScrollMod = _ref.hotspotScrollMode, hotspotScrollMode = _ref$hotspotScrollMod === void 0 ? "none" : _ref$hotspotScrollMod, _ref$hotspots = _ref.hotspots, hotspots = _ref$hotspots === void 0 ? [] : _ref$hotspots, currentTime = _ref.currentTime, duration = _ref.duration, video = _ref.video; var _useState = useState(null), _useState2 = _slicedToArray(_useState, 2), hoverThumbnail = _useState2[0], setHoverThumbnail = _useState2[1]; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), dragging = _useState4[0], setDragging = _useState4[1]; var _useState5 = useState(null), _useState6 = _slicedToArray(_useState5, 2), hoverX = _useState6[0], setHoverX = _useState6[1]; var thumbnailCache = useRef({}); var barRef = useRef(null); var percent = duration > 0 ? currentTime / duration * 100 : 0; var updateSeek = function updateSeek(e) { if (!barRef.current || duration <= 0) { return; } var rect = barRef.current.getBoundingClientRect(); var px = e.clientX - rect.left; var ratio = Math.max(0, Math.min(1, px / rect.width)); onSeek(ratio * duration); setHoverX(px); }; var generateThumbnail = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(time) { var tempVideo; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (!thumbnailCache.current[time]) { _context.next = 2; break; } return _context.abrupt("return", thumbnailCache.current[time]); case 2: if (video) { _context.next = 4; break; } return _context.abrupt("return", null); case 4: tempVideo = document.createElement("video"); tempVideo.src = video.src; tempVideo.crossOrigin = "anonymous"; tempVideo.muted = true; tempVideo.currentTime = time; return _context.abrupt("return", new Promise(function (resolve) { tempVideo.onseeked = function () { var canvas = document.createElement("canvas"); canvas.width = 160; canvas.height = 90; var ctx = canvas.getContext("2d"); ctx.drawImage(tempVideo, 0, 0, canvas.width, canvas.height); var dataURL = canvas.toDataURL(); thumbnailCache.current[time] = dataURL; resolve(dataURL); }; })); case 10: case "end": return _context.stop(); } }, _callee); })); return function generateThumbnail(_x) { return _ref2.apply(this, arguments); }; }(); useEffect(function () { if (hotspotScrollMode === "interpolate") { return; } var stop = function stop() { return setDragging(false); }; if (dragging) { window.addEventListener("mouseup", stop); window.addEventListener("mousemove", updateSeek); } return function () { window.removeEventListener("mouseup", stop); window.removeEventListener("mousemove", updateSeek); }; }, [hotspotScrollMode, dragging]); return /*#__PURE__*/React.createElement("div", _extends({ ref: barRef, style: _objectSpread({ position: "absolute", cursor: hotspotScrollMode === "interpolate" ? "default" : "pointer", borderRadius: "2px", background: "rgba(255, 255, 255, 0.08)", height: "4px", zIndex: 20, bottom: "0.75rem", right: "5%", left: "5%" }, videoTimelineBarContainerConfigurationSettings), onMouseLeave: function onMouseLeave() { setHoverX(null); setHoverThumbnail(null); }, onMouseMove: disableBarHoverOnHotspotScrollMode && hotspotScrollMode === "interpolate" ? undefined : function (e) { if (!dragging && barRef.current && !hoverThumbnail) { var rect = barRef.current.getBoundingClientRect(); setHoverX(e.clientX - rect.left); } }, onMouseDown: disableBarSeekOnHotspotScrollMode && hotspotScrollMode === "interpolate" ? undefined : function (e) { setDragging(true); updateSeek(e); } }, videoTimelineBarContainerConfigurations), /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ position: "absolute", transition: "width 0.05s ease-out", borderRadius: "2px", boxShadow: "0 0 6px 2px rgba(255, 255, 255, 0.25)", background: "#fff", width: "".concat(percent, "%"), bottom: 0, left: 0, top: 0 }, videoTimelineBarConfigurationSettings) }, videoTimelineBarConfigurations)), hotspots.map(function (h, idx) { return /*#__PURE__*/React.createElement("div", _extends({ key: idx, style: _objectSpread({ position: "absolute", transition: "transform 0.2s ease, box-shadow 0.2s ease", backdropFilter: "blur(10px)", WebkitBackdropFilter: "blur(10px)", border: "1px solid rgba(255, 255, 255, 0.169)", borderRadius: "0.169rem", boxShadow: "0 0 12.69px rgba(255, 255, 255, 0.269)", background: h.color || "rgba(255, 255, 255, 0.1269)", zIndex: 21, height: "9.69px", width: "5.69px", left: "calc(".concat(h.time / duration * 100, "% - 6px)"), top: "-3px" }, hotspotConfigurationSettings), onMouseLeave: function onMouseLeave() { return setHoverThumbnail(null); }, onMouseEnter: /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { var img; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: _context2.t0 = h.thumbnail; if (_context2.t0) { _context2.next = 5; break; } _context2.next = 4; return generateThumbnail(h.time); case 4: _context2.t0 = _context2.sent; case 5: img = _context2.t0; setHoverThumbnail({ img: img, time: h.time, label: h.label }); case 7: case "end": return _context2.stop(); } }, _callee2); })), onMouseOver: function onMouseOver(e) { e.currentTarget.style.transform = "scale(1.3)"; e.currentTarget.style.boxShadow = "0 0 8px rgba(255,255,255,0.6)"; }, onMouseOut: function onMouseOut(e) { e.currentTarget.style.transform = "scale(1)"; e.currentTarget.style.boxShadow = "0 0 3px rgba(255,255,255,0.3)"; }, onClick: function onClick() { if (disableHotspotInteractionOnHotspotScrollMode && hotspotScrollMode === "interpolate") { return; } onSeek(h.time); setHoverX(null); setHoverThumbnail(null); } }, hotspotConfigurations)); }), hoverX !== null && duration > 0 && /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ position: "absolute", pointerEvents: "none", userSelect: "none", whiteSpace: "nowrap", transform: "translateX(-50%)", fontSize: "12px", borderRadius: "4px", boxShadow: "0 2px 6px rgba(0, 0, 0, 0.369)", background: "rgba(0, 0, 0, 0.69)", color: "#fff", zIndex: 30, padding: "2px 6px", bottom: "140%", left: hoverX }, videoTimelineBarTimestampHoverContentConfigurationSettings) }, videoTimelineBarTimestampHoverContentConfigurations), videoTimelineBarTimestampHoverUpperContent, ConvertToVideoTime(hoverX / barRef.current.offsetWidth * duration), videoTimelineBarTimestampHoverContent), hoverThumbnail && /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ position: "absolute", display: "flex", flexDirection: "column", alignItems: "center", transform: "translateX(-50%)", zIndex: 35, bottom: "190%", left: "".concat(hoverThumbnail.time / duration * 100, "%") }, hotspotThumbnailContainerConfigurationSettings) }, hotspotThumbnailContainerConfigurations), /*#__PURE__*/React.createElement("img", _extends({ src: hoverThumbnail.img, style: _objectSpread({ borderRadius: "6px", boxShadow: "0 4px 12px rgba(0, 0, 0, 0.5)", height: "90px", width: "160px" }, hotspotThumbnailConfigurationSettings), alt: "thumbnail" }, hotspotThumbnailConfigurations)), /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ pointerEvents: "none", whiteSpace: "nowrap", textAlign: "center", WebkitBackdropFilter: "blur(10px)", backdropFilter: "blur(10px)", fontWeight: 500, fontSize: "13px", borderRadius: "8px", boxShadow: "0 2px 8px rgba(0, 0, 0, 0.4)", background: "rgba(18, 18, 18, 0.75)", color: "#fff", padding: "6px 10px", marginTop: "6px" }, hotspotThumbnailDetailsContainerConfigurationSettings) }, hotspotThumbnailDetailsContainerConfigurations), /*#__PURE__*/React.createElement("div", hotspotThumbnailLabelConfigurations, hoverThumbnail.label), /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ fontSize: "11px", opacity: 0.8 }, hotspotThumbnailTimestampLabelConfigurationSettings) }, hotspotThumbnailTimestampLabelConfigurations), ConvertToVideoTime(hoverThumbnail.time))))); } ; function HUDVideoScroller(_ref4) { var _ref4$videoTimelineBa = _ref4.videoTimelineBarTimestampHoverContentConfigurationSettings, videoTimelineBarTimestampHoverContentConfigurationSettings = _ref4$videoTimelineBa === void 0 ? {} : _ref4$videoTimelineBa, _ref4$hotspotThumbnai = _ref4.hotspotThumbnailDetailsContainerConfigurationSettings, hotspotThumbnailDetailsContainerConfigurationSettings = _ref4$hotspotThumbnai === void 0 ? {} : _ref4$hotspotThumbnai, _ref4$hotspotThumbnai2 = _ref4.hotspotThumbnailTimestampLabelConfigurationSettings, hotspotThumbnailTimestampLabelConfigurationSettings = _ref4$hotspotThumbnai2 === void 0 ? {} : _ref4$hotspotThumbnai2, _ref4$hotspotThumbnai3 = _ref4.hotspotThumbnailContainerConfigurationSettings, hotspotThumbnailContainerConfigurationSettings = _ref4$hotspotThumbnai3 === void 0 ? {} : _ref4$hotspotThumbnai3, _ref4$videoTimelineBa2 = _ref4.videoTimelineBarContainerConfigurationSettings, videoTimelineBarContainerConfigurationSettings = _ref4$videoTimelineBa2 === void 0 ? {} : _ref4$videoTimelineBa2, _ref4$videoScrollArea = _ref4.videoScrollAreaContainerConfigurationSettings, videoScrollAreaContainerConfigurationSettings = _ref4$videoScrollArea === void 0 ? {} : _ref4$videoScrollArea, _ref4$videoScrollerCo = _ref4.videoScrollerContainerConfigurationSettings, videoScrollerContainerConfigurationSettings = _ref4$videoScrollerCo === void 0 ? {} : _ref4$videoScrollerCo, _ref4$videoScrollArea2 = _ref4.videoScrollAreaConfigurationSettings, videoScrollAreaConfigurationSettings = _ref4$videoScrollArea2 === void 0 ? {} : _ref4$videoScrollArea2, _ref4$videoScrollerCo2 = _ref4.videoScrollerConfigurationSettings, videoScrollerConfigurationSettings = _ref4$videoScrollerCo2 === void 0 ? {} : _ref4$videoScrollerCo2, _ref4$videoScrollArea3 = _ref4.videoScrollAreaContainerConfigurations, videoScrollAreaContainerConfigurations = _ref4$videoScrollArea3 === void 0 ? {} : _ref4$videoScrollArea3, _ref4$videoTimelineBa3 = _ref4.videoTimelineBarConfigurationSettings, videoTimelineBarConfigurationSettings = _ref4$videoTimelineBa3 === void 0 ? {} : _ref4$videoTimelineBa3, _ref4$hotspotThumbnai4 = _ref4.hotspotThumbnailConfigurationSettings, hotspotThumbnailConfigurationSettings = _ref4$hotspotThumbnai4 === void 0 ? {} : _ref4$hotspotThumbnai4, _ref4$videoScrollerCo3 = _ref4.videoScrollerContainerConfigurations, videoScrollerContainerConfigurations = _ref4$videoScrollerCo3 === void 0 ? {} : _ref4$videoScrollerCo3, _ref4$idleContainerCo = _ref4.idleContainerConfigurationSettings, idleContainerConfigurationSettings = _ref4$idleContainerCo === void 0 ? {} : _ref4$idleContainerCo, _ref4$idleContentConf = _ref4.idleContentConfigurationSettings, idleContentConfigurationSettings = _ref4$idleContentConf === void 0 ? {} : _ref4$idleContentConf, _ref4$hotspotConfigur = _ref4.hotspotConfigurationSettings, hotspotConfigurationSettings = _ref4$hotspotConfigur === void 0 ? {} : _ref4$hotspotConfigur, _ref4$videoTimelineBa4 = _ref4.videoTimelineBarTimestampHoverContentConfigurations, videoTimelineBarTimestampHoverContentConfigurations = _ref4$videoTimelineBa4 === void 0 ? {} : _ref4$videoTimelineBa4, _ref4$hotspotThumbnai5 = _ref4.hotspotThumbnailDetailsContainerConfigurations, hotspotThumbnailDetailsContainerConfigurations = _ref4$hotspotThumbnai5 === void 0 ? {} : _ref4$hotspotThumbnai5, _ref4$hotspotThumbnai6 = _ref4.hotspotThumbnailTimestampLabelConfigurations, hotspotThumbnailTimestampLabelConfigurations = _ref4$hotspotThumbnai6 === void 0 ? {} : _ref4$hotspotThumbnai6, _ref4$hotspotThumbnai7 = _ref4.hotspotThumbnailContainerConfigurations, hotspotThumbnailContainerConfigurations = _ref4$hotspotThumbnai7 === void 0 ? {} : _ref4$hotspotThumbnai7, _ref4$videoTimelineBa5 = _ref4.videoTimelineBarContainerConfigurations, videoTimelineBarContainerConfigurations = _ref4$videoTimelineBa5 === void 0 ? {} : _ref4$videoTimelineBa5, _ref4$hotspotThumbnai8 = _ref4.hotspotThumbnailLabelConfigurations, hotspotThumbnailLabelConfigurations = _ref4$hotspotThumbnai8 === void 0 ? {} : _ref4$hotspotThumbnai8, _ref4$videoTimelineBa6 = _ref4.videoTimelineBarConfigurations, videoTimelineBarConfigurations = _ref4$videoTimelineBa6 === void 0 ? {} : _ref4$videoTimelineBa6, _ref4$hotspotThumbnai9 = _ref4.hotspotThumbnailConfigurations, hotspotThumbnailConfigurations = _ref4$hotspotThumbnai9 === void 0 ? {} : _ref4$hotspotThumbnai9, _ref4$videoScrollArea4 = _ref4.videoScrollAreaConfigurations, videoScrollAreaConfigurations = _ref4$videoScrollArea4 === void 0 ? {} : _ref4$videoScrollArea4, _ref4$videoScrollerCo4 = _ref4.videoScrollerConfigurations, videoScrollerConfigurations = _ref4$videoScrollerCo4 === void 0 ? {} : _ref4$videoScrollerCo4, _ref4$idleContainerCo2 = _ref4.idleContainerConfigurations, idleContainerConfigurations = _ref4$idleContainerCo2 === void 0 ? {} : _ref4$idleContainerCo2, _ref4$idleContentConf2 = _ref4.idleContentConfigurations, idleContentConfigurations = _ref4$idleContentConf2 === void 0 ? {} : _ref4$idleContentConf2, _ref4$hotspotConfigur2 = _ref4.hotspotConfigurations, hotspotConfigurations = _ref4$hotspotConfigur2 === void 0 ? {} : _ref4$hotspotConfigur2, _ref4$videoConfigurat = _ref4.videoConfigurations, videoConfigurations = _ref4$videoConfigurat === void 0 ? {} : _ref4$videoConfigurat, _ref4$scrollDirection = _ref4.scrollDirection, scrollDirection = _ref4$scrollDirection === void 0 ? "vertical" : _ref4$scrollDirection, _ref4$scrollResolutio = _ref4.scrollResolution, scrollResolution = _ref4$scrollResolutio === void 0 ? 250 : _ref4$scrollResolutio, _ref4$externalScrollP = _ref4.externalScrollPercent, externalScrollPercent = _ref4$externalScrollP === void 0 ? null : _ref4$externalScrollP, _ref4$autoPlayUntil = _ref4.autoPlayUntil, autoPlayUntil = _ref4$autoPlayUntil === void 0 ? null : _ref4$autoPlayUntil, _ref4$hotspotScrollMo = _ref4.hotspotScrollMode, hotspotScrollMode = _ref4$hotspotScrollMo === void 0 ? "interpolate" : _ref4$hotspotScrollMo, _ref4$interpolationDu = _ref4.interpolationDuration, interpolationDuration = _ref4$interpolationDu === void 0 ? 2000 : _ref4$interpolationDu, _ref4$disableHotspotI = _ref4.disableHotspotInteractionOnHotspotScrollMode, disableHotspotInteractionOnHotspotScrollMode = _ref4$disableHotspotI === void 0 ? true : _ref4$disableHotspotI, _ref4$disableBarHover = _ref4.disableBarHoverOnHotspotScrollMode, disableBarHoverOnHotspotScrollMode = _ref4$disableBarHover === void 0 ? false : _ref4$disableBarHover, _ref4$disableBarSeekO = _ref4.disableBarSeekOnHotspotScrollMode, disableBarSeekOnHotspotScrollMode = _ref4$disableBarSeekO === void 0 ? true : _ref4$disableBarSeekO, _ref4$displayBaseIdle = _ref4.displayBaseIdleContent, displayBaseIdleContent = _ref4$displayBaseIdle === void 0 ? true : _ref4$displayBaseIdle, _ref4$idleDetectionEn = _ref4.idleDetectionEnabled, idleDetectionEnabled = _ref4$idleDetectionEn === void 0 ? false : _ref4$idleDetectionEn, _ref4$idleContent = _ref4.idleContent, idleContent = _ref4$idleContent === void 0 ? null : _ref4$idleContent, _ref4$idleTimeout = _ref4.idleTimeout, idleTimeout = _ref4$idleTimeout === void 0 ? 5000 : _ref4$idleTimeout, _ref4$hotspots = _ref4.hotspots, hotspots = _ref4$hotspots === void 0 ? [] : _ref4$hotspots, videoSRC = _ref4.videoSRC; var _useState7 = useState(0), _useState8 = _slicedToArray(_useState7, 2), videoDuration = _useState8[0], setVideoDuration = _useState8[1]; var _useState9 = useState(0), _useState10 = _slicedToArray(_useState9, 2), displayedTime = _useState10[0], setDisplayedTime = _useState10[1]; var _useState11 = useState(0), _useState12 = _slicedToArray(_useState11, 2), actualTime = _useState12[0], setActualTime = _useState12[1]; var _useState13 = useState(false), _useState14 = _slicedToArray(_useState13, 2), idle = _useState14[0], setIdle = _useState14[1]; var lastInterpolatedTarget = useRef(null); var previousScrollPercent = useRef(null); var autoPlayStopCallback = useRef(null); var interpolationLockUntil = useRef(0); var currentLerpTarget = useRef(null); var animationFrame = useRef(null); var debounceTimer = useRef(null); var renderLoopRef = useRef(null); var lerpAnimation = useRef(null); var autoPlaying = useRef(false); var isDrawing = useRef(false); var scrollRef = useRef(null); var canvasRef = useRef(null); var videoRef = useRef(null); var lerping = useRef(false); var scrollSize = videoDuration * scrollResolution || 1; var isHorizontal = scrollDirection === "horizontal"; var isVertical = scrollDirection === "vertical"; var isBoth = scrollDirection === "both"; var resetIdleTimer = useIdleDetection(function () { setIdle(true); }, idleTimeout, idleDetectionEnabled); var startRenderLoop = function startRenderLoop() { if (renderLoopRef.current) { return; } var loop = function loop() { drawFrame(); renderLoopRef.current = requestAnimationFrame(loop); }; renderLoopRef.current = requestAnimationFrame(loop); }; var stopRenderLoop = function stopRenderLoop() { if (renderLoopRef.current) { cancelAnimationFrame(renderLoopRef.current); renderLoopRef.current = null; } }; var drawFrame = function drawFrame() { if (isDrawing.current) { return; } isDrawing.current = true; requestAnimationFrame(function () { var canvas = canvasRef.current; var video = videoRef.current; if (!video || !canvas) { return; } var ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(video, 0, 0, canvas.width, canvas.height); isDrawing.current = false; }); }; var seekTo = function seekTo(percent) { var scroll = scrollRef.current; var video = videoRef.current; if (!video || !scroll || !videoDuration) { return; } percent = Math.max(0, Math.min(1, percent)); var targetTime = percent * videoDuration; if (Math.abs(targetTime - video.currentTime) > 0.01) { video.currentTime = targetTime; drawFrame(); } requestAnimationFrame(function () { var h = scroll.scrollHeight - scroll.clientHeight; var w = scroll.scrollWidth - scroll.clientWidth; syncScrollToPercent(scroll, percent, h, w); }); }; var syncScrollToPercent = useCallback(function (scroll, percent, h, w) { if (!scroll) { return; } if (isBoth) { scroll.scrollLeft = percent * w; scroll.scrollTop = percent * h; } else if (isVertical) { scroll.scrollTop = percent * h; } else { scroll.scrollLeft = percent * w; } }, [isBoth, isVertical]); var findNearestHotspot = useCallback(function (currentTime) { var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "forward"; if (hotspots.length === 0) { return currentTime; } var sortedTimes = _toConsumableArray(hotspots).map(function (h) { return h.time; }).sort(function (a, b) { return a - b; }); var first = sortedTimes[0]; var last = sortedTimes[sortedTimes.length - 1]; if (direction === "backward") { var _reverse$find; if (currentTime > last) { return last; } return (_reverse$find = _toConsumableArray(sortedTimes).reverse().find(function (t) { return t < currentTime; })) !== null && _reverse$find !== void 0 ? _reverse$find : 0; } if (direction === "forward") { var _sortedTimes$find; if (currentTime < first) { return first; } return (_sortedTimes$find = sortedTimes.find(function (t) { return t > currentTime; })) !== null && _sortedTimes$find !== void 0 ? _sortedTimes$find : videoDuration; } return sortedTimes.reduce(function (prev, curr) { return Math.abs(curr - currentTime) < Math.abs(prev - currentTime) ? curr : prev; }, first); }, [hotspots, videoDuration]); var startLerpTo = useCallback(function (targetTime) { var duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000; if (!videoRef.current || lerping.current || lastInterpolatedTarget.current === targetTime) { return; } lerping.current = true; lastInterpolatedTarget.current = targetTime; currentLerpTarget.current = targetTime; interpolationLockUntil.current = performance.now() + duration; lerping.current = true; var scroll = scrollRef.current; var video = videoRef.current; var scrollHeight = scroll.scrollHeight - scroll.clientHeight; var scrollWidth = scroll.scrollWidth - scroll.clientWidth; var initialTime = video.currentTime; var delta = targetTime - initialTime; var start = performance.now(); var render = function render(now) { var elapsed = now - start; var t = Math.min(1, elapsed / duration); var easedT = 0.5 - 0.5 * Math.cos(Math.PI * t); var time = initialTime + delta * easedT; video.currentTime = time; var onSeeked = function onSeeked() { drawFrame(); video.removeEventListener("seeked", onSeeked); var percent = time / videoDuration; if (isHorizontal || isBoth) { scroll.scrollLeft = percent * scrollWidth; } if (isVertical || isBoth) { scroll.scrollTop = percent * scrollHeight; } if (t < 1) { lerpAnimation.current = requestAnimationFrame(render); } else { setTimeout(function () { lerping.current = false; lastInterpolatedTarget.current = null; currentLerpTarget.current = null; }, 100); } }; video.addEventListener("seeked", onSeeked); }; lerpAnimation.current = requestAnimationFrame(render); }, [videoDuration, isHorizontal, isVertical, isBoth]); var handleScroll = function handleScroll() { handleDismissIdle(); if (externalScrollPercent !== null || !videoDuration) { return; } if (autoPlaying.current && autoPlayStopCallback.current) { autoPlayStopCallback.current(); } var scroll = scrollRef.current; if (!scroll || !videoRef.current) { return; } var percent = 0; if (isBoth) { var y = scroll.scrollTop / (scroll.scrollHeight - scroll.clientHeight); var x = scroll.scrollLeft / (scroll.scrollWidth - scroll.clientWidth); percent = Math.max(x, y); } else if (isVertical) { percent = scroll.scrollTop / (scroll.scrollHeight - scroll.clientHeight); } else { percent = scroll.scrollLeft / (scroll.scrollWidth - scroll.clientWidth); } var direction = "forward"; if (previousScrollPercent.current !== null) { var delta = percent - previousScrollPercent.current; direction = delta > 0 ? "forward" : delta < 0 ? "backward" : "none"; } previousScrollPercent.current = percent; if (debounceTimer.current) { clearTimeout(debounceTimer.current); } debounceTimer.current = setTimeout(function () { var currentTime = percent * videoDuration; if (hotspotScrollMode === "interpolate" && hotspots.length > 0 && !lerping.current && currentLerpTarget.current === null && lastInterpolatedTarget.current !== currentTime) { var nearest = findNearestHotspot(currentTime, direction); startLerpTo(nearest, interpolationDuration); } else if (hotspotScrollMode !== "interpolate") { seekTo(percent); } }, 5); }; var handleDismissIdle = function handleDismissIdle() { if (idle) { setIdle(false); resetIdleTimer(); } }; useEffect(function () { var video = videoRef.current; if (!video) { return; } var handleLoaded = function handleLoaded() { var duration = video.duration || 0; setVideoDuration(duration); video.pause(); video.currentTime = 0; video.play().then(function () { return video.pause(); })["catch"](function () {}); setActualTime(0); setDisplayedTime(0); if (autoPlayUntil !== null) { autoPlaying.current = true; if (hotspotScrollMode === "interpolate") { var targetTime = videoDuration; if (hotspots.length > 0) { if (autoPlayUntil === "end") { targetTime = hotspots[hotspots.length - 1].time; } else { var _sorted$find; var sorted = _toConsumableArray(hotspots).map(function (h) { return h.time; }).sort(function (a, b) { return a - b; }); targetTime = (_sorted$find = sorted.find(function (t) { return t >= autoPlayUntil; })) !== null && _sorted$find !== void 0 ? _sorted$find : sorted[sorted.length - 1]; } } else { targetTime = autoPlayUntil === "end" ? videoDuration : Math.min(autoPlayUntil, videoDuration); } startLerpTo(targetTime, interpolationDuration); setTimeout(function () { autoPlaying.current = false; lastInterpolatedTarget.current = null; currentLerpTarget.current = null; }, interpolationDuration + 100); return; } var playTo = autoPlayUntil === "end" ? duration : Math.min(autoPlayUntil, duration); setTimeout(function () { video.currentTime = 0; video.play()["catch"](function () {}); startRenderLoop(); var stopPlayback = function stopPlayback() { if (video.currentTime >= playTo) { video.pause(); stopRenderLoop(); video.removeEventListener("timeupdate", stopPlayback); autoPlaying.current = false; var percent = video.currentTime / duration; requestAnimationFrame(function () { var scroll = scrollRef.current; if (!scroll) { return; } var h = scroll.scrollHeight - scroll.clientHeight; var w = scroll.scrollWidth - scroll.clientWidth; syncScrollToPercent(scroll, percent, h, w); }); } }; video.addEventListener("timeupdate", stopPlayback); autoPlayStopCallback.current = function () { var percent = video.currentTime / duration; requestAnimationFrame(function () { var scroll = scrollRef.current; if (!scroll) { return; } var h = scroll.scrollHeight - scroll.clientHeight; var w = scroll.scrollWidth - scroll.clientWidth; syncScrollToPercent(scroll, percent, h, w); }); video.pause(); stopRenderLoop(); video.removeEventListener("timeupdate", stopPlayback); autoPlaying.current = false; }; }, 269); } }; var handleTimeUpdate = function handleTimeUpdate() { setActualTime(video.currentTime); if (video.paused || video.ended) { stopRenderLoop(); } }; video.addEventListener("loadedmetadata", handleLoaded); video.addEventListener("timeupdate", handleTimeUpdate); return function () { video.removeEventListener("loadedmetadata", handleLoaded); video.removeEventListener("timeupdate", handleTimeUpdate); stopRenderLoop(); }; }, [videoSRC, autoPlayUntil, hotspotScrollMode]); useEffect(function () { var lerp = function lerp(a, b, t) { return a + (b - a) * t; }; var loop = function loop() { setDisplayedTime(function (prev) { var next = lerp(prev, actualTime, 0.2); return Math.abs(next - actualTime) < 0.001 ? actualTime : next; }); animationFrame.current = requestAnimationFrame(loop); }; loop(); return function () { cancelAnimationFrame(animationFrame.current); }; }, [actualTime]); useEffect(function () { var scroll = scrollRef.current; var video = videoRef.current; if (typeof externalScrollPercent !== "number" || !scroll || !video || !videoDuration) { return; } var percent = Math.max(0, Math.min(1, externalScrollPercent)); var targetTime = percent * videoDuration; video.currentTime = targetTime; requestAnimationFrame(function () { var h = scroll.scrollHeight - scroll.clientHeight; var w = scroll.scrollWidth - scroll.clientWidth; syncScrollToPercent(scroll, percent, h, w); }); }, [externalScrollPercent, videoDuration, scrollSize]); useEffect(function () { var video = videoRef.current; if (!video) { return; } video.addEventListener("seeked", drawFrame); return function () { return video.removeEventListener("seeked", drawFrame); }; }, []); return /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ position: "relative", overflow: "hidden", borderRadius: "1rem", background: "#000", height: "100%", width: "100%" }, videoScrollerContainerConfigurationSettings) }, videoScrollerContainerConfigurations), /*#__PURE__*/React.createElement(HUDVideoTimelineBar, { videoTimelineBarTimestampHoverContentConfigurationSettings: videoTimelineBarTimestampHoverContentConfigurationSettings, hotspotThumbnailDetailsContainerConfigurationSettings: hotspotThumbnailDetailsContainerConfigurationSettings, hotspotThumbnailTimestampLabelConfigurationSettings: hotspotThumbnailTimestampLabelConfigurationSettings, hotspotThumbnailContainerConfigurationSettings: hotspotThumbnailContainerConfigurationSettings, videoTimelineBarContainerConfigurationSettings: videoTimelineBarContainerConfigurationSettings, videoTimelineBarConfigurationSettings: videoTimelineBarConfigurationSettings, hotspotThumbnailConfigurationSettings: hotspotThumbnailConfigurationSettings, hotspotConfigurationSettings: hotspotConfigurationSettings, videoTimelineBarTimestampHoverContentConfigurations: videoTimelineBarTimestampHoverContentConfigurations, hotspotThumbnailDetailsContainerConfigurations: hotspotThumbnailDetailsContainerConfigurations, hotspotThumbnailTimestampLabelConfigurations: hotspotThumbnailTimestampLabelConfigurations, hotspotThumbnailContainerConfigurations: hotspotThumbnailContainerConfigurations, videoTimelineBarContainerConfigurations: videoTimelineBarContainerConfigurations, hotspotThumbnailLabelConfigurations: hotspotThumbnailLabelConfigurations, videoTimelineBarConfigurations: videoTimelineBarConfigurations, hotspotThumbnailConfigurations: hotspotThumbnailConfigurations, hotspotConfigurations: hotspotConfigurations, onSeek: function onSeek(time) { seekTo(time / videoDuration); }, disableHotspotInteractionOnHotspotScrollMode: disableHotspotInteractionOnHotspotScrollMode, disableBarHoverOnHotspotScrollMode: disableBarHoverOnHotspotScrollMode, disableBarSeekOnHotspotScrollMode: disableBarSeekOnHotspotScrollMode, hotspotScrollMode: hotspotScrollMode, currentTime: displayedTime, duration: videoDuration, video: videoRef.current, hotspots: hotspots }), /*#__PURE__*/React.createElement("canvas", _extends({ ref: canvasRef, style: _objectSpread({ display: "block", borderRadius: "1rem", background: "#000", height: "auto", width: "100%" }, videoScrollerConfigurationSettings), height: 1080, width: 1920 }, videoScrollerConfigurations)), /*#__PURE__*/React.createElement("div", _extends({ ref: scrollRef, style: _objectSpread({ position: "absolute", overflowX: isHorizontal || isBoth ? "scroll" : "hidden", overflowY: isVertical || isBoth ? "scroll" : "hidden", pointerEvents: "auto", zIndex: 10, bottom: 0, right: 0, left: 0, top: 0 }, videoScrollAreaContainerConfigurationSettings), onScroll: handleScroll }, videoScrollAreaContainerConfigurations), /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ height: isVertical ? scrollSize : "100%", width: isVertical ? "100%" : scrollSize }, videoScrollAreaConfigurationSettings) }, videoScrollAreaConfigurations))), /*#__PURE__*/React.createElement("video", _extends({ ref: videoRef, style: { display: "none" }, src: videoSRC, playsInline: true, muted: true }, videoConfigurations)), idle && /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ position: "absolute", inset: 0, zIndex: 0 }, idleContainerConfigurationSettings), onTouchStart: handleDismissIdle, onWheel: handleDismissIdle, onClick: handleDismissIdle }, idleContainerConfigurations), typeof idleContent === "funtion" ? idleContent(handleDismissIdle, seekTo, handleScroll) : idleContent ? idleContent : displayBaseIdleContent ? /*#__PURE__*/React.createElement("div", _extends({ style: _objectSpread({ position: "absolute", cursor: "pointer", transform: "translateX(-50%)", textAlign: "center", fontSize: "1rem", fontWeight: 500, borderRadius: "1rem", boxShadow: "0 0 20px rgba(0,0,0,0.4)", background: "rgba(0,0,0,0.7)", color: "#fff", zIndex: 9999, padding: "1rem 2rem", bottom: "5%", left: "50%" }, idleContentConfigurationSettings) }, idleContentConfigurations), "Scroll to proceed") : null)); } ; export default HUDVideoScroller;