分离控制器功能

This commit is contained in:
Harvey Zack committed 2018-11-06 09:57:30 +08:00
1 parent 851303e530
commit ca7e24a525
21 files changed
+539 -487

No files matched your search

-49
View File
@@ -1,49 +0,0 @@
import { append, tooltip, setStyle } from '../utils';
import icons from '../icons';
export default class FullscreenWeb {
constructor(option) {
this.option = option;
this.state = false;
}
apply(art, $control) {
this.art = art;
const { events: { proxy }, i18n, player, controls } = art;
this.$fullscreenWeb = append($control, icons.fullscreenWeb);
tooltip(this.$fullscreenWeb, i18n.get('Web fullscreen'));
proxy($control, 'click', () => {
if (controls.fullscreen && controls.fullscreen.state) {
controls.fullscreen.exit();
}
this.toggle();
player.resetAspectRatio();
art.emit('fullscreenWeb', this.state);
});
}
enabled() {
const { i18n, refs: { $player } } = this.art;
this.state = true;
$player.classList.add('artplayer-web-fullscreen');
setStyle(this.$fullscreenWeb, 'opacity', '0.8');
tooltip(this.$fullscreenWeb, i18n.get('Exit web fullscreen'));
}
exit() {
const { i18n, refs: { $player } } = this.art;
this.state = false;
$player.classList.remove('artplayer-web-fullscreen');
setStyle(this.$fullscreenWeb, 'opacity', '1');
tooltip(this.$fullscreenWeb, i18n.get('Web fullscreen'));
}
toggle() {
if (this.state) {
this.exit();
} else {
this.enabled();
}
}
}
+9 -54
View File
@@ -1,70 +1,25 @@
import { append, tooltip, setStyle } from '../utils';
import icons from '../icons';
import screenfull from 'screenfull';
export default class Fullscreen {
constructor(option) {
this.option = option;
}
get state() {
return screenfull.isFullscreen;
}
apply(art, $control) {
this.art = art;
const { events: { destroyEvents, proxy }, i18n, player, controls, notice } = art;
const { events: { proxy }, i18n, player } = art;
this.$fullscreen = append($control, icons.fullscreen);
tooltip(this.$fullscreen, i18n.get('Fullscreen'));
proxy($control, 'click', () => {
if (controls.fullscreenWeb && controls.fullscreenWeb.state) {
controls.fullscreenWeb.exit();
}
this.toggle();
});
const screenfullChange = () => {
player.resetAspectRatio();
art.emit('fullscreen', screenfull.isFullscreen);
};
const screenfullError = () => {
notice.show('Your browser does not seem to support full screen functionality.');
};
screenfull.on('change', screenfullChange);
screenfull.on('error', screenfullError);
destroyEvents.push(() => {
screenfull.off('change', screenfullChange);
screenfull.off('error', screenfullError);
});
}
enabled() {
const { i18n, refs: { $player } } = this.art;
$player.classList.add('artplayer-fullscreen');
setStyle(this.$fullscreen, 'opacity', '0.8');
tooltip(this.$fullscreen, i18n.get('Exit fullscreen'));
screenfull.request($player);
}
exit() {
const { i18n, refs: { $player } } = this.art;
$player.classList.remove('artplayer-fullscreen');
setStyle(this.$fullscreen, 'opacity', '1');
tooltip(this.$fullscreen, i18n.get('Fullscreen'));
screenfull.exit();
}
toggle() {
if (screenfull.enabled) {
if (screenfull.isFullscreen) {
this.exit();
if (player.fullscreenState) {
player.fullscreenExit();
setStyle(this.$fullscreen, 'opacity', '1');
tooltip(this.$fullscreen, i18n.get('Fullscreen'));
} else {
this.enabled();
player.fullscreenEnabled();
setStyle(this.$fullscreen, 'opacity', '0.8');
tooltip(this.$fullscreen, i18n.get('Exit fullscreen'));
}
}
});
}
}
+25
View File
@@ -0,0 +1,25 @@
import { append, tooltip, setStyle } from '../utils';
import icons from '../icons';
export default class FullscreenWeb {
constructor(option) {
this.option = option;
}
apply(art, $control) {
const { events: { proxy }, i18n, player } = art;
this.$fullscreenWeb = append($control, icons.fullscreenWeb);
tooltip(this.$fullscreenWeb, i18n.get('Web fullscreen'));
proxy($control, 'click', () => {
if (player.fullscreenWebState) {
player.fullscreenWebExit();
setStyle(this.$fullscreenWeb, 'opacity', '1');
tooltip(this.$fullscreenWeb, i18n.get('Web fullscreen'));
} else {
player.fullscreenWebEnabled();
setStyle(this.$fullscreenWeb, 'opacity', '0.8');
tooltip(this.$fullscreenWeb, i18n.get('Exit web fullscreen'));
}
});
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
import { setStyle, append } from '../utils';
import Danmu from './danmu';
import Fullscreen from './fullscreen';
import FullscreenWeb from './fullscreen-web';
import FullscreenWeb from './fullscreenWeb';
import Pip from './pip';
import PlayAndPause from './playAndPause';
import Progress from './progress';
+3 -25
View File
@@ -1,4 +1,4 @@
import { append, tooltip, secondToTime, setStyle } from '../utils';
import { append, tooltip } from '../utils';
import icons from '../icons';
export default class Screenshot {
@@ -7,33 +7,11 @@ export default class Screenshot {
}
apply(art, $control) {
this.art = art;
const { events: { proxy }, i18n, notice } = this.art;
const { events: { proxy }, i18n, player } = art;
this.$screenshot = append($control, icons.screenshot);
tooltip(this.$screenshot, i18n.get('Screenshot'));
proxy(this.$screenshot, 'click', () => {
try {
this.captureFrame();
art.emit('screenshot');
} catch (error) {
notice.show(error);
}
player.screenshot();
});
}
captureFrame() {
const { $video } = this.art.refs;
const canvas = document.createElement('canvas');
canvas.width = $video.videoWidth;
canvas.height = $video.videoHeight;
canvas.getContext('2d').drawImage($video, 0, 0);
const dataUri = canvas.toDataURL('image/png');
const elink = document.createElement('a');
setStyle(elink, 'display', 'none');
elink.href = dataUri;
elink.download = `ArtPlayer_${secondToTime($video.currentTime)}.png`;
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
}
}
-2
View File
@@ -15,12 +15,10 @@ export default class Setting {
setting.hide();
setStyle(this.$setting, 'opacity', '1');
tooltip(this.$setting, i18n.get('Show setting'));
art.emit('setting:hide');
} else {
setting.show();
setStyle(this.$setting, 'opacity', '0.8');
tooltip(this.$setting, i18n.get('Hide setting'));
art.emit('setting:show');
}
});
}
-2
View File
@@ -15,12 +15,10 @@ export default class Subtitle {
subtitle.hide();
setStyle(this.$subtitle, 'opacity', '1');
tooltip(this.$subtitle, i18n.get('Show subtitle'));
art.emit('subtitle:hide');
} else {
subtitle.show();
setStyle(this.$subtitle, 'opacity', '0.8');
tooltip(this.$subtitle, i18n.get('Hide subtitle'));
art.emit('subtitle:show');
}
});
}
+6 -7
View File
@@ -1,9 +1,10 @@
import { setStyle, sublings } from '../utils';
export default function aspectRatioMix(art, player) {
const { refs: { $video, $player }, i18n, notice, contextmenu } = art;
Object.defineProperty(player, 'aspectRatio', {
value: ratio => {
const { refs: { $video, $player }, i18n, notice } = art;
const ratioName = ratio.length === 2 ? `${ratio[0]}:${ratio[1]}` : i18n.get('Default');
if (ratio.length === 2) {
@@ -37,23 +38,21 @@ export default function aspectRatioMix(art, player) {
}
});
Object.defineProperty(player, 'removeAspectRatio', {
Object.defineProperty(player, 'aspectRatioRemove', {
value: () => {
const { refs: { $video }, contextmenu: { $aspectRatio } } = art;
setStyle($video, 'width', null);
setStyle($video, 'height', null);
setStyle($video, 'padding', null);
if ($aspectRatio) {
const $default = $aspectRatio.querySelector('.default');
if (contextmenu.$aspectRatio) {
const $default = contextmenu.$aspectRatio.querySelector('.default');
sublings($default).forEach(item => item.classList.remove('current'));
$default.classList.add('current');
}
}
});
Object.defineProperty(player, 'resetAspectRatio', {
Object.defineProperty(player, 'aspectRatioReset', {
value: () => {
const { refs: { $player } } = art;
const { aspectRatio } = $player.dataset;
if (aspectRatio) {
player.aspectRatio(aspectRatio.split(':'));
+57
View File
@@ -0,0 +1,57 @@
import screenfull from 'screenfull';
export default function fullscreenMix(art, player) {
const { notice, events: { destroyEvents }, refs: { $player } } = art;
const screenfullChange = () => {
player.aspectRatioReset();
art.emit('fullscreen', screenfull.isFullscreen);
};
const screenfullError = () => {
notice.show('Your browser does not seem to support full screen functionality.');
};
screenfull.on('change', screenfullChange);
screenfull.on('error', screenfullError);
destroyEvents.push(() => {
screenfull.off('change', screenfullChange);
screenfull.off('error', screenfullError);
});
Object.defineProperty(player, 'fullscreenState', {
get: () => screenfull.isFullscreen
});
Object.defineProperty(player, 'fullscreenEnabled', {
value: () => {
if (player.fullscreenWebState) {
player.fullscreenWebExit();
}
$player.classList.add('artplayer-fullscreen');
screenfull.request($player);
}
});
Object.defineProperty(player, 'fullscreenExit', {
value: () => {
if (player.fullscreenWebState) {
player.fullscreenWebExit();
}
$player.classList.remove('artplayer-fullscreen');
screenfull.exit();
}
});
Object.defineProperty(player, 'fullscreenToggle', {
value: () => {
if (screenfull.enabled) {
if (screenfull.isFullscreen) {
player.fullscreenExit();
} else {
player.fullscreenEnabled();
}
}
}
});
}
+39
View File
@@ -0,0 +1,39 @@
export default function fullscreenWebMix(art, player) {
const { refs: { $player } } = art;
Object.defineProperty(player, 'fullscreenWebState', {
get: () => $player.classList.contains('artplayer-web-fullscreen')
});
Object.defineProperty(player, 'fullscreenWebEnabled', {
value: () => {
if (player.fullscreenState) {
player.fullscreenExit();
}
$player.classList.add('artplayer-web-fullscreen');
player.aspectRatioReset();
art.emit('fullscreenWeb', true);
}
});
Object.defineProperty(player, 'fullscreenWebExit', {
value: () => {
if (player.fullscreenState) {
player.fullscreenExit();
}
$player.classList.remove('artplayer-web-fullscreen');
player.aspectRatioReset();
art.emit('fullscreenWeb', false);
}
});
Object.defineProperty(player, 'fullscreenWebToggle', {
value: () => {
if (player.fullscreenWebState) {
player.exit();
} else {
player.enabled();
}
}
});
}
+6
View File
@@ -10,6 +10,9 @@ import durationMix from './durationMix';
import switchMix from './switchMix';
import playbackRateMix from './playbackRateMix';
import aspectRatioMix from './aspectRatioMix';
import screenshotMix from './screenshotMix';
import fullscreenMix from './fullscreenMix';
import fullscreenWebMix from './fullscreenWebMix';
export default class Player {
constructor(art) {
@@ -28,5 +31,8 @@ export default class Player {
switchMix(art, this);
playbackRateMix(art, this);
aspectRatioMix(art, this);
screenshotMix(art, this);
fullscreenMix(art, this);
fullscreenWebMix(art, this);
}
}
+2 -1
View File
@@ -1,7 +1,8 @@
export default function pauseMin(art, player) {
const { refs: { $video }, i18n, notice } = art;
Object.defineProperty(player, 'pause', {
value: () => {
const { refs: { $video }, i18n, notice } = art;
$video.pause();
notice.show(i18n.get('Pause'));
art.emit('pause', $video);
+2 -1
View File
@@ -1,7 +1,8 @@
export default function playMix(art, player) {
const { refs: { $video }, i18n, notice } = art;
Object.defineProperty(player, 'play', {
value: () => {
const { refs: { $video }, i18n, notice } = art;
const promise = $video.play();
if (promise !== undefined) {
promise.then().catch(err => {
+6 -7
View File
@@ -1,9 +1,10 @@
import { clamp, sublings } from '../utils';
export default function playbackRateMix(art, player) {
const { refs: { $video, $player }, i18n, notice, contextmenu } = art;
Object.defineProperty(player, 'playbackRate', {
value: rate => {
const { refs: { $video, $player }, i18n, notice } = art;
const newRate = clamp(rate, 0.1, 10);
$video.playbackRate = newRate;
$player.dataset.playbackRate = newRate;
@@ -12,20 +13,18 @@ export default function playbackRateMix(art, player) {
}
});
Object.defineProperty(player, 'removePlaybackRate', {
Object.defineProperty(player, 'playbackRateRemove', {
value: () => {
const { contextmenu: { $playbackRate } } = art;
if ($playbackRate) {
const $normal = $playbackRate.querySelector('.normal');
if (contextmenu.$playbackRate) {
const $normal = contextmenu.$playbackRate.querySelector('.normal');
sublings($normal).forEach(item => item.classList.remove('current'));
$normal.classList.add('current');
}
}
});
Object.defineProperty(player, 'resetPlaybackRate', {
Object.defineProperty(player, 'playbackRateReset', {
value: () => {
const { refs: { $player } } = art;
const { playbackRate } = $player.dataset;
if (playbackRate) {
player.playbackRate(Number(playbackRate));
+33
View File
@@ -0,0 +1,33 @@
import { setStyle, secondToTime } from '../utils';
export default function screenshotMix(art, player) {
const { notice } = art;
function captureFrame() {
const { $video } = art.refs;
const canvas = document.createElement('canvas');
canvas.width = $video.videoWidth;
canvas.height = $video.videoHeight;
canvas.getContext('2d').drawImage($video, 0, 0);
const dataUri = canvas.toDataURL('image/png');
const elink = document.createElement('a');
setStyle(elink, 'display', 'none');
elink.href = dataUri;
elink.download = `ArtPlayer_${secondToTime($video.currentTime)}.png`;
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
}
Object.defineProperty(player, 'screenshot', {
value: () => {
try {
captureFrame();
art.emit('screenshot');
} catch (error) {
notice.show(error);
console.warn(error);
}
}
});
}
+2 -1
View File
@@ -1,9 +1,10 @@
import { secondToTime } from '../utils';
export default function seekMix(art, player) {
const { refs: { $video }, notice } = art;
Object.defineProperty(player, 'seek', {
value: time => {
const { refs: { $video }, notice } = art;
let newTime = Math.max(time, 0);
if ($video.duration) {
newTime = Math.min(newTime, $video.duration);
+2 -1
View File
@@ -1,7 +1,8 @@
export default function switchMix(art, player) {
const { refs: { $video }, i18n, notice, isPlaying, option } = art;
Object.defineProperty(player, 'switch', {
value: (url, name = 'Unknown') => {
const { refs: { $video }, i18n, notice, isPlaying, option } = art;
const currentTime = player.currentTime();
$video.src = url;
option.url = url;
+2 -1
View File
@@ -1,9 +1,10 @@
import { clamp, setStorage } from '../utils';
export default function volumeMix(art, player) {
const { refs: { $video }, i18n, notice } = art;
Object.defineProperty(player, 'volume', {
value: percentage => {
const { refs: { $video }, i18n, notice } = art;
if (percentage !== undefined) {
$video.volume = clamp(percentage, 0, 1);
notice.show(`${i18n.get('Volume')}: ${parseInt($video.volume * 100)}`);