视频播放UI
CSS:
* {
margin: 0;
padding: 0;
}
body {
height: 2000px;
}
/* 去掉全屏时显示的自带控制条 */
.mianVideo::-webkit-media-controls {
display: none !important;
}
.mianVideo {
width: 700px;
width: 1000px;
height: auto;
position: absolute;
top: 100px;
left: 30px;
}
.cloudVideoDiv {
position: absolute;
user-select: none;
overflow: hidden;
}
.controlPanelDiv {
position: absolute;
background-color: rgba(255, 252, 252, 0.5);
border-radius: 5px;
display: none;
height: 30px;
bottom: 0px;
left: 10px;
animation: controlPanelDiv 0.5s forwards;
opacity: 0;
}
@keyframes controlPanelDiv {
0% {}
100% {
bottom: 10px;
opacity: 1;
}
}
.progressBar {
position: absolute;
opacity: 0.8;
cursor: pointer;
}
.progressNum {
position: absolute;
right: 160px;
bottom: 4px;
}
.fullScreen {
position: absolute;
right: 5px;
bottom: 4px;
cursor: pointer;
}
.controlSound {
position: absolute;
right: 38px;
bottom: 0px;
cursor: pointer;
}
.controlSoundProgress {
position: absolute;
right: 35px;
bottom: 35px;
width: 35px;
height: 110px;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 3px;
display: none;
text-align: center;
}
.controlSoundProgress input {
width: 80px;
height: 6px;
transform-origin: 0% 100%;
transform: rotate(-90deg);
position: absolute;
top: 90%;
left: 60%;
}
.playAndPause {
position: absolute;
bottom: -2px;
left: 8px;
cursor: pointer;
}
.videoSpeed {
width: 52px;
position: absolute;
bottom: 4px;
right: 90px;
cursor: pointer;
font-weight: 600;
}
.videoSpeedList {
width: 60px;
position: absolute;
bottom: 35px;
right: 95px;
cursor: pointer;
font-weight: 600;
list-style: none;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 3px;
display: none;
}
.videoSpeedList li {
padding: 5px;
border-bottom: 1px solid black;
text-align: center;
}
.videoSpeedList li:hover {
background-color: rgba(255, 255, 255, 0.4);
}
.videoSpeedList li.select {
background-color: rgba(255, 255, 255, 0.6);
}
.customizePlaybackRate {
padding: 1px !important;
border: none !important;
}
.customizePlaybackRate input {
padding: 3px !important;
width: 95%;
height: 100%;
background-color: transparent;
border: none;
text-align: center;
font-weight: 600;
}
.customizePlaybackRate input::-webkit-input-placeholder {
color: black;
}
.customizePlaybackRate input:focus {
outline: none;
}
.replay {
cursor: pointer;
position: absolute;
top: 50%;
left: 43%;
transform: translate(-50%, -50%);
}
.loop {
cursor: pointer;
position: absolute;
top: 50%;
left: 57%;
transform: translate(-50%, -50%);
}
.setUp {
position: absolute;
bottom: 4px;
right: 73px;
cursor: pointer;
}
JS:(暂时没做优化什么的)
window.onload = function () {
const mianVideo = document.querySelector('.mianVideo');
// 视频的元数据加载后触发
mianVideo.addEventListener('loadedmetadata', () => {
const body = document.body;
const mianVideoPlaceAndSize = mianVideo.getBoundingClientRect();
// 获取mianVideo的zIndex
const mianVideoZIndex = getComputedStyle(mianVideo, null).zIndex;
// 创建视频上方的遮盖层
const cloudVideoDiv = document.createElement('div');
cloudVideoDiv.classList.add('cloudVideoDiv');
cloudVideoDiv.style.width = mianVideoPlaceAndSize.width + 'px';
cloudVideoDiv.style.height = mianVideoPlaceAndSize.height + 'px';
cloudVideoDiv.style.top = mianVideo.offsetTop + 'px';
cloudVideoDiv.style.left = mianVideo.offsetLeft + 'px';
// 使遮盖层的zIndex永远比视频大
mianVideoZIndex == 'auto' ? cloudVideoDiv.style.zIndex = '1' : cloudVideoDiv.style.zIndex =
parseInt(mianVideoZIndex) + 1;
body.appendChild(cloudVideoDiv);
// 创建控制面板
const controlPanelDiv = document.createElement('div');
controlPanelDiv.classList.add('controlPanelDiv');
controlPanelDiv.style.width = mianVideoPlaceAndSize.width - 20 + 'px';
cloudVideoDiv.appendChild(controlPanelDiv);
// 控制面板的显示和隐藏
cloudVideoDiv.addEventListener('mouseenter', () => controlPanelDiv.style.display = 'block');
cloudVideoDiv.addEventListener('mouseleave', () => controlPanelDiv.style.display = 'none');
// 创建进度条
const progressBar = document.createElement('input');
progressBar.setAttribute('type', 'range');
progressBar.setAttribute('min', 0);
progressBar.setAttribute('max', mianVideo.duration);
progressBar.value = 0;
progressBar.classList.add('progressBar');
progressBar.style.width = mianVideoPlaceAndSize.width - 340 + 'px';
progressBar.style.bottom = '5px';
progressBar.style.left = '40px';
controlPanelDiv.appendChild(progressBar);
// 为进度条添加事件
progressBar.addEventListener('input', () => {
mianVideo.currentTime = progressBar.value;
mianVideo.play();
cloudVideoDiv.style.backgroundColor = 'rgba(0, 0, 0, 0)';
document.querySelector('.replay').style.display = 'none';
document.querySelector('.loop').style.display = 'none';
});
// 为视频添加事件
mianVideo.addEventListener('timeupdate', () => {
progressBar.value = mianVideo.currentTime;
const currentNum = document.querySelector('.currentNum');
currentNum.innerHTML = formatTime(mianVideo.currentTime);
});
// 创建展示进度的数字
controlPanelDiv.insertAdjacentHTML('beforeend', `
00:00 /
${formatTime(mianVideo.duration)}
`);
// 创建全屏按钮
controlPanelDiv.insertAdjacentHTML('beforeend', `
`);
const fullScreen = document.querySelector('.fullScreen');
fullScreen.addEventListener('click', () => {
// 点击全屏
if (mianVideo.requestFullscreen) {
mianVideo.requestFullscreen();
} else if (mianVideo.webkitRequestFullscreen) {
mianVideo.webkitRequestFullscreen();
} else if (mianVideo.mozRequestFullScreen) {
mianVideo.mozRequestFullScreen();
} else if (mianVideo.msRequestFullscreen) {
mianVideo.msRequestFullscreen();
}
})
// 创建声音按钮
controlPanelDiv.insertAdjacentHTML('beforeend', ``);
const controlSound = document.querySelector('.controlSound');
const openSoundSvg = ``;
const closeSoundSvg =
``;
controlSound.innerHTML = openSoundSvg;
controlSound.addEventListener('click', () => {
const val = controlSoundProgress.querySelector('input').value;
if (val === '0') {
controlSound.innerHTML = openSoundSvg;
controlSoundProgress.querySelector('input').value = '100';
mianVideo.volume = 1;
} else {
controlSound.innerHTML = closeSoundSvg;
controlSoundProgress.querySelector('input').value = '0';
mianVideo.volume = 0;
}
controlSoundProgressValue.innerHTML = controlSoundProgress.querySelector('input').value;
});
// 创建声音控制条
controlPanelDiv.insertAdjacentHTML('beforeend', `
100
`);
// 声音控制条的显示和隐藏
const controlSoundProgress = document.querySelector('.controlSoundProgress');
const controlSoundProgressValue = document.querySelector('.controlSoundProgressValue');
controlSound.addEventListener('mouseenter', () => controlSoundProgress.style.display = 'block');
controlSoundProgress.addEventListener('mouseleave', () => controlSoundProgress.style.display =
'none');
controlSoundProgress.addEventListener('input', () => {
const val = controlSoundProgress.querySelector('input').value;
val <= 0 ? controlSound.innerHTML = closeSoundSvg : controlSound.innerHTML =
openSoundSvg;
mianVideo.volume = val / 100;
controlSoundProgressValue.innerHTML = `${val}`;
});
// 创建播放|暂停按钮
controlPanelDiv.insertAdjacentHTML('beforeend', ``);
const playAndPause = document.querySelector('.playAndPause');
const playSvg =
``;
const pauseSvg =
``;
playAndPause.innerHTML = playSvg;
playAndPause.addEventListener('click', () => {
if (mianVideo.paused) {
mianVideo.play();
playAndPause.innerHTML = playSvg;
} else {
mianVideo.pause();
playAndPause.innerHTML = pauseSvg;
}
});
// 创建倍速按钮
controlPanelDiv.insertAdjacentHTML('beforeend', `倍速`);
const videoSpeed = document.querySelector('.videoSpeed');
controlPanelDiv.insertAdjacentHTML('beforeend', `
- 0.5×
- 0.75×
- 1×
- 1.25×
- 1.5×
- 2×
-
`);
const videoSpeedList = document.querySelector('.videoSpeedList');
const videoSpeedListLi = document.querySelectorAll('.videoSpeedList li[data-playbackRate]');
const customizePlaybackRate = document.querySelector('.customizePlaybackRate');
const customizePlaybackRateInput = document.querySelector('.customizePlaybackRate input');
videoSpeed.addEventListener('mouseenter', () => videoSpeedList.style.display = 'block')
videoSpeedList.addEventListener('mouseleave', () => videoSpeedList.style.display = 'none');
videoSpeedListLi.forEach(item => {
item.addEventListener('click', () => {
videoSpeedListLi.forEach(item => item.classList.remove('select'));
customizePlaybackRate.classList.remove('select')
item.classList.add('select')
mianVideo.playbackRate = item.getAttribute('data-playbackRate');
});
});
customizePlaybackRateInput.addEventListener('input', () => {
videoSpeedListLi.forEach(item => item.classList.remove('select'));
customizePlaybackRate.classList.add('select')
mianVideo.playbackRate = customizePlaybackRateInput.value;
if (!customizePlaybackRateInput.value) mianVideo.playbackRate = 1;
});
// 创建重新播放按钮
const replaySvg =
''
// 创建循环播放按钮
const loopSvg =
''
mianVideo.addEventListener('ended', () => {
cloudVideoDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
if (document.querySelector('.replay')) {
document.querySelector('.replay').style.display = 'block';
document.querySelector('.loop').style.display = 'block';
} else {
cloudVideoDiv.insertAdjacentHTML('beforeend', replaySvg);
cloudVideoDiv.insertAdjacentHTML('beforeend', loopSvg);
}
const replay = document.querySelector('.replay');
const loop = document.querySelector('.loop');
function endedClick() {
mianVideo.currentTime = 0;
mianVideo.play();
cloudVideoDiv.style.backgroundColor = 'rgba(0, 0, 0, 0)';
replay.style.display = 'none';
loop.style.display = 'none';
}
replay.addEventListener('click', endedClick);
loop.addEventListener('click', () => {
mianVideo.loop = true;
endedClick();
});
});
// 创建设置按钮
const setUpSvg = ''
controlPanelDiv.insertAdjacentHTML('beforeend', setUpSvg);
});
// 格式化时间
function formatTime(t) {
let m = parseInt(t % 3600 / 60);
m = m < 10 ? '0' + m : m;
let s = parseInt(t % 60);
s = s < 10 ? '0' + s : s;
return m + ':' + s;
}
}