格式化

This commit is contained in:
Harvey Zack committed 2018-11-21 19:45:44 +08:00
1 parent 0454f785be
commit 203ad0d3a0
75 files changed
+3120 -2904

No files matched your search

+23 -19
View File
@@ -2,27 +2,31 @@ import { append, tooltip, setStyle } from '../utils';
import icons from '../icons';
export default class Fullscreen {
constructor(option) {
this.option = option;
}
constructor(option) {
this.option = option;
}
apply(art, $control) {
const { events: { proxy }, i18n, player } = art;
this.$fullscreen = append($control, icons.fullscreen);
tooltip(this.$fullscreen, i18n.get('Fullscreen'));
apply(art, $control) {
const {
events: { proxy },
i18n,
player,
} = art;
this.$fullscreen = append($control, icons.fullscreen);
tooltip(this.$fullscreen, i18n.get('Fullscreen'));
proxy($control, 'click', () => {
player.fullscreenToggle();
});
proxy($control, 'click', () => {
player.fullscreenToggle();
});
art.on('fullscreen:enabled', () => {
setStyle(this.$fullscreen, 'opacity', '0.8');
tooltip(this.$fullscreen, i18n.get('Exit fullscreen'));
});
art.on('fullscreen:enabled', () => {
setStyle(this.$fullscreen, 'opacity', '0.8');
tooltip(this.$fullscreen, i18n.get('Exit fullscreen'));
});
art.on('fullscreen:exit', () => {
setStyle(this.$fullscreen, 'opacity', '1');
tooltip(this.$fullscreen, i18n.get('Fullscreen'));
});
}
art.on('fullscreen:exit', () => {
setStyle(this.$fullscreen, 'opacity', '1');
tooltip(this.$fullscreen, i18n.get('Fullscreen'));
});
}
}
@@ -2,27 +2,31 @@ import { append, tooltip, setStyle } from '../utils';
import icons from '../icons';
export default class FullscreenWeb {
constructor(option) {
this.option = option;
}
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'));
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', () => {
player.fullscreenWebToggle();
});
proxy($control, 'click', () => {
player.fullscreenWebToggle();
});
art.on('fullscreenWeb:enabled', () => {
setStyle(this.$fullscreenWeb, 'opacity', '0.8');
tooltip(this.$fullscreenWeb, i18n.get('Exit web fullscreen'));
});
art.on('fullscreenWeb:enabled', () => {
setStyle(this.$fullscreenWeb, 'opacity', '0.8');
tooltip(this.$fullscreenWeb, i18n.get('Exit web fullscreen'));
});
art.on('fullscreenWeb:exit', () => {
setStyle(this.$fullscreenWeb, 'opacity', '1');
tooltip(this.$fullscreenWeb, i18n.get('Web fullscreen'));
});
}
art.on('fullscreenWeb:exit', () => {
setStyle(this.$fullscreenWeb, 'opacity', '1');
tooltip(this.$fullscreenWeb, i18n.get('Web fullscreen'));
});
}
}
+176 -148
View File
@@ -14,159 +14,187 @@ import Quality from './quality';
let id = 0;
export default class Controls {
constructor(art) {
id = 0;
this.art = art;
this.art.on('firstCanplay', () => {
this.init();
});
}
init() {
this.add(new Progress({
name: 'progress',
disable: false,
position: 'top',
index: 10
}));
this.add(new Thumbnails({
name: 'thumbnails',
disable: !this.art.option.thumbnails.url,
position: 'top',
index: 20
}));
this.add(new PlayAndPause({
name: 'playAndPause',
disable: false,
position: 'left',
index: 10
}));
this.add(new Volume({
name: 'volume',
disable: false,
position: 'left',
index: 20
}));
this.add(new Time({
name: 'time',
disable: false,
position: 'left',
index: 30
}));
this.add(new Quality({
name: 'quality',
disable: this.art.option.quality.length === 0,
position: 'right',
index: 10
}));
this.add(new Screenshot({
name: 'screenshot',
disable: !this.art.option.screenshot,
position: 'right',
index: 20
}));
this.add(new Subtitle({
name: 'subtitle',
disable: !this.art.option.subtitle.url,
position: 'right',
index: 30
}));
this.add(new Setting({
name: 'setting',
disable: !this.art.option.setting,
position: 'right',
index: 40
}));
this.add(new Pip({
name: 'pip',
disable: !this.art.option.pip,
position: 'right',
index: 50
}));
this.add(new FullscreenWeb({
name: 'fullscreenWeb',
disable: !this.art.option.fullscreenWeb,
position: 'right',
index: 60
}));
this.add(new Fullscreen({
name: 'fullscreen',
disable: !this.art.option.fullscreen,
position: 'right',
index: 70
}));
this.art.option.controls.forEach(item => {
this.add(item);
});
}
add(control, callback) {
const { option } = control;
if (option && !option.disable) {
id++;
const name = option.name || `control${id}`;
const $control = document.createElement('div');
$control.classList.value = `art-control art-control-${name}`;
this.mount(option.position, $control, option.index || id);
this.commonMethod(control, $control);
control.apply && control.apply(this.art, $control);
callback && callback($control);
this[name] = control;
constructor(art) {
id = 0;
this.art = art;
this.art.on('firstCanplay', () => {
this.init();
});
}
}
mount(position, $control, index) {
const { $progress, $controlsLeft, $controlsRight } = this.art.refs;
switch (position) {
case 'top':
insertByIndex($progress, $control, index);
break;
case 'left':
insertByIndex($controlsLeft, $control, index);
break;
case 'right':
insertByIndex($controlsRight, $control, index);
break;
default:
break;
init() {
this.add(
new Progress({
name: 'progress',
disable: false,
position: 'top',
index: 10,
}),
);
this.add(
new Thumbnails({
name: 'thumbnails',
disable: !this.art.option.thumbnails.url,
position: 'top',
index: 20,
}),
);
this.add(
new PlayAndPause({
name: 'playAndPause',
disable: false,
position: 'left',
index: 10,
}),
);
this.add(
new Volume({
name: 'volume',
disable: false,
position: 'left',
index: 20,
}),
);
this.add(
new Time({
name: 'time',
disable: false,
position: 'left',
index: 30,
}),
);
this.add(
new Quality({
name: 'quality',
disable: this.art.option.quality.length === 0,
position: 'right',
index: 10,
}),
);
this.add(
new Screenshot({
name: 'screenshot',
disable: !this.art.option.screenshot,
position: 'right',
index: 20,
}),
);
this.add(
new Subtitle({
name: 'subtitle',
disable: !this.art.option.subtitle.url,
position: 'right',
index: 30,
}),
);
this.add(
new Setting({
name: 'setting',
disable: !this.art.option.setting,
position: 'right',
index: 40,
}),
);
this.add(
new Pip({
name: 'pip',
disable: !this.art.option.pip,
position: 'right',
index: 50,
}),
);
this.add(
new FullscreenWeb({
name: 'fullscreenWeb',
disable: !this.art.option.fullscreenWeb,
position: 'right',
index: 60,
}),
);
this.add(
new Fullscreen({
name: 'fullscreen',
disable: !this.art.option.fullscreen,
position: 'right',
index: 70,
}),
);
this.art.option.controls.forEach(item => {
this.add(item);
});
}
}
commonMethod(control, $control) {
Object.defineProperty(control, 'hide', {
value: () => {
setStyle($control, 'display', 'none');
this.art.emit('control:hide', $control);
}
});
add(control, callback) {
const { option } = control;
if (option && !option.disable) {
id += 1;
const name = option.name || `control${id}`;
const $control = document.createElement('div');
$control.classList.value = `art-control art-control-${name}`;
this.mount(option.position, $control, option.index || id);
this.commonMethod(control, $control);
if (control.apply) {
control.apply(this.art, $control);
}
if (callback) {
callback($control);
}
this[name] = control;
}
}
Object.defineProperty(control, 'show', {
value: () => {
setStyle($control, 'display', 'block');
this.art.emit('control:show', $control);
}
});
}
mount(position, $control, index) {
const { $progress, $controlsLeft, $controlsRight } = this.art.refs;
switch (position) {
case 'top':
insertByIndex($progress, $control, index);
break;
case 'left':
insertByIndex($controlsLeft, $control, index);
break;
case 'right':
insertByIndex($controlsRight, $control, index);
break;
default:
break;
}
}
show() {
const { $player } = this.art.refs;
$player.classList.add('artplayer-controls-show');
}
commonMethod(control, $control) {
Object.defineProperty(control, 'hide', {
value: () => {
setStyle($control, 'display', 'none');
this.art.emit('control:hide', $control);
},
});
hide() {
const { $player } = this.art.refs;
$player.classList.remove('artplayer-controls-show');
}
Object.defineProperty(control, 'show', {
value: () => {
setStyle($control, 'display', 'block');
this.art.emit('control:show', $control);
},
});
}
show() {
const { $player } = this.art.refs;
$player.classList.add('artplayer-controls-show');
}
hide() {
const { $player } = this.art.refs;
$player.classList.remove('artplayer-controls-show');
}
}
+15 -11
View File
@@ -2,16 +2,20 @@ import { append, tooltip } from '../utils';
import icons from '../icons';
export default class Pip {
constructor(option) {
this.option = option;
}
constructor(option) {
this.option = option;
}
apply(art, $control) {
const { events: { proxy }, i18n, player } = art;
this.$pip = append($control, icons.pip);
tooltip(this.$pip, i18n.get('Mini player'));
proxy($control, 'click', () => {
player.pipEnabled();
});
}
apply(art, $control) {
const {
events: { proxy },
i18n,
player,
} = art;
this.$pip = append($control, icons.pip);
tooltip(this.$pip, i18n.get('Mini player'));
proxy($control, 'click', () => {
player.pipEnabled();
});
}
}
+29 -25
View File
@@ -2,34 +2,38 @@ import { append, tooltip, setStyle } from '../utils';
import icons from '../icons';
export default class PlayAndPause {
constructor(option) {
this.option = option;
}
constructor(option) {
this.option = option;
}
apply(art, $control) {
const { events: { proxy }, player, i18n } = art;
this.$play = append($control, icons.play);
this.$pause = append($control, icons.pause);
tooltip(this.$play, i18n.get('Play'));
tooltip(this.$pause, i18n.get('Pause'));
setStyle(this.$pause, 'display', 'none');
apply(art, $control) {
const {
events: { proxy },
player,
i18n,
} = art;
this.$play = append($control, icons.play);
this.$pause = append($control, icons.pause);
tooltip(this.$play, i18n.get('Play'));
tooltip(this.$pause, i18n.get('Pause'));
setStyle(this.$pause, 'display', 'none');
proxy(this.$play, 'click', () => {
player.play();
});
proxy(this.$play, 'click', () => {
player.play();
});
proxy(this.$pause, 'click', () => {
player.pause();
});
proxy(this.$pause, 'click', () => {
player.pause();
});
art.on('video:playing', () => {
setStyle(this.$play, 'display', 'none');
setStyle(this.$pause, 'display', 'flex');
});
art.on('video:playing', () => {
setStyle(this.$play, 'display', 'none');
setStyle(this.$pause, 'display', 'flex');
});
art.on('video:pause', () => {
setStyle(this.$play, 'display', 'flex');
setStyle(this.$pause, 'display', 'none');
});
}
art.on('video:pause', () => {
setStyle(this.$play, 'display', 'flex');
setStyle(this.$pause, 'display', 'none');
});
}
}
+139 -125
View File
@@ -1,134 +1,148 @@
import { append, clamp, secondToTime, setStyle, getStyle } from '../utils';
export default class Progress {
constructor(option) {
this.option = option;
this.isDroging = false;
this.set = this.set.bind(this);
}
apply(art, $control) {
this.art = art;
this.$control = $control;
const { option: { highlight, theme }, events: { proxy }, player } = art;
append(
$control,
`
<div class="art-control-progress-inner">
<div class="art-progress-loaded"></div>
<div class="art-progress-played" style="background: ${theme}"></div>
<div class="art-progress-highlight"></div>
<div class="art-progress-indicator" style="background: ${theme}"></div>
<div class="art-progress-tip art-tip"></div>
</div>
`
);
this.$loaded = $control.querySelector('.art-progress-loaded');
this.$played = $control.querySelector('.art-progress-played');
this.$highlight = $control.querySelector('.art-progress-highlight');
this.$indicator = $control.querySelector('.art-progress-indicator');
this.$tip = $control.querySelector('.art-progress-tip');
highlight.forEach(item => {
const left = clamp(item.time, 0, player.duration) / player.duration * 100;
append(this.$highlight, `<span data-text="${item.text}" data-time="${item.time}" style="left: ${left}%"></span>`);
});
this.set('loaded', player.loaded);
this.art.on('video:progress', () => {
this.set('loaded', player.loaded);
});
this.art.on('video:timeupdate', () => {
this.set('played', player.played);
});
this.art.on('video:ended', () => {
this.set('played', 1);
});
proxy($control, 'mousemove', event => {
setStyle(this.$tip, 'display', 'block');
if (event.composedPath().indexOf(this.$highlight) > -1) {
this.showHighlight(event);
} else {
this.showTime(event);
}
});
proxy($control, 'mouseout', () => {
setStyle(this.$tip, 'display', 'none');
});
proxy($control, 'click', event => {
if (event.target !== this.$indicator) {
const { second, percentage } = this.getPosFromEvent(event);
this.set('played', percentage);
player.seek(second);
}
});
proxy(this.$indicator, 'mousedown', () => {
this.isDroging = true;
});
proxy(document, 'mousemove', event => {
if (this.isDroging) {
const { second, percentage } = this.getPosFromEvent(event);
this.$indicator.classList.add('art-show-indicator');
this.set('played', percentage);
player.seek(second);
}
});
proxy(document, 'mouseup', () => {
if (this.isDroging) {
constructor(option) {
this.option = option;
this.isDroging = false;
this.$indicator.classList.remove('art-show-indicator');
}
});
}
showHighlight(event) {
const { text, time } = event.target.dataset;
this.$tip.innerHTML = text;
const left =
Number(time) / this.art.player.duration * this.$control.clientWidth +
event.target.clientWidth / 2 -
this.$tip.clientWidth / 2;
setStyle(this.$tip, 'left', `${left}px`);
}
showTime(event) {
const { width, time } = this.getPosFromEvent(event);
const tipWidth = this.$tip.clientWidth;
this.$tip.innerHTML = time;
if (width <= tipWidth / 2) {
setStyle(this.$tip, 'left', 0);
} else if (width > this.$control.clientWidth - tipWidth / 2) {
setStyle(this.$tip, 'left', `${this.$control.clientWidth - tipWidth}px`);
} else {
setStyle(this.$tip, 'left', `${width - tipWidth / 2}px`);
this.set = this.set.bind(this);
}
}
getPosFromEvent(event) {
const { player, refs: { $progress } } = this.art;
const { left } = $progress.getBoundingClientRect();
const width = clamp(event.x - left, 0, $progress.clientWidth);
const second = width / $progress.clientWidth * player.duration;
const time = secondToTime(second);
const percentage = clamp(width / $progress.clientWidth, 0, 1);
return { second, time, width, percentage };
}
apply(art, $control) {
this.art = art;
this.$control = $control;
const {
option: { highlight, theme },
events: { proxy },
player,
} = art;
set(type, percentage) {
setStyle(this[`$${type}`], 'width', `${percentage * 100}%`);
if (type === 'played') {
setStyle(this.$indicator, 'left', `calc(${percentage * 100}% - ${getStyle(this.$indicator, 'width') / 2}px)`);
append(
$control,
`
<div class="art-control-progress-inner">
<div class="art-progress-loaded"></div>
<div class="art-progress-played" style="background: ${theme}"></div>
<div class="art-progress-highlight"></div>
<div class="art-progress-indicator" style="background: ${theme}"></div>
<div class="art-progress-tip art-tip"></div>
</div>
`,
);
this.$loaded = $control.querySelector('.art-progress-loaded');
this.$played = $control.querySelector('.art-progress-played');
this.$highlight = $control.querySelector('.art-progress-highlight');
this.$indicator = $control.querySelector('.art-progress-indicator');
this.$tip = $control.querySelector('.art-progress-tip');
highlight.forEach(item => {
const left = (clamp(item.time, 0, player.duration) / player.duration) * 100;
append(
this.$highlight,
`<span data-text="${item.text}" data-time="${item.time}" style="left: ${left}%"></span>`,
);
});
this.set('loaded', player.loaded);
this.art.on('video:progress', () => {
this.set('loaded', player.loaded);
});
this.art.on('video:timeupdate', () => {
this.set('played', player.played);
});
this.art.on('video:ended', () => {
this.set('played', 1);
});
proxy($control, 'mousemove', event => {
setStyle(this.$tip, 'display', 'block');
if (event.composedPath().indexOf(this.$highlight) > -1) {
this.showHighlight(event);
} else {
this.showTime(event);
}
});
proxy($control, 'mouseout', () => {
setStyle(this.$tip, 'display', 'none');
});
proxy($control, 'click', event => {
if (event.target !== this.$indicator) {
const { second, percentage } = this.getPosFromEvent(event);
this.set('played', percentage);
player.seek(second);
}
});
proxy(this.$indicator, 'mousedown', () => {
this.isDroging = true;
});
proxy(document, 'mousemove', event => {
if (this.isDroging) {
const { second, percentage } = this.getPosFromEvent(event);
this.$indicator.classList.add('art-show-indicator');
this.set('played', percentage);
player.seek(second);
}
});
proxy(document, 'mouseup', () => {
if (this.isDroging) {
this.isDroging = false;
this.$indicator.classList.remove('art-show-indicator');
}
});
}
showHighlight(event) {
const { text, time } = event.target.dataset;
this.$tip.innerHTML = text;
const left =
(Number(time) / this.art.player.duration) * this.$control.clientWidth +
event.target.clientWidth / 2 -
this.$tip.clientWidth / 2;
setStyle(this.$tip, 'left', `${left}px`);
}
showTime(event) {
const { width, time } = this.getPosFromEvent(event);
const tipWidth = this.$tip.clientWidth;
this.$tip.innerHTML = time;
if (width <= tipWidth / 2) {
setStyle(this.$tip, 'left', 0);
} else if (width > this.$control.clientWidth - tipWidth / 2) {
setStyle(this.$tip, 'left', `${this.$control.clientWidth - tipWidth}px`);
} else {
setStyle(this.$tip, 'left', `${width - tipWidth / 2}px`);
}
}
getPosFromEvent(event) {
const {
player,
refs: { $progress },
} = this.art;
const { left } = $progress.getBoundingClientRect();
const width = clamp(event.x - left, 0, $progress.clientWidth);
const second = (width / $progress.clientWidth) * player.duration;
const time = secondToTime(second);
const percentage = clamp(width / $progress.clientWidth, 0, 1);
return { second, time, width, percentage };
}
set(type, percentage) {
setStyle(this[`$${type}`], 'width', `${percentage * 100}%`);
if (type === 'played') {
setStyle(
this.$indicator,
'left',
`calc(${percentage * 100}% - ${getStyle(this.$indicator, 'width') / 2}px)`,
);
}
}
}
}
+36 -26
View File
@@ -1,33 +1,43 @@
import { append } from '../utils';
export default class Quality {
constructor(option) {
this.option = option;
this.playIndex = -1;
}
constructor(option) {
this.option = option;
this.playIndex = -1;
}
apply(art, $control) {
const { option, events: { proxy, hover }, player } = art;
const defaultQuality = option.quality.find(item => item.default) || option.quality[0];
this.playIndex = option.quality.indexOf(defaultQuality);
const $qualityName = append($control, `<div class="art-quality-name">${defaultQuality.name}</div>`);
const qualityList = option.quality.map((item, index) => `<div class="art-quality-item" data-index="${index}">${item.name}</div>`).join('');
const $qualitys = append($control, `<div class="art-qualitys">${qualityList}</div>`);
apply(art, $control) {
const {
option,
events: { proxy, hover },
player,
} = art;
const defaultQuality = option.quality.find(item => item.default) || option.quality[0];
this.playIndex = option.quality.indexOf(defaultQuality);
const $qualityName = append($control, `<div class="art-quality-name">${defaultQuality.name}</div>`);
const qualityList = option.quality
.map((item, index) => `<div class="art-quality-item" data-index="${index}">${item.name}</div>`)
.join('');
const $qualitys = append($control, `<div class="art-qualitys">${qualityList}</div>`);
hover($control, () => {
$control.classList.add('art-quality-hover');
}, () => {
$control.classList.remove('art-quality-hover');
});
hover(
$control,
() => {
$control.classList.add('art-quality-hover');
},
() => {
$control.classList.remove('art-quality-hover');
},
);
proxy($qualitys, 'click', event => {
const index = Number(event.target.dataset.index);
const { url, name } = option.quality[index];
if (url && name && this.playIndex !== index) {
player.switch(url, name);
$qualityName.innerHTML = name;
this.playIndex = index;
}
});
}
proxy($qualitys, 'click', event => {
const index = Number(event.target.dataset.index);
const { url, name } = option.quality[index];
if (url && name && this.playIndex !== index) {
player.switch(url, name);
$qualityName.innerHTML = name;
this.playIndex = index;
}
});
}
}
+15 -11
View File
@@ -2,16 +2,20 @@ import { append, tooltip } from '../utils';
import icons from '../icons';
export default class Screenshot {
constructor(option) {
this.option = option;
}
constructor(option) {
this.option = option;
}
apply(art, $control) {
const { events: { proxy }, i18n, player } = art;
this.$screenshot = append($control, icons.screenshot);
tooltip(this.$screenshot, i18n.get('Screenshot'));
proxy(this.$screenshot, 'click', () => {
player.screenshot();
});
}
apply(art, $control) {
const {
events: { proxy },
i18n,
player,
} = art;
this.$screenshot = append($control, icons.screenshot);
tooltip(this.$screenshot, i18n.get('Screenshot'));
proxy(this.$screenshot, 'click', () => {
player.screenshot();
});
}
}
+23 -19
View File
@@ -2,27 +2,31 @@ import { append, tooltip, setStyle } from '../utils';
import icons from '../icons';
export default class Setting {
constructor(option) {
this.option = option;
}
constructor(option) {
this.option = option;
}
apply(art, $control) {
const { events: { proxy }, i18n, setting } = art;
this.$setting = append($control, icons.setting);
tooltip(this.$setting, i18n.get('Show setting'));
apply(art, $control) {
const {
events: { proxy },
i18n,
setting,
} = art;
this.$setting = append($control, icons.setting);
tooltip(this.$setting, i18n.get('Show setting'));
proxy($control, 'click', () => {
setting.toggle();
});
proxy($control, 'click', () => {
setting.toggle();
});
art.on('setting:show', () => {
setStyle(this.$setting, 'opacity', '0.8');
tooltip(this.$setting, i18n.get('Hide setting'));
});
art.on('setting:show', () => {
setStyle(this.$setting, 'opacity', '0.8');
tooltip(this.$setting, i18n.get('Hide setting'));
});
art.on('setting:hide', () => {
setStyle(this.$setting, 'opacity', '1');
tooltip(this.$setting, i18n.get('Show setting'));
});
}
art.on('setting:hide', () => {
setStyle(this.$setting, 'opacity', '1');
tooltip(this.$setting, i18n.get('Show setting'));
});
}
}
+23 -19
View File
@@ -2,27 +2,31 @@ import { append, tooltip, setStyle } from '../utils';
import icons from '../icons';
export default class Subtitle {
constructor(option) {
this.option = option;
}
constructor(option) {
this.option = option;
}
apply(art, $control) {
const { events: { proxy }, i18n, subtitle } = art;
this.$subtitle = append($control, icons.subtitle);
tooltip(this.$subtitle, i18n.get('Hide subtitle'));
apply(art, $control) {
const {
events: { proxy },
i18n,
subtitle,
} = art;
this.$subtitle = append($control, icons.subtitle);
tooltip(this.$subtitle, i18n.get('Hide subtitle'));
proxy($control, 'click', () => {
subtitle.toggle();
});
proxy($control, 'click', () => {
subtitle.toggle();
});
art.on('subtitle:show', () => {
setStyle(this.$subtitle, 'opacity', '1');
tooltip(this.$subtitle, i18n.get('Hide subtitle'));
});
art.on('subtitle:show', () => {
setStyle(this.$subtitle, 'opacity', '1');
tooltip(this.$subtitle, i18n.get('Hide subtitle'));
});
art.on('subtitle:hide', () => {
setStyle(this.$subtitle, 'opacity', '0.8');
tooltip(this.$subtitle, i18n.get('Show subtitle'));
});
}
art.on('subtitle:hide', () => {
setStyle(this.$subtitle, 'opacity', '0.8');
tooltip(this.$subtitle, i18n.get('Show subtitle'));
});
}
}
+58 -52
View File
@@ -1,57 +1,63 @@
import { errorHandle, setStyle } from '../utils';
export default class Thumbnails {
constructor(option) {
this.option = option;
this.loading = false;
this.isLoad = false;
}
apply(art, $control) {
this.art = art;
errorHandle(art.controls.progress, '\'thumbnails\' control dependent on \'progress\' control');
const { refs: { $progress }, events: { proxy, loadImg } } = art;
this.$control = $control;
proxy($progress, 'mousemove', event => {
if (!this.loading) {
this.loading = true;
loadImg(this.art.option.thumbnails.url).then(() => {
this.isLoad = true;
});
}
if (this.isLoad) {
setStyle($control, 'display', 'block');
this.showThumbnails(event);
}
});
proxy($progress, 'mouseout', () => {
setStyle($control, 'display', 'none');
});
}
showThumbnails(event) {
const { refs: { $progress }, controls } = this.art;
const { width: posWidth } = controls.progress.getPosFromEvent(event);
const { url, height, width, number, column } = this.art.option.thumbnails;
const perWidth = $progress.clientWidth / number;
const perIndex = Math.ceil(posWidth / perWidth);
let yIndex = Math.ceil(perIndex / column);
let xIndex = perIndex % column || column;
setStyle(this.$control, 'backgroundImage', `url(${url})`);
setStyle(this.$control, 'height', `${height}px`);
setStyle(this.$control, 'width', `${width}px`);
setStyle(this.$control, 'backgroundPosition', `-${--xIndex * width}px -${--yIndex * height}px`);
if (posWidth <= width / 2) {
setStyle(this.$control, 'left', 0);
} else if (posWidth > $progress.clientWidth - width / 2) {
setStyle(this.$control, 'left', `${$progress.clientWidth - width}px`);
} else {
setStyle(this.$control, 'left', `${posWidth - width / 2}px`);
constructor(option) {
this.option = option;
this.loading = false;
this.isLoad = false;
}
apply(art, $control) {
this.art = art;
errorHandle(art.controls.progress, "'thumbnails' control dependent on 'progress' control");
const {
refs: { $progress },
events: { proxy, loadImg },
} = art;
this.$control = $control;
proxy($progress, 'mousemove', event => {
if (!this.loading) {
this.loading = true;
loadImg(this.art.option.thumbnails.url).then(() => {
this.isLoad = true;
});
}
if (this.isLoad) {
setStyle($control, 'display', 'block');
this.showThumbnails(event);
}
});
proxy($progress, 'mouseout', () => {
setStyle($control, 'display', 'none');
});
}
showThumbnails(event) {
const {
refs: { $progress },
controls,
} = this.art;
const { width: posWidth } = controls.progress.getPosFromEvent(event);
const { url, height, width, number, column } = this.art.option.thumbnails;
const perWidth = $progress.clientWidth / number;
const perIndex = Math.ceil(posWidth / perWidth);
const yIndex = Math.ceil(perIndex / column) - 1;
const xIndex = perIndex % column || column - 1;
setStyle(this.$control, 'backgroundImage', `url(${url})`);
setStyle(this.$control, 'height', `${height}px`);
setStyle(this.$control, 'width', `${width}px`);
setStyle(this.$control, 'backgroundPosition', `-${xIndex * width}px -${yIndex * height}px`);
if (posWidth <= width / 2) {
setStyle(this.$control, 'left', 0);
} else if (posWidth > $progress.clientWidth - width / 2) {
setStyle(this.$control, 'left', `${$progress.clientWidth - width}px`);
} else {
setStyle(this.$control, 'left', `${posWidth - width / 2}px`);
}
}
}
}
+15 -15
View File
@@ -1,21 +1,21 @@
import { secondToTime } from '../utils';
export default class Time {
constructor(option) {
this.option = option;
}
apply(art, $control) {
function getTime() {
const newTime = `${secondToTime(art.player.currentTime)} / ${secondToTime(art.player.duration)}`;
if (newTime !== $control.innerHTML) {
$control.innerHTML = newTime;
}
constructor(option) {
this.option = option;
}
getTime();
['video:loadedmetadata', 'video:timeupdate', 'video:progress'].forEach(event => {
art.on(event, getTime);
});
}
apply(art, $control) {
function getTime() {
const newTime = `${secondToTime(art.player.currentTime)} / ${secondToTime(art.player.duration)}`;
if (newTime !== $control.innerHTML) {
$control.innerHTML = newTime;
}
}
getTime();
['video:loadedmetadata', 'video:timeupdate', 'video:progress'].forEach(event => {
art.on(event, getTime);
});
}
}
+86 -76
View File
@@ -2,83 +2,93 @@ import { append, clamp, tooltip, setStyle, sleep, getStyle } from '../utils';
import icons from '../icons';
export default class Volume {
constructor(option) {
this.option = option;
this.isDroging = false;
}
apply(art, $control) {
const { events: { proxy, hover }, player, i18n, storage } = art;
this.$volume = append($control, icons.volume);
this.$volumeClose = append($control, icons.volumeClose);
this.$volumePanel = append($control, '<div class="art-volume-panel"></div>');
this.$volumeHandle = append(this.$volumePanel, '<div class="art-volume-slider-handle"></div>');
tooltip(this.$volume, i18n.get('Mute'));
setStyle(this.$volumeClose, 'display', 'none');
art.on('volumeChange', percentage => {
if (percentage === 0) {
setStyle(this.$volume, 'display', 'none');
setStyle(this.$volumeClose, 'display', 'flex');
} else {
setStyle(this.$volume, 'display', 'flex');
setStyle(this.$volumeClose, 'display', 'none');
}
});
art.on('video:volumechange', () => {
this.setVolumeHandle(player.volume);
});
proxy(this.$volume, 'click', () => {
player.volume = 0;
});
proxy(this.$volumeClose, 'click', () => {
player.volume = storage.get('volume');
});
hover($control, () => {
this.$volumePanel.classList.add('art-volume-panel-hover');
sleep(200).then(() => {
this.setVolumeHandle(player.volume);
});
}, () => {
this.$volumePanel.classList.remove('art-volume-panel-hover');
});
proxy(this.$volumePanel, 'click', event => {
player.volume = this.volumeChangeFromEvent(event);
});
proxy(this.$volumeHandle, 'mousedown', () => {
this.isDroging = true;
});
proxy(this.$volumeHandle, 'mousemove', event => {
if (this.isDroging) {
player.volume = this.volumeChangeFromEvent(event);
}
});
proxy(document, 'mouseup', () => {
if (this.isDroging) {
constructor(option) {
this.option = option;
this.isDroging = false;
}
});
}
}
volumeChangeFromEvent(event) {
const { left: panelLeft, width: panelWidth } = this.$volumePanel.getBoundingClientRect();
const { width: handleWidth } = this.$volumeHandle.getBoundingClientRect();
const percentage = clamp(event.x - panelLeft - handleWidth / 2, 0, panelWidth - handleWidth / 2) / (panelWidth - handleWidth);
return percentage;
}
apply(art, $control) {
const {
events: { proxy, hover },
player,
i18n,
storage,
} = art;
this.$volume = append($control, icons.volume);
this.$volumeClose = append($control, icons.volumeClose);
this.$volumePanel = append($control, '<div class="art-volume-panel"></div>');
this.$volumeHandle = append(this.$volumePanel, '<div class="art-volume-slider-handle"></div>');
tooltip(this.$volume, i18n.get('Mute'));
setStyle(this.$volumeClose, 'display', 'none');
setVolumeHandle(percentage = 0.7) {
const panelWidth = getStyle(this.$volumePanel, 'width');
const handleWidth = getStyle(this.$volumeHandle, 'width');
const width = handleWidth / 2 + (panelWidth - handleWidth) * percentage - handleWidth / 2;
setStyle(this.$volumeHandle, 'left', `${width}px`);
}
art.on('volumeChange', percentage => {
if (percentage === 0) {
setStyle(this.$volume, 'display', 'none');
setStyle(this.$volumeClose, 'display', 'flex');
} else {
setStyle(this.$volume, 'display', 'flex');
setStyle(this.$volumeClose, 'display', 'none');
}
});
art.on('video:volumechange', () => {
this.setVolumeHandle(player.volume);
});
proxy(this.$volume, 'click', () => {
player.volume = 0;
});
proxy(this.$volumeClose, 'click', () => {
player.volume = storage.get('volume');
});
hover(
$control,
() => {
this.$volumePanel.classList.add('art-volume-panel-hover');
sleep(200).then(() => {
this.setVolumeHandle(player.volume);
});
},
() => {
this.$volumePanel.classList.remove('art-volume-panel-hover');
},
);
proxy(this.$volumePanel, 'click', event => {
player.volume = this.volumeChangeFromEvent(event);
});
proxy(this.$volumeHandle, 'mousedown', () => {
this.isDroging = true;
});
proxy(this.$volumeHandle, 'mousemove', event => {
if (this.isDroging) {
player.volume = this.volumeChangeFromEvent(event);
}
});
proxy(document, 'mouseup', () => {
if (this.isDroging) {
this.isDroging = false;
}
});
}
volumeChangeFromEvent(event) {
const { left: panelLeft, width: panelWidth } = this.$volumePanel.getBoundingClientRect();
const { width: handleWidth } = this.$volumeHandle.getBoundingClientRect();
const percentage =
clamp(event.x - panelLeft - handleWidth / 2, 0, panelWidth - handleWidth / 2) / (panelWidth - handleWidth);
return percentage;
}
setVolumeHandle(percentage = 0.7) {
const panelWidth = getStyle(this.$volumePanel, 'width');
const handleWidth = getStyle(this.$volumeHandle, 'width');
const width = handleWidth / 2 + (panelWidth - handleWidth) * percentage - handleWidth / 2;
setStyle(this.$volumeHandle, 'left', `${width}px`);
}
}