Create Loop Button and functionality in video player
This commit is contained in:
parent
fda38b1b21
commit
7be4bf28f2
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="20px" height="20px"><path class="loop" d="M12 4V2.21c0-.45-.54-.67-.85-.35l-2.8 2.79c-.2.2-.2.51 0 .71l2.79 2.79c.32.31.86.09.86-.36V6c3.31 0 6 2.69 6 6 0 .79-.15 1.56-.44 2.25-.15.36-.04.77.23 1.04.51.51 1.37.33 1.64-.34.37-.91.57-1.91.57-2.95 0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-.79.15-1.56.44-2.25.15-.36.04-.77-.23-1.04-.51-.51-1.37-.33-1.64.34C4.2 9.96 4 10.96 4 12c0 4.42 3.58 8 8 8v1.79c0 .45.54.67.85.35l2.79-2.79c.2-.2.2-.51 0-.71l-2.79-2.79c-.31-.31-.85-.09-.85.36V18z"/></svg>
|
After Width: | Height: | Size: 577 B |
|
@ -1,4 +1,5 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
import { mapActions } from 'vuex'
|
||||||
import FtCard from '../ft-card/ft-card.vue'
|
import FtCard from '../ft-card/ft-card.vue'
|
||||||
|
|
||||||
import $ from 'jquery'
|
import $ from 'jquery'
|
||||||
|
@ -87,6 +88,7 @@ export default Vue.extend({
|
||||||
'remainingTimeDisplay',
|
'remainingTimeDisplay',
|
||||||
'customControlSpacer',
|
'customControlSpacer',
|
||||||
'playbackRateMenuButton',
|
'playbackRateMenuButton',
|
||||||
|
'loopButton',
|
||||||
'chaptersButton',
|
'chaptersButton',
|
||||||
'descriptionsButton',
|
'descriptionsButton',
|
||||||
'subsCapsButton',
|
'subsCapsButton',
|
||||||
|
@ -156,6 +158,7 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.createFullWindowButton()
|
this.createFullWindowButton()
|
||||||
|
this.createLoopButton()
|
||||||
this.determineFormatType()
|
this.determineFormatType()
|
||||||
this.determineMaxFramerate()
|
this.determineMaxFramerate()
|
||||||
},
|
},
|
||||||
|
@ -533,7 +536,53 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
createFullWindowButton: function() {
|
createLoopButton: function () {
|
||||||
|
const v = this
|
||||||
|
const VjsButton = videojs.getComponent('Button')
|
||||||
|
const loopButton = videojs.extend(VjsButton, {
|
||||||
|
constructor: function(player, options) {
|
||||||
|
VjsButton.call(this, player, options)
|
||||||
|
},
|
||||||
|
handleClick: function() {
|
||||||
|
v.toggleVideoLoop()
|
||||||
|
},
|
||||||
|
createControlTextEl: function (button) {
|
||||||
|
return $(button).html($('<div id="loopButton" class="vjs-icon-loop loop-white vjs-button loopWhite"></div>')
|
||||||
|
.attr('title', 'Toggle Loop'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
videojs.registerComponent('loopButton', loopButton)
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleVideoLoop: async function () {
|
||||||
|
if (!this.player.loop()) {
|
||||||
|
const currentTheme = localStorage.getItem('mainColor')
|
||||||
|
const colorNames = this.$store.state.utils.colorClasses
|
||||||
|
const colorValues = this.$store.state.utils.colorValues
|
||||||
|
|
||||||
|
const nameIndex = colorNames.findIndex((color) => {
|
||||||
|
return color === currentTheme
|
||||||
|
})
|
||||||
|
|
||||||
|
const themeTextColor = await this.calculateColorLuminance(colorValues[nameIndex])
|
||||||
|
|
||||||
|
$('#loopButton').addClass('vjs-icon-loop-active')
|
||||||
|
|
||||||
|
if (themeTextColor === '#000000') {
|
||||||
|
$('#loopButton').addClass('loop-black')
|
||||||
|
$('#loopButton').removeClass('loop-white')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.player.loop(true)
|
||||||
|
} else {
|
||||||
|
$('#loopButton').removeClass('vjs-icon-loop-active')
|
||||||
|
$('#loopButton').removeClass('loop-black')
|
||||||
|
$('#loopButton').addClass('loop-white')
|
||||||
|
this.player.loop(false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
createFullWindowButton: function () {
|
||||||
const v = this
|
const v = this
|
||||||
const VjsButton = videojs.getComponent('Button')
|
const VjsButton = videojs.getComponent('Button')
|
||||||
const fullWindowButton = videojs.extend(VjsButton, {
|
const fullWindowButton = videojs.extend(VjsButton, {
|
||||||
|
@ -827,6 +876,10 @@ export default Vue.extend({
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
...mapActions([
|
||||||
|
'calculateColorLuminance'
|
||||||
|
])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -449,7 +449,6 @@ body.vjs-full-window {
|
||||||
content: url(assets/img/open_fullwindow.svg);
|
content: url(assets/img/open_fullwindow.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.vjs-icon-fullwindow-exit, .video-js.vjs-fullwindow .vjs-fullwindow-control .vjs-icon-placeholder {
|
.vjs-icon-fullwindow-exit, .video-js.vjs-fullwindow .vjs-fullwindow-control .vjs-icon-placeholder {
|
||||||
font-family: VideoJS;
|
font-family: VideoJS;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -459,6 +458,30 @@ body.vjs-full-window {
|
||||||
content: url(assets/img/close_fullwindow.svg);
|
content: url(assets/img/close_fullwindow.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vjs-icon-loop, .video-js .vjs-fullwindow-control .vjs-icon-placeholder {
|
||||||
|
color: white !important;
|
||||||
|
margin-top: 5px !important;
|
||||||
|
padding-top: 5px !important;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vjs-icon-loop-active {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vjs-icon-loop:before, .video-js.vjs-fullwindow .vjs-fullwindow-control .vjs-icon-placeholder:before {
|
||||||
|
content: url(assets/img/loop.svg);
|
||||||
|
/* filter: invert(1) drop-shadow(1px 0px 0px var(--primary-color)); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.loop-black:before {
|
||||||
|
filter: brightness(0%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loop-white:before {
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
|
||||||
.vjs-full-window .video-js.vjs-fullscreen {
|
.vjs-full-window .video-js.vjs-fullscreen {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
Loading…
Reference in New Issue