From 2e2ac6f8703c05f95c4396fc7811f986e246f370 Mon Sep 17 00:00:00 2001 From: Gary Katsevman Date: Fri, 27 Jan 2017 15:08:20 -0500 Subject: [PATCH] refactor: move most volume panel functionality into css state (#3981) --- src/css/_utilities.scss | 1 + src/css/components/_control.scss | 25 ---- src/css/components/_volume.scss | 116 ++++++++++++++++-- .../volume-control/volume-control.js | 65 ++-------- src/js/control-bar/volume-panel.js | 37 ++++-- 5 files changed, 142 insertions(+), 102 deletions(-) diff --git a/src/css/_utilities.scss b/src/css/_utilities.scss index 19a19fc9ea..93df9dc1f3 100644 --- a/src/css/_utilities.scss +++ b/src/css/_utilities.scss @@ -16,6 +16,7 @@ @mixin transition($string: $transition--default) { -webkit-transition: $string; -moz-transition: $string; + -ms-transition: $string; -o-transition: $string; transition: $string; } diff --git a/src/css/components/_control.scss b/src/css/components/_control.scss index d5b11c500b..3e6da44c93 100644 --- a/src/css/components/_control.scss +++ b/src/css/components/_control.scss @@ -35,28 +35,3 @@ display: table-cell; vertical-align: middle; } - -// visually hide a control-bar component without changing the position -// and without hiding it from screen readers. This also preserves -// a transition animation. -.video-js .vjs-control .vjs-visual-hide-vertical { - height: 1px; - margin: 0; - padding: 0; - overflow: hidden; - opacity: 0; -} - -// visually hide a control-bar component without changing the position -// and without hiding it from screen readers. This also preserves -// a transition animation. -.video-js .vjs-control .vjs-visual-hide-horizontal { - width: 1px; - margin: 0; - padding: 0; - overflow: hidden; - opacity: 0; -} - - - diff --git a/src/css/components/_volume.scss b/src/css/components/_volume.scss index bea13ca965..6582e3de16 100644 --- a/src/css/components/_volume.scss +++ b/src/css/components/_volume.scss @@ -2,6 +2,11 @@ cursor: pointer; @include flex(none); @extend .vjs-icon-volume-high; + // padding here is for IE < 9, it doesn't do width: auto from + // another style correctly + padding-left: 2em; + padding-right: 2em; + padding-bottom: 3em; } .video-js .vjs-mute-control.vjs-vol-0 { @@ -14,19 +19,109 @@ @extend .vjs-icon-volume-mid; } - .video-js .vjs-volume-control { - width: auto; margin-right: 1em; - @include flex(none); - @include display-flex(center); - @include transition(all 0.4s); + @include display-flex; +} +.video-js .vjs-volume-control.vjs-volume-horizontal { + width: 5em; +} + +.video-js .vjs-volume-panel .vjs-volume-control { + visibility: visible; + opacity: 0; + width: 1px; + height: 1px; + margin-left: -1px; + +} +.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + & .vjs-volume-bar, + & .vjs-volume-level { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + } } .video-js .vjs-volume-panel { - width: auto; - @include flex(none); - @include display-flex(center); + &:hover .vjs-volume-control, + &:active .vjs-volume-control, + &:focus .vjs-volume-control, + & .vjs-volume-control:hover , + & .vjs-volume-control:active , + & .vjs-volume-control:focus , + & .vjs-mute-control:hover ~ .vjs-volume-control, + & .vjs-mute-control:active ~ .vjs-volume-control, + & .vjs-mute-control:focus ~ .vjs-volume-control, + & .vjs-volume-control.vjs-slider-active { + &.vjs-volume-horizontal { + width: 5em; + height: 3em; + } + + visibility: visible; + opacity: 1; + position: relative; + + &.vjs-volume-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + & .vjs-volume-bar, + & .vjs-volume-level { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + } + } + + $transition-property: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s; + @include transition($transition-property); + } + + &.vjs-volume-panel-horizontal { + &:hover, + &:focus, + &:active, + &.vjs-slider-active { + width: 9em; + + @include transition(width 0.1s); + } + } + + @include transition(width 1s); +} + +.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical { + height: 8em; + width: 3em; + left: -3.5em; + + $transition-property: visibility 1s, opacity 1s, height 1s 1s, width 1s 1s, left 1s 1s, top 1s 1s; + @include transition($transition-property) +} +.video-js .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal { + $transition-property: visibility 1s, opacity 1s, height 1s 1s, width 1s, left 1s 1s, top 1s 1s; + @include transition($transition-property) +} + +.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-horizontal { + width: 5em; + height: 3em; + + visibility: visible; + opacity: 1; + position: relative; + + @include transition(none); +} + +.video-js.vjs-no-flex .vjs-volume-control.vjs-volume-vertical, +.video-js.vjs-no-flex .vjs-volume-panel .vjs-volume-control.vjs-volume-vertical { + position: absolute; + bottom: 3em; + left: 0.5em; +} + +.video-js .vjs-volume-panel { + @include display-flex; } .video-js .vjs-volume-bar { @@ -93,10 +188,9 @@ } .video-js .vjs-volume-vertical { - width: 2.9em; + width: 3em; height: 8em; - bottom: 5.5em; - left: -3.5em; + bottom: 8em; @include background-color-with-alpha($primary-background-color, $primary-background-transparency); } diff --git a/src/js/control-bar/volume-control/volume-control.js b/src/js/control-bar/volume-control/volume-control.js index 69d6408696..a2240b9369 100644 --- a/src/js/control-bar/volume-control/volume-control.js +++ b/src/js/control-bar/volume-control/volume-control.js @@ -40,65 +40,18 @@ class VolumeControl extends Component { checkVolumeSupport(this, player); // while the slider is active (the mouse has been pressed down and - // is dragging) we do not want to hide the VolumeBar - this.on(this.volumeBar, ['slideractive'], () => { + // is dragging) or in focus we do not want to hide the VolumeBar + this.on(this.volumeBar, ['focus', 'slideractive'], () => { this.volumeBar.addClass('vjs-slider-active'); - this.lockShowing_ = true; + this.addClass('vjs-slider-active'); + this.trigger('slideractive'); }); - // when the slider becomes inactive again we want to hide - // the VolumeBar, but only if we tried to hide when - // lockShowing_ was true. see the VolumeBar#hide function. - this.on(this.volumeBar, ['sliderinactive'], () => { + this.on(this.volumeBar, ['blur', 'sliderinactive'], () => { this.volumeBar.removeClass('vjs-slider-active'); - this.lockShowing_ = false; - - if (this.shouldHide_) { - this.hide(); - } + this.removeClass('vjs-slider-active'); + this.trigger('sliderinactive'); }); - - // show/hide the VolumeBar on focus/blur - // happens in VolumeControl but if we want to use the - // VolumeBar by itself we will need this - this.on(this.volumeBar, ['focus'], () => this.show()); - this.on(this.volumeBar, ['blur'], () => this.hide()); - } - - /** - * Remove the visual hidden state from the `VolumeControl`. - */ - show() { - this.shouldHide_ = false; - - if (this.options_.vertical) { - this.removeClass('vjs-visual-hide-vertical'); - } else { - this.removeClass('vjs-visual-hide-horizontal'); - } - - } - - /** - * Hide the `VolumeControl` visually but not from screen-readers unless - * showing is locked (due to the slider being active). If showing is locked - * hide will be called when the slider becomes inactive. - */ - hide() { - // if we are currently locked to the showing state - // don't hide, but store that we should hide when - // lockShowing_ turns to a false value. - if (this.lockShowing_) { - this.shouldHide_ = true; - return; - } - - // animate hiding the bar via transitions - if (this.options_.vertical) { - this.addClass('vjs-visual-hide-vertical'); - } else { - this.addClass('vjs-visual-hide-horizontal'); - } } /** @@ -108,10 +61,10 @@ class VolumeControl extends Component { * The element that was created. */ createEl() { - let orientationClass = 'vjs-volume-horizonal vjs-visual-hide-horizontal'; + let orientationClass = 'vjs-volume-horizontal'; if (this.options_.vertical) { - orientationClass = 'vjs-volume-vertical vjs-visual-hide-vertical'; + orientationClass = 'vjs-volume-vertical'; } return super.createEl('div', { diff --git a/src/js/control-bar/volume-panel.js b/src/js/control-bar/volume-panel.js index b4ca97bce2..471244706c 100644 --- a/src/js/control-bar/volume-panel.js +++ b/src/js/control-bar/volume-panel.js @@ -45,16 +45,33 @@ class VolumePanel extends Component { // hide this control if volume support is missing checkVolumeSupport(this, player); - // when the mouse leaves the VolumePanel area hide the VolumeControl (slider/bar) - this.on(['mouseenter', 'touchstart'], () => this.volumeControl.show()); - this.on(['mouseleave', 'touchend'], () => this.volumeControl.hide()); - - // when any child of the VolumePanel gets or loses focus - // show/hide the VolumeControl (slider/bar) - this.children().forEach((child) => { - this.on(child, ['focus'], () => this.volumeControl.show()); - this.on(child, ['blur'], () => this.volumeControl.hide()); - }); + // while the slider is active (the mouse has been pressed down and + // is dragging) or in focus we do not want to hide the VolumeBar + this.on(this.volumeControl, ['slideractive'], this.sliderActive_); + this.on(this.muteToggle, 'focus', this.sliderActive_); + + this.on(this.volumeControl, ['sliderinactive'], this.sliderInactive_); + this.on(this.muteToggle, 'blur', this.sliderInactive_); + } + + /** + * Add vjs-slider-active class to the VolumePanel + * + * @listens VolumeControl#slideractive + * @private + */ + sliderActive_() { + this.addClass('vjs-slider-active'); + } + + /** + * Removes vjs-slider-active class to the VolumePanel + * + * @listens VolumeControl#sliderinactive + * @private + */ + sliderInactive_() { + this.removeClass('vjs-slider-active'); } /**