diff --git a/ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx b/ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx index 0c58f92d2..2bc4f6281 100644 --- a/ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx +++ b/ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx @@ -9,6 +9,7 @@ import "./PlaylistButtons"; import "./source-selector"; import "./persist-volume"; import "./markers"; +import "./big-buttons"; import cx from "classnames"; import * as GQL from "src/core/generated-graphql"; @@ -168,6 +169,7 @@ export const ScenePlayer: React.FC = ({ (player as any).offset(); (player as any).sourceSelector(); (player as any).persistVolume(); + (player as any).bigButtons(); player.focus(); playerRef.current = player; @@ -316,6 +318,7 @@ export const ScenePlayer: React.FC = ({ }); player.on("play", function (this: VideoJsPlayer) { + player.poster(""); if (scene.interactive) { interactiveClient.play(this.currentTime()); } diff --git a/ui/v2.5/src/components/ScenePlayer/big-buttons.ts b/ui/v2.5/src/components/ScenePlayer/big-buttons.ts new file mode 100644 index 000000000..ac503afee --- /dev/null +++ b/ui/v2.5/src/components/ScenePlayer/big-buttons.ts @@ -0,0 +1,54 @@ +import videojs, { VideoJsPlayer } from "video.js"; + +const BigPlayButton = videojs.getComponent("BigPlayButton"); + +class BigPlayPauseButton extends BigPlayButton { + handleClick(event: videojs.EventTarget.Event) { + if (this.player().paused()) { + // @ts-ignore for some reason handleClick isn't defined in BigPlayButton type. Not sure why + super.handleClick(event); + } else { + this.player().pause(); + } + } + + buildCSSClass() { + return "vjs-control vjs-button vjs-big-play-pause-button"; + } +} + +class BigButtonGroup extends videojs.getComponent("Component") { + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + constructor(player: VideoJsPlayer, options: any) { + super(player, options); + + this.addChild("seekButton", { + direction: "back", + seconds: 10, + }); + + this.addChild("BigPlayPauseButton"); + + this.addChild("seekButton", { + direction: "forward", + seconds: 10, + }); + } + + createEl() { + return super.createEl("div", { + className: "vjs-big-button-group", + }); + } +} + +const bigButtons = function (this: VideoJsPlayer) { + this.addChild("BigButtonGroup"); +}; + +// Register the plugin with video.js. +videojs.registerComponent("BigButtonGroup", BigButtonGroup); +videojs.registerComponent("BigPlayPauseButton", BigPlayPauseButton); +videojs.registerPlugin("bigButtons", bigButtons); + +export default bigButtons; diff --git a/ui/v2.5/src/components/ScenePlayer/styles.scss b/ui/v2.5/src/components/ScenePlayer/styles.scss index c500ae549..b2fbc7a8a 100644 --- a/ui/v2.5/src/components/ScenePlayer/styles.scss +++ b/ui/v2.5/src/components/ScenePlayer/styles.scss @@ -35,31 +35,71 @@ $sceneTabWidth: 450px; opacity: 0; } + .vjs-big-button-group { + display: none; + height: 80px; + justify-content: space-around; + opacity: 0; + position: absolute; + top: calc(50% - 40px); + width: 100%; + + .vjs-button { + font-size: 4em; + height: 100%; + width: 80px; + + .vjs-icon-placeholder::before { + height: 100%; + line-height: 80px; + } + } + } + .vjs-touch-enabled { margin: 0 -15px; width: 100vw; - &:hover.vjs-user-active { - .vjs-button { - pointer-events: auto; - } + &.vjs-has-started .vjs-big-button-group { + display: flex; + opacity: 1; + visibility: visible; } - // make controls a little more compact on smaller screens - @media (max-width: 576px) { - .vjs-control-bar { - height: 2.5em; - } + &.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-big-button-group { + opacity: 0; + pointer-events: none; + transition: visibility 1s, opacity 1s; + visibility: visible; + } - .vjs-control-bar .vjs-control:not(.vjs-progress-control) { + .vjs-big-play-pause-button .vjs-icon-placeholder::before { + content: "\f101"; + font-family: VideoJS; + } + + &.vjs-playing .vjs-big-play-pause-button .vjs-icon-placeholder::before { + content: "\f103"; + } + + // hide the regular play/pause button on touch screens + .vjs-play-control { + display: none; + } + + // hide the regular seek buttons on touch screens + .vjs-control-bar .vjs-seek-button { + display: none; + } + } + + // make controls a little more compact on smaller screens + @media (max-width: 576px) { + .vjs-control-bar { + .vjs-control:not(.vjs-progress-control) { width: 2.5em; } - .vjs-time-control { - font-size: 12px; - line-height: 4em; - } - .vjs-button > .vjs-icon-placeholder::before, .vjs-skip-button::before { font-size: 1.5em; @@ -67,6 +107,16 @@ $sceneTabWidth: 450px; } } + .vjs-time-control { + font-size: 12px; + line-height: 4em; + } + + .vjs-big-button-group .vjs-button { + font-size: 2em; + width: 50px; + } + .vjs-current-time { margin-left: 1em; } @@ -83,8 +133,6 @@ $sceneTabWidth: 450px; /* Scales control size */ font-size: 15px; - opacity: 0; - transition: opacity 0.25s cubic-bezier(0, 0, 0.2, 1); &::before { background: linear-gradient( @@ -119,13 +167,6 @@ $sceneTabWidth: 450px; display: none; } - &:hover, - &.vjs-paused { - .vjs-control-bar { - opacity: 1; - } - } - .vjs-progress-control { bottom: 3rem; margin-left: 1%; @@ -445,3 +486,21 @@ $sceneTabWidth: 450px; width: 160px; z-index: 1; } + +.VideoPlayer + .video-js + .vjs-seek-button.skip-back + span.vjs-icon-placeholder::before { + -ms-transform: none; + -webkit-transform: none; + transform: none; +} + +.VideoPlayer + .video-js + .vjs-seek-button.skip-forward + span.vjs-icon-placeholder::before { + -ms-transform: scale(-1, 1); + -webkit-transform: scale(-1, 1); + transform: scale(-1, 1); +}