Started using custom video controls

This commit is contained in:
Eduard Urbach 2018-12-07 09:54:17 +09:00
parent da716fc3aa
commit 11865a6500
13 changed files with 126 additions and 54 deletions

View File

@ -9,10 +9,17 @@ component AMVMini(amv *arn.AMV, user *arn.User)
AMVMiniFooter(amv, user)
component AMVVideo(amv *arn.AMV)
.video-container
video.video.lazy(controls, controlsList="nodownload")
.video-container(id=amv.ID)
video.video.media-play-area.lazy.action(data-action="playVideo", data-trigger="click", data-media-id=amv.ID)
source(data-src="https://notify.moe/videos/amvs/" + amv.File, data-type="video/webm")
//- button.media-play-button
//- RawIcon("play")
.video-controls
button.video-control.action(data-action="toggleFullscreen", data-trigger="click", data-id=amv.ID)
RawIcon("square-o")
component AMVFooter(amv *arn.AMV, user *arn.User)
.amv-footer
if amv.Title.ByUser(user) == ""

View File

@ -19,12 +19,13 @@ component SoundTrackContent(track *arn.SoundTrack, user *arn.User)
component SoundTrackMedia(track *arn.SoundTrack)
if track.File != "" && track.HasMediaByService("Youtube")
.soundtrack-media
.soundtrack-play-area.action(data-action="toggleAudio", data-trigger="click", data-audio-src="https://notify.moe/audio/" + track.File, data-soundtrack-id=track.ID)
img.soundtrack-image.lazy(data-src="https://img.youtube.com/vi/" + track.MediaByService("Youtube")[0].ServiceID + "/0.jpg", alt=track.Title)
button.soundtrack-play-button
.media-play-area.action(data-action="toggleAudio", data-trigger="click", data-audio-src="https://notify.moe/audio/" + track.File, data-media-id=track.ID)
img.media-image.lazy(data-src="https://img.youtube.com/vi/" + track.MediaByService("Youtube")[0].ServiceID + "/0.jpg", alt=track.Title)
button.media-play-button
RawIcon("play")
.soundtrack-visualizer
.media-visualizer
.visualizer-box.visualizer-box-1
.visualizer-box.visualizer-box-2
.visualizer-box.visualizer-box-3

View File

@ -24,7 +24,7 @@
min-height 112px
height 112px
.soundtrack-play-button
.media-play-button
width 48px
height 48px
font-size 1rem

View File

@ -17,7 +17,7 @@ component SoundTrackPage(track *arn.SoundTrack, user *arn.User)
if user != nil && media.Service == "Youtube" && track.File != ""
.buttons
button.action(data-action="playAudio", data-trigger="click", data-audio-src="/audio/" + track.File, data-soundtrack-id=track.ID)
button.action(data-action="playAudio", data-trigger="click", data-audio-src="/audio/" + track.File, data-media-id=track.ID)
Icon("play")
span Play in background

View File

@ -31,7 +31,7 @@ const soundtrack-margin = 1rem
iframe
width 100%
.soundtrack-image
.media-image
object-fit cover
width 100%
height 100%
@ -39,7 +39,7 @@ const soundtrack-margin = 1rem
filter brightness(100%)
transition filter transition-speed ease
.soundtrack-play-button
.media-play-button
position absolute
top 50%
left 50%
@ -56,7 +56,7 @@ const soundtrack-margin = 1rem
.icon-play
transform translateX(27%)
.soundtrack-visualizer
.media-visualizer
horizontal
justify-content center
align-items center
@ -101,33 +101,6 @@ animation change-color
100%
background-color hsl(235, 100%, 68%)
.soundtrack-play-area
position absolute
top 0
left 0
width 100%
height 100%
cursor pointer
transition opacity 250ms ease
&.playing
.soundtrack-play-button
opacity 0
.soundtrack-visualizer
opacity 1
.soundtrack-image
filter brightness(0) !important
:hover
.soundtrack-play-button
color button-hover-color
background button-hover-background
.soundtrack-image
filter brightness(50%)
.soundtrack-footer
media-footer
@ -142,7 +115,7 @@ animation change-color
border-bottom-right-radius 0
border-top-right-radius 0
.soundtrack-image
.media-image
border-bottom-left-radius 0
border-top-left-radius 0

View File

@ -2,7 +2,7 @@ import AnimeNotifier from "../AnimeNotifier"
// Play audio
export function playAudio(arn: AnimeNotifier, element: HTMLElement) {
arn.audioPlayer.play(element.dataset.soundtrackId, element.dataset.audioSrc)
arn.audioPlayer.play(element.dataset.mediaId, element.dataset.audioSrc)
}
// Pause audio
@ -45,7 +45,7 @@ export function playPauseAudio(arn: AnimeNotifier) {
export function toggleAudio(arn: AnimeNotifier, element: HTMLElement) {
// If we're clicking on the same track again, stop playing.
// Otherwise, start the track we clicked on.
if(arn.currentSoundTrackId && element.dataset.soundtrackId === arn.currentSoundTrackId) {
if(arn.currentMediaId && element.dataset.mediaId === arn.currentMediaId) {
stopAudio(arn)
} else {
playAudio(arn, element)

View File

@ -1,5 +1,5 @@
import AnimeNotifier from "../AnimeNotifier"
import Diff from "scripts/Diff";
import Diff from "scripts/Diff"
// Follow user
export async function followUser(arn: AnimeNotifier, element: HTMLElement) {

37
scripts/Actions/Video.ts Normal file
View File

@ -0,0 +1,37 @@
import AnimeNotifier from "../AnimeNotifier"
// Play video
export function playVideo(arn: AnimeNotifier, video: HTMLVideoElement) {
video.volume = arn.audioPlayer.volume
if(video.readyState >= 2) {
togglePlayVideo(video)
return
}
video.load()
video.addEventListener("loadeddata", () => {
togglePlayVideo(video)
})
}
function togglePlayVideo(video: HTMLVideoElement) {
if(video.paused) {
video.play()
} else {
video.pause()
}
}
// Toggle fullscreen
export function toggleFullscreen(arn: AnimeNotifier, button: HTMLElement) {
let elementId = button.dataset.id
let element = document.getElementById(elementId)
if(document.fullscreen) {
document.exitFullscreen()
} else {
element.requestFullscreen()
}
}

View File

@ -20,3 +20,4 @@ export * from "./SideBar"
export * from "./StatusMessage"
export * from "./Theme"
export * from "./Upload"
export * from "./Video"

View File

@ -34,7 +34,7 @@ export default class AnimeNotifier {
isLoading: boolean
diffCompletedForCurrentPath: boolean
lastReloadContentPath: string
currentSoundTrackId: string
currentMediaId: string
serverEvents: ServerEvents
constructor(app: Application) {
@ -160,7 +160,7 @@ export default class AnimeNotifier {
Promise.resolve().then(() => this.displayLocalDates()),
Promise.resolve().then(() => this.setSelectBoxValue()),
Promise.resolve().then(() => this.textAreaFocus()),
Promise.resolve().then(() => this.markPlayingSoundTrack()),
Promise.resolve().then(() => this.markPlayingMedia()),
Promise.resolve().then(() => this.assignActions()),
Promise.resolve().then(() => this.updatePushUI()),
Promise.resolve().then(() => this.dragAndDrop()),
@ -639,9 +639,9 @@ export default class AnimeNotifier {
}
}
markPlayingSoundTrack() {
for(let element of findAll("soundtrack-play-area")) {
if(element.dataset.soundtrackId === this.currentSoundTrackId) {
markPlayingMedia() {
for(let element of findAll("media-play-area")) {
if(element.dataset.mediaId === this.currentMediaId) {
element.classList.add("playing")
}
}
@ -893,7 +893,7 @@ export default class AnimeNotifier {
lazyLoadVideo(video: HTMLVideoElement) {
// Once the video becomes visible, load it
video["became visible"] = () => {
video.pause()
// video.pause()
// Prevent context menu
video.addEventListener("contextmenu", e => e.preventDefault())
@ -907,11 +907,16 @@ export default class AnimeNotifier {
element.src = element.dataset.src
modified = true
}
if(element.type !== element.dataset.type) {
element.type = element.dataset.type
modified = true
}
}
if(modified) {
Diff.mutations.queue(() => {
video.load()
// video.load()
video.classList.add("element-found")
})
}

View File

@ -63,8 +63,8 @@ export default class AudioPlayer {
// Stop current track
this.stop()
this.arn.currentSoundTrackId = trackId
this.arn.markPlayingSoundTrack()
this.arn.currentMediaId = trackId
this.arn.markPlayingMedia()
this.arn.loading(true)
// Mark as loading
@ -187,7 +187,7 @@ export default class AudioPlayer {
// Stop
stop() {
this.arn.currentSoundTrackId = undefined
this.arn.currentMediaId = undefined
// Remove CSS class "playing"
let playingElements = document.getElementsByClassName("playing")
@ -242,6 +242,8 @@ export default class AudioPlayer {
// Set volume
setVolume(volume: number) {
this.volume = volume
if(!this.gainNode) {
return
}

26
styles/media.scarlet Normal file
View File

@ -0,0 +1,26 @@
.media-play-area
position absolute
top 0
left 0
width 100%
height 100%
cursor pointer
transition opacity 250ms ease
&.playing
.media-play-button
opacity 0
.media-visualizer
opacity 1
.media-image
filter brightness(0) !important
:hover
.media-play-button
color button-hover-color
background button-hover-background
.media-image
filter brightness(50%)

View File

@ -8,6 +8,10 @@ const video-padding = 56.25%
border-radius ui-element-border-radius
overflow hidden
:hover
.video-controls
opacity 1
.video
position absolute
width 100%
@ -15,3 +19,19 @@ const video-padding = 56.25%
left 0
top 0
background-color black
.video-controls
position absolute
bottom 1rem
right 1rem
opacity 0
default-transition
.video-control
background transparent
border none
color white
font-size 1.2rem
::-webkit-media-controls
display none !important