mirror of
https://github.com/videojs/video.js.git
synced 2024-12-14 11:23:30 +02:00
refactor: move most volume panel functionality into css state (#3981)
This commit is contained in:
parent
4979ea78d5
commit
2e2ac6f870
@ -16,6 +16,7 @@
|
|||||||
@mixin transition($string: $transition--default) {
|
@mixin transition($string: $transition--default) {
|
||||||
-webkit-transition: $string;
|
-webkit-transition: $string;
|
||||||
-moz-transition: $string;
|
-moz-transition: $string;
|
||||||
|
-ms-transition: $string;
|
||||||
-o-transition: $string;
|
-o-transition: $string;
|
||||||
transition: $string;
|
transition: $string;
|
||||||
}
|
}
|
||||||
|
@ -35,28 +35,3 @@
|
|||||||
display: table-cell;
|
display: table-cell;
|
||||||
vertical-align: middle;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@include flex(none);
|
@include flex(none);
|
||||||
@extend .vjs-icon-volume-high;
|
@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 {
|
.video-js .vjs-mute-control.vjs-vol-0 {
|
||||||
@ -14,19 +19,109 @@
|
|||||||
@extend .vjs-icon-volume-mid;
|
@extend .vjs-icon-volume-mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.video-js .vjs-volume-control {
|
.video-js .vjs-volume-control {
|
||||||
width: auto;
|
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
@include flex(none);
|
@include display-flex;
|
||||||
@include display-flex(center);
|
}
|
||||||
@include transition(all 0.4s);
|
.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 {
|
.video-js .vjs-volume-panel {
|
||||||
width: auto;
|
&:hover .vjs-volume-control,
|
||||||
@include flex(none);
|
&:active .vjs-volume-control,
|
||||||
@include display-flex(center);
|
&: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 {
|
.video-js .vjs-volume-bar {
|
||||||
@ -93,10 +188,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.video-js .vjs-volume-vertical {
|
.video-js .vjs-volume-vertical {
|
||||||
width: 2.9em;
|
width: 3em;
|
||||||
height: 8em;
|
height: 8em;
|
||||||
bottom: 5.5em;
|
bottom: 8em;
|
||||||
left: -3.5em;
|
|
||||||
|
|
||||||
@include background-color-with-alpha($primary-background-color, $primary-background-transparency);
|
@include background-color-with-alpha($primary-background-color, $primary-background-transparency);
|
||||||
}
|
}
|
||||||
|
@ -40,65 +40,18 @@ class VolumeControl extends Component {
|
|||||||
checkVolumeSupport(this, player);
|
checkVolumeSupport(this, player);
|
||||||
|
|
||||||
// while the slider is active (the mouse has been pressed down and
|
// while the slider is active (the mouse has been pressed down and
|
||||||
// is dragging) we do not want to hide the VolumeBar
|
// is dragging) or in focus we do not want to hide the VolumeBar
|
||||||
this.on(this.volumeBar, ['slideractive'], () => {
|
this.on(this.volumeBar, ['focus', 'slideractive'], () => {
|
||||||
this.volumeBar.addClass('vjs-slider-active');
|
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
|
this.on(this.volumeBar, ['blur', 'sliderinactive'], () => {
|
||||||
// the VolumeBar, but only if we tried to hide when
|
|
||||||
// lockShowing_ was true. see the VolumeBar#hide function.
|
|
||||||
this.on(this.volumeBar, ['sliderinactive'], () => {
|
|
||||||
this.volumeBar.removeClass('vjs-slider-active');
|
this.volumeBar.removeClass('vjs-slider-active');
|
||||||
this.lockShowing_ = false;
|
this.removeClass('vjs-slider-active');
|
||||||
|
this.trigger('sliderinactive');
|
||||||
if (this.shouldHide_) {
|
|
||||||
this.hide();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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.
|
* The element that was created.
|
||||||
*/
|
*/
|
||||||
createEl() {
|
createEl() {
|
||||||
let orientationClass = 'vjs-volume-horizonal vjs-visual-hide-horizontal';
|
let orientationClass = 'vjs-volume-horizontal';
|
||||||
|
|
||||||
if (this.options_.vertical) {
|
if (this.options_.vertical) {
|
||||||
orientationClass = 'vjs-volume-vertical vjs-visual-hide-vertical';
|
orientationClass = 'vjs-volume-vertical';
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.createEl('div', {
|
return super.createEl('div', {
|
||||||
|
@ -45,16 +45,33 @@ class VolumePanel extends Component {
|
|||||||
// hide this control if volume support is missing
|
// hide this control if volume support is missing
|
||||||
checkVolumeSupport(this, player);
|
checkVolumeSupport(this, player);
|
||||||
|
|
||||||
// when the mouse leaves the VolumePanel area hide the VolumeControl (slider/bar)
|
// while the slider is active (the mouse has been pressed down and
|
||||||
this.on(['mouseenter', 'touchstart'], () => this.volumeControl.show());
|
// is dragging) or in focus we do not want to hide the VolumeBar
|
||||||
this.on(['mouseleave', 'touchend'], () => this.volumeControl.hide());
|
this.on(this.volumeControl, ['slideractive'], this.sliderActive_);
|
||||||
|
this.on(this.muteToggle, 'focus', this.sliderActive_);
|
||||||
|
|
||||||
// when any child of the VolumePanel gets or loses focus
|
this.on(this.volumeControl, ['sliderinactive'], this.sliderInactive_);
|
||||||
// show/hide the VolumeControl (slider/bar)
|
this.on(this.muteToggle, 'blur', this.sliderInactive_);
|
||||||
this.children().forEach((child) => {
|
}
|
||||||
this.on(child, ['focus'], () => this.volumeControl.show());
|
|
||||||
this.on(child, ['blur'], () => this.volumeControl.hide());
|
/**
|
||||||
});
|
* 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');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user