From 059bbec1cfc00103078f0985aac207621354a4e9 Mon Sep 17 00:00:00 2001 From: alesmaye Date: Mon, 19 Aug 2024 14:48:15 +0200 Subject: [PATCH 1/6] button interaction --- src/scss/skin-super-modern/components/_button.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/scss/skin-super-modern/components/_button.scss b/src/scss/skin-super-modern/components/_button.scss index 108a574ed..2f2668a4c 100644 --- a/src/scss/skin-super-modern/components/_button.scss +++ b/src/scss/skin-super-modern/components/_button.scss @@ -3,6 +3,7 @@ %ui-button { @extend %ui-component; + transition: transform 0.15s ease; background-color: transparent; background-origin: content-box; background-position: center; @@ -36,6 +37,10 @@ } } + &:active { + transform: scale(0.9); + } + @include hidden; @include focusable; } From b6f5a0fd83e2140e7d463f6fa0dce23d51a86573 Mon Sep 17 00:00:00 2001 From: alesmaye Date: Mon, 19 Aug 2024 15:16:10 +0200 Subject: [PATCH 2/6] button style changes --- src/scss/skin-super-modern/_mixins.scss | 6 +--- .../components/_settingstogglebutton.scss | 6 ---- .../_smallcenteredplaybacktogglebutton.scss | 35 ++----------------- 3 files changed, 3 insertions(+), 44 deletions(-) diff --git a/src/scss/skin-super-modern/_mixins.scss b/src/scss/skin-super-modern/_mixins.scss index 2e8ac6d34..7bf444b62 100644 --- a/src/scss/skin-super-modern/_mixins.scss +++ b/src/scss/skin-super-modern/_mixins.scss @@ -120,11 +120,7 @@ } @mixin svg-icon-shadow { - filter: drop-shadow(0 0 1px $color-primary); -} - -@mixin svg-icon-on-shadow { - filter: drop-shadow(0 0 1px $color-highlight); + filter: drop-shadow(0 0 .25px $color-primary); } @mixin seekbar-position-marker($marker-dimension) { diff --git a/src/scss/skin-super-modern/components/_settingstogglebutton.scss b/src/scss/skin-super-modern/components/_settingstogglebutton.scss index be3d494bc..889daaa23 100644 --- a/src/scss/skin-super-modern/components/_settingstogglebutton.scss +++ b/src/scss/skin-super-modern/components/_settingstogglebutton.scss @@ -7,12 +7,6 @@ &:hover { @include svg-icon-shadow; } - - &.#{$prefix}-on { - &:hover { - @include svg-icon-on-shadow; - } - } } .#{$prefix}-ui-settingstogglebutton { diff --git a/src/scss/skin-super-modern/components/_smallcenteredplaybacktogglebutton.scss b/src/scss/skin-super-modern/components/_smallcenteredplaybacktogglebutton.scss index efabe66da..0f0491872 100644 --- a/src/scss/skin-super-modern/components/_smallcenteredplaybacktogglebutton.scss +++ b/src/scss/skin-super-modern/components/_smallcenteredplaybacktogglebutton.scss @@ -3,39 +3,8 @@ .#{$prefix}-ui-smallcenteredplaybacktogglebutton { @extend %ui-button; - @keyframes #{$prefix}-fade-out { - from { - opacity: 1; - visibility: visible; - } - - to { - opacity: 0; - transform: scale(2); - visibility: hidden; - } - } - - @keyframes #{$prefix}-fade-in { - from { - opacity: 0; - transform: scale(2); - visibility: visible; - } - - to { - opacity: 1; - } - } - - @keyframes #{$prefix}-breathe { - 30% { - transform: scale(1.1); - } - - 60% { - transform: scale(1); - } + &:hover { + @include svg-icon-shadow; } cursor: default; From 67697a8d8d84cfacd1e2f6c618c22bd1e736febe Mon Sep 17 00:00:00 2001 From: alesmaye Date: Thu, 22 Aug 2024 12:32:02 +0200 Subject: [PATCH 3/6] seek animation works but without label with seeked seconds --- .../components/_touch-control-overlay.scss | 35 +++++++++++++++++++ src/ts/components/touchcontroloverlay.ts | 12 +++++++ 2 files changed, 47 insertions(+) diff --git a/src/scss/skin-super-modern/components/_touch-control-overlay.scss b/src/scss/skin-super-modern/components/_touch-control-overlay.scss index 7d7a526f7..376fe1c61 100644 --- a/src/scss/skin-super-modern/components/_touch-control-overlay.scss +++ b/src/scss/skin-super-modern/components/_touch-control-overlay.scss @@ -1,6 +1,21 @@ @import '../variables'; @import '../mixins'; +%seek-circle { + content: ''; + position: absolute; + height: 200%; + width: 100%; + background-color: rgba(156, 156, 156, .35); + border-radius: 50%; + opacity: 0; + -webkit-transition: opacity .2s ease; + -moz-transition: opacity .2s ease; + -ms-transition: opacity .2s ease; + -o-transition: opacity .2s ease; + transition: opacity .2s ease-out; +} + .#{$prefix}-ui-touchcontrol-overlay { @extend %ui-container; @include layout-cover; @@ -9,4 +24,24 @@ display: flex; justify-content: center; text-align: center; + + &::before { + @extend %seek-circle; + left: -60%; + } + &::after { + @extend %seek-circle; + right: -60%; + } + + &.#{$prefix}-seek-forward { + &::after { + opacity: 1; + } + } + &.#{$prefix}-seek-backward { + &::before { + opacity: 1; + } + } } diff --git a/src/ts/components/touchcontroloverlay.ts b/src/ts/components/touchcontroloverlay.ts index 76c599dd8..65a686365 100644 --- a/src/ts/components/touchcontroloverlay.ts +++ b/src/ts/components/touchcontroloverlay.ts @@ -46,6 +46,8 @@ interface ClickPosition { * Overlays the player and detects touch input */ export class TouchControlOverlay extends Container { + private readonly SEEK_FORWARD_CLASS = 'seek-forward'; + private readonly SEEK_BACKWARD_CLASS = 'seek-backward'; private touchControlEvents = { onSingleClick: new EventDispatcher(), @@ -83,6 +85,7 @@ export class TouchControlOverlay extends Container { this.doubleTapTimeout = new Timeout(500, () => { this.couldBeDoubleTapping = false; + this.removeSeekCssClasses(); }); uimanager.onControlsHide.subscribe(() => { @@ -98,11 +101,15 @@ export class TouchControlOverlay extends Container { this.touchControlEvents.onSeekBackward.subscribe(() => { playerSeekTime -= this.config.seekTime; player.seek(playerSeekTime); + this.getDomElement().removeClass(this.prefixCss(this.SEEK_FORWARD_CLASS)); + this.getDomElement().addClass(this.prefixCss(this.SEEK_BACKWARD_CLASS)); }); this.touchControlEvents.onSeekForward.subscribe(() => { playerSeekTime += this.config.seekTime; player.seek(playerSeekTime); + this.getDomElement().removeClass(this.prefixCss(this.SEEK_BACKWARD_CLASS)); + this.getDomElement().addClass(this.prefixCss(this.SEEK_FORWARD_CLASS)); }); this.touchControlEvents.onSingleClick.subscribe((_, e) => { @@ -158,6 +165,11 @@ export class TouchControlOverlay extends Container { }; } + private removeSeekCssClasses(): void { + this.getDomElement().removeClass(this.prefixCss(this.SEEK_FORWARD_CLASS)); + this.getDomElement().removeClass(this.prefixCss(this.SEEK_BACKWARD_CLASS)); + } + protected onDoubleClickEvent(e: Event) { this.touchControlEvents.onDoubleClick.dispatch(this, e); } From aa866506c5b0f6188a7fd1ba755b92bc0a564812 Mon Sep 17 00:00:00 2001 From: alesmaye Date: Thu, 22 Aug 2024 16:38:09 +0200 Subject: [PATCH 4/6] seeking time label and linter fixes --- .../_skin-modern-smallscreen.scss | 1 - src/scss/skin-super-modern/_variables.scss | 2 + .../skin-super-modern/components/_button.scss | 4 +- .../_smallcenteredplaybacktogglebutton.scss | 8 +-- .../components/_touch-control-overlay.scss | 59 ++++++++++++++++--- src/ts/components/touchcontroloverlay.ts | 33 +++++++++-- 6 files changed, 85 insertions(+), 22 deletions(-) diff --git a/src/scss/skin-super-modern/_skin-modern-smallscreen.scss b/src/scss/skin-super-modern/_skin-modern-smallscreen.scss index 75c238aac..18460ee0c 100644 --- a/src/scss/skin-super-modern/_skin-modern-smallscreen.scss +++ b/src/scss/skin-super-modern/_skin-modern-smallscreen.scss @@ -2,7 +2,6 @@ @import 'mixins'; &.#{$prefix}-ui-skin-modern-smallscreen { - font-size: 1.2em; .#{$prefix}-ui-fullscreentogglebutton { background-image: url('../../assets/skin-super-modern/images/fullscreensmall.svg'); diff --git a/src/scss/skin-super-modern/_variables.scss b/src/scss/skin-super-modern/_variables.scss index bba9b643f..d2561e963 100644 --- a/src/scss/skin-super-modern/_variables.scss +++ b/src/scss/skin-super-modern/_variables.scss @@ -15,6 +15,8 @@ $color-focus: #1b7fcc; $color-item-hover: #54565a !default; $color-background-menu: #212226 !default; +$color-background-seek-circle: rgba(124, 124, 124, .3) !default; +$color-shadow-seek-label: 0 0 30px 0 rgba(0, 0, 0, .75) !default; $font-family: sans-serif !default; $font-size: 1em !default; diff --git a/src/scss/skin-super-modern/components/_button.scss b/src/scss/skin-super-modern/components/_button.scss index 2f2668a4c..5da696ccd 100644 --- a/src/scss/skin-super-modern/components/_button.scss +++ b/src/scss/skin-super-modern/components/_button.scss @@ -3,7 +3,6 @@ %ui-button { @extend %ui-component; - transition: transform 0.15s ease; background-color: transparent; background-origin: content-box; background-position: center; @@ -16,6 +15,7 @@ height: 1.5em; min-width: 1.5em; padding: .25em; + transition: transform .15s ease; .#{$prefix}-label { color: $color-primary; @@ -38,7 +38,7 @@ } &:active { - transform: scale(0.9); + transform: scale(.9); } @include hidden; diff --git a/src/scss/skin-super-modern/components/_smallcenteredplaybacktogglebutton.scss b/src/scss/skin-super-modern/components/_smallcenteredplaybacktogglebutton.scss index 0f0491872..f63de66a5 100644 --- a/src/scss/skin-super-modern/components/_smallcenteredplaybacktogglebutton.scss +++ b/src/scss/skin-super-modern/components/_smallcenteredplaybacktogglebutton.scss @@ -3,16 +3,16 @@ .#{$prefix}-ui-smallcenteredplaybacktogglebutton { @extend %ui-button; - &:hover { - @include svg-icon-shadow; - } - cursor: default; height: 2.5em; outline: none; overflow: hidden; // hide overflow from scale animation width: 2.5em; + &:hover { + @include svg-icon-shadow; + } + .#{$prefix}-image { background-position: center; background-repeat: no-repeat; diff --git a/src/scss/skin-super-modern/components/_touch-control-overlay.scss b/src/scss/skin-super-modern/components/_touch-control-overlay.scss index 376fe1c61..7e30a6d39 100644 --- a/src/scss/skin-super-modern/components/_touch-control-overlay.scss +++ b/src/scss/skin-super-modern/components/_touch-control-overlay.scss @@ -1,19 +1,34 @@ @import '../variables'; @import '../mixins'; +// sass-lint:disable no-vendor-prefixes +%opacity-transition { + -moz-transition: opacity .25s ease; + -ms-transition: opacity .25s ease; + -o-transition: opacity .25s ease; + -webkit-transition: opacity .25s ease; + transition: opacity .25s ease-out; +} + %seek-circle { + @extend %opacity-transition; + background-color: $color-background-seek-circle; + border-radius: 50%; content: ''; - position: absolute; height: 200%; - width: 100%; - background-color: rgba(156, 156, 156, .35); - border-radius: 50%; opacity: 0; - -webkit-transition: opacity .2s ease; - -moz-transition: opacity .2s ease; - -ms-transition: opacity .2s ease; - -o-transition: opacity .2s ease; - transition: opacity .2s ease-out; + position: absolute; + width: 100%; +} + +%seek-label { + @extend %opacity-transition; + font-size: .4em; + font-weight: 600; + margin: 0; + opacity: 1; + position: absolute; + text-shadow: $color-shadow-seek-label; } .#{$prefix}-ui-touchcontrol-overlay { @@ -25,10 +40,35 @@ justify-content: center; text-align: center; + // sass-lint:disable nesting-depth + > .#{$prefix}-container-wrapper { + align-items: center; + display: flex; + + .#{$prefix}-seek-forward-label { + @extend %seek-label; + right: 15%; + + &.#{$prefix}-hidden { + opacity: 0; + } + } + + .#{$prefix}-seek-backward-label { + @extend %seek-label; + left: 15%; + + &.#{$prefix}-hidden { + opacity: 0; + } + } + } + &::before { @extend %seek-circle; left: -60%; } + &::after { @extend %seek-circle; right: -60%; @@ -39,6 +79,7 @@ opacity: 1; } } + &.#{$prefix}-seek-backward { &::before { opacity: 1; diff --git a/src/ts/components/touchcontroloverlay.ts b/src/ts/components/touchcontroloverlay.ts index 65a686365..ef34aab6e 100644 --- a/src/ts/components/touchcontroloverlay.ts +++ b/src/ts/components/touchcontroloverlay.ts @@ -5,6 +5,8 @@ import { UIInstanceManager } from '../uimanager'; import { EventDispatcher, NoArgs, Event as EDEvent } from '../eventdispatcher'; import { Timeout } from '../timeout'; import { HTMLElementWithComponent } from '../dom'; +import { Label, LabelConfig } from './label'; +import { i18n } from '../main'; export interface TouchControlOverlayConfig extends ContainerConfig { /** @@ -57,6 +59,8 @@ export class TouchControlOverlay extends Container { }; private playbackToggleButton: SmallCenteredPlaybackToggleButton; + private seekForwardLabel: Label; + private seekBackwardLabel: Label; // true if the last tap on the overlay was less than 500msec ago private couldBeDoubleTapping: Boolean; @@ -71,21 +75,28 @@ export class TouchControlOverlay extends Container { enterFullscreenOnInitialPlayback: Boolean(config.enterFullscreenOnInitialPlayback), }); + this.seekForwardLabel = new Label({text: '', for: this.getConfig().id, cssClass: 'seek-forward-label', hidden: true}); + this.seekBackwardLabel = new Label({text: '', for: this.getConfig().id, cssClass: 'seek-backward-label', hidden: true}); + this.config = this.mergeConfig(config, { cssClass: 'ui-touchcontrol-overlay', acceptsTouchWithUiHidden: true, seekTime: 10, seekDoubleTapMargin: 15, - components: [this.playbackToggleButton], + components: [this.playbackToggleButton, this.seekForwardLabel, this.seekBackwardLabel], }, this.config); } configure(player: PlayerAPI, uimanager: UIInstanceManager): void { super.configure(player, uimanager); + let playerSeekTime = 0; + let startSeekTime = 0; + this.doubleTapTimeout = new Timeout(500, () => { this.couldBeDoubleTapping = false; - this.removeSeekCssClasses(); + startSeekTime = 0; + setTimeout(() => this.hideSeekAnimationElements(), 150); }); uimanager.onControlsHide.subscribe(() => { @@ -96,25 +107,33 @@ export class TouchControlOverlay extends Container { this.playbackToggleButton.show(); }); - let playerSeekTime = 0; this.touchControlEvents.onSeekBackward.subscribe(() => { playerSeekTime -= this.config.seekTime; player.seek(playerSeekTime); - this.getDomElement().removeClass(this.prefixCss(this.SEEK_FORWARD_CLASS)); + + this.seekBackwardLabel.setText(Math.abs(Math.round(playerSeekTime - startSeekTime)) + ' ' + i18n.performLocalization(i18n.getLocalizer('settings.time.seconds'))); + this.seekBackwardLabel.show(); this.getDomElement().addClass(this.prefixCss(this.SEEK_BACKWARD_CLASS)); + this.seekForwardLabel.hide(); + this.getDomElement().removeClass(this.prefixCss(this.SEEK_FORWARD_CLASS)); }); this.touchControlEvents.onSeekForward.subscribe(() => { playerSeekTime += this.config.seekTime; player.seek(playerSeekTime); - this.getDomElement().removeClass(this.prefixCss(this.SEEK_BACKWARD_CLASS)); + + this.seekForwardLabel.setText(Math.abs(Math.round(playerSeekTime - startSeekTime)) + ' ' + i18n.performLocalization(i18n.getLocalizer('settings.time.seconds'))); + this.seekForwardLabel.show(); this.getDomElement().addClass(this.prefixCss(this.SEEK_FORWARD_CLASS)); + this.seekBackwardLabel.hide(); + this.getDomElement().removeClass(this.prefixCss(this.SEEK_BACKWARD_CLASS)); }); this.touchControlEvents.onSingleClick.subscribe((_, e) => { uimanager.getUI().toggleUiShown(); playerSeekTime = player.getCurrentTime(); + startSeekTime = playerSeekTime; const eventTarget = (e as Event).target as HTMLElementWithComponent; const rect = eventTarget.getBoundingClientRect(); @@ -165,9 +184,11 @@ export class TouchControlOverlay extends Container { }; } - private removeSeekCssClasses(): void { + private hideSeekAnimationElements(): void { this.getDomElement().removeClass(this.prefixCss(this.SEEK_FORWARD_CLASS)); this.getDomElement().removeClass(this.prefixCss(this.SEEK_BACKWARD_CLASS)); + this.seekForwardLabel.hide(); + this.seekBackwardLabel.hide(); } protected onDoubleClickEvent(e: Event) { From 3726b9ba28ac36fa6f7734be212e8b05f8238cfb Mon Sep 17 00:00:00 2001 From: alesmaye Date: Thu, 22 Aug 2024 17:07:35 +0200 Subject: [PATCH 5/6] updated color --- src/scss/skin-super-modern/_variables.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scss/skin-super-modern/_variables.scss b/src/scss/skin-super-modern/_variables.scss index d2561e963..2430b3625 100644 --- a/src/scss/skin-super-modern/_variables.scss +++ b/src/scss/skin-super-modern/_variables.scss @@ -15,7 +15,7 @@ $color-focus: #1b7fcc; $color-item-hover: #54565a !default; $color-background-menu: #212226 !default; -$color-background-seek-circle: rgba(124, 124, 124, .3) !default; +$color-background-seek-circle: rgba(124, 124, 124, .35) !default; $color-shadow-seek-label: 0 0 30px 0 rgba(0, 0, 0, .75) !default; $font-family: sans-serif !default; From ac72a2cd389cbd1b5f12140fd5a5e3adccbfb1d0 Mon Sep 17 00:00:00 2001 From: alesmaye Date: Tue, 27 Aug 2024 12:15:45 +0200 Subject: [PATCH 6/6] fixed import --- src/ts/components/touchcontroloverlay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/components/touchcontroloverlay.ts b/src/ts/components/touchcontroloverlay.ts index ef34aab6e..461627fa7 100644 --- a/src/ts/components/touchcontroloverlay.ts +++ b/src/ts/components/touchcontroloverlay.ts @@ -6,7 +6,7 @@ import { EventDispatcher, NoArgs, Event as EDEvent } from '../eventdispatcher'; import { Timeout } from '../timeout'; import { HTMLElementWithComponent } from '../dom'; import { Label, LabelConfig } from './label'; -import { i18n } from '../main'; +import { i18n } from '../localization/i18n'; export interface TouchControlOverlayConfig extends ContainerConfig { /**