Files
aifo-portal-web/pages/you_tube_style_video_player_page.html
steven 4d30803b60 Initial commit: AIFO official portal web.
Add static site, shared layout, and Node dev server with standard .gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 15:29:50 +08:00

242 lines
4.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video Player</title>
<style>
.yt-player {
color: #fff;
font-family: Arial, sans-serif;
}
.yt-player .container {
/* max-width: 1100px; */
margin: 0 auto;
padding: 12px;
padding-top: 20px;
display: grid;
grid-template-columns: 2.5fr 0.9fr;
gap: 16px;
background: #19191a;
}
.yt-player .player {
width: 100%;
/* border-radius: 12px; */
overflow: hidden;
background: black;
}
.yt-player .player iframe {
width: 100%;
height: 100%;
border: none;
}
.yt-player .list {
overflow-y: auto;
padding-right: 6px;
scroll-behavior: smooth;
}
.yt-player .list::-webkit-scrollbar {
width: 6px;
}
.yt-player .list::-webkit-scrollbar-thumb {
background: rgba(255,255,255,0.25);
border-radius: 999px;
}
.yt-player .item {
margin-bottom: 12px;
cursor: pointer;
transition: 0.2s;
display: flex;
justify-content: center;
}
.yt-player .item:hover {
transform: scale(1.03);
}
.yt-player .item.active {
border-right: 5px solid #a19e9b5c;
/* padding-right: 3px; */
}
.yt-player .thumb {
width: 100%;
max-width: 260px;
height: 130px;
/* border-radius: 10px; */
overflow: hidden;
position: relative;
}
.yt-player .thumb img {
width: 100%;
height: 100%;
object-fit: cover;
}
.yt-player .play-mini {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.yt-player .play-mini div {
width: 36px;
height: 30px;
/* background: rgba(0, 0, 0, 0.6); */
border-radius: 25%;
position: relative;
background: #F98715;
transform: scale(1.08);
}
.yt-player .play-mini div::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-35%, -50%);
width: 0;
height: 0;
border-left: 12px solid white;
border-top: 7px solid transparent;
border-bottom: 7px solid transparent;
}
@media (max-width: 900px) {
.yt-player .container {
grid-template-columns: 1fr;
}
.yt-player .player {
height: 260px !important;
}
}
@media(max-width: 768px) {
.yt-player .thumb {
max-width: unset;
}
}
</style>
</head>
<body>
<div class="yt-player">
<div class="container">
<div class="player" id="playerWrap">
<iframe id="player"
src="https://www.youtube.com/embed/48fvMsfZbXA?rel=0"
allowfullscreen>
</iframe>
</div>
<div class="list" id="list"></div>
</div>
</div>
<script>
const videos = [
{ id: "48fvMsfZbXA" },
{ id: "-zOBe7aB5ps" },
{ id: "2krWtQ9v4i4" },
];
const list = document.getElementById('list');
const player = document.getElementById('player');
const playerWrap = document.getElementById('playerWrap');
let currentId = videos[0].id;
function render() {
list.innerHTML = '';
videos.forEach(v => {
const item = document.createElement('div');
item.className = 'item' + (v.id === currentId ? ' active' : '');
item.innerHTML = `
<div class="thumb">
<img src="https://img.youtube.com/vi/${v.id}/hqdefault.jpg">
<div class="play-mini"><div></div></div>
</div>
`;
item.onclick = () => {
currentId = v.id;
player.src = `https://www.youtube.com/embed/${v.id}?autoplay=1`;
render();
syncHeight();
scrollToActive();
};
list.appendChild(item);
});
}
function syncHeight() {
const items = document.querySelectorAll('.yt-player .item');
if (items.length < 3) return;
let height = 0;
for (let i = 0; i < 3; i++) {
height += items[i].offsetHeight;
}
height += 17;
height *= 1.05;
playerWrap.style.height = height-10 + 'px';
list.style.height = height + 'px';
}
function scrollToActive() {
const active = document.querySelector('.yt-player .item.active');
if (!active) return;
const listRect = list.getBoundingClientRect();
const itemRect = active.getBoundingClientRect();
const offset = itemRect.top - listRect.top - list.clientHeight / 2 + itemRect.height / 2;
list.scrollBy({
top: offset,
behavior: 'smooth'
});
}
window.onload = () => {
render();
setTimeout(syncHeight, 100);
};
window.onresize = syncHeight;
</script>
</body>
</html>