This commit is contained in:
2026-06-01 00:21:44 +08:00
parent 2e9fb16579
commit ad0d0075c8

View File

@@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>视频圆形放大镜(修复版)</title>
<title>视频圆形放大镜(最终流畅版)</title>
<script src="./lazyload.min.js"></script>
<style>
* {
@@ -43,21 +43,25 @@
/* 放大镜样式 */
.video-magnifier {
position: fixed;
width: 380px;
height: 380px;
width: 400px;
height: 400px;
border-radius: 50%;
border: 3px solid #fff;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
border: 3px solid rgba(255, 255, 255, 0.9);
box-shadow: 0 0 30px rgba(0, 0, 0, 0.6), 0 0 0 4px rgba(0, 0, 0, 0.3);
pointer-events: none;
overflow: hidden;
z-index: 9999;
z-index: 10000;
display: none;
backdrop-filter: blur(10px);
transition: left 0.02s ease-out, top 0.02s ease-out;
background: transparent !important;
}
.video-magnifier video {
position: absolute;
width: 100%;
height: 100%;
background: transparent !important;
}
</style>
</head>
@@ -81,9 +85,27 @@
const magnifier = document.getElementById('magnifier');
const magnifierVideo = document.getElementById('magnifierVideo');
let hoveredVideo = null;
let magnifierEnabled = false;
// ==================== 流畅缩放配置 ====================
const minMagnifierSize = 400; // 最小尺寸
const maxMagnifierSize = 600; // 最大尺寸(防卡顿)
const stepSize = 100; // 每次增减 40px流畅不卡
let magnifierSize = 400;
const scale = 4;
// 记录当前鼠标位置
let currentMouseX = 0;
let currentMouseY = 0;
let lazyLoadInstance = null;
// 实时记录鼠标位置
document.addEventListener('mousemove', (e) => {
currentMouseX = e.clientX;
currentMouseY = e.clientY;
});
const initLazyLoad = () => {
if (lazyLoadInstance) return;
lazyLoadInstance = new LazyLoad({
@@ -156,28 +178,80 @@
};
document.onclick = toggleScroll;
// 强制更新放大镜到当前鼠标位置
function updateMagnifierToMouse() {
if (!magnifierEnabled) return;
magnifier.style.width = magnifierSize + 'px';
magnifier.style.height = magnifierSize + 'px';
const element = document.elementFromPoint(currentMouseX, currentMouseY);
if (!element || element.tagName !== 'VIDEO') {
magnifier.style.display = 'none';
return;
}
const video = element;
if (hoveredVideo !== video) {
hoveredVideo = video;
magnifierVideo.src = video.dataset.src || video.src;
magnifierVideo.play().catch(() => { });
}
magnifier.style.display = 'block';
magnifier.style.left = (currentMouseX - magnifierSize / 2) + 'px';
magnifier.style.top = (currentMouseY - magnifierSize / 2) + 'px';
const rect = video.getBoundingClientRect();
const relativeX = (currentMouseX - rect.left) / rect.width;
const relativeY = (currentMouseY - rect.top) / rect.height;
const offsetX = -(relativeX - 0.5) * rect.width * scale;
const offsetY = -(relativeY - 0.5) * rect.height * scale;
magnifierVideo.style.transform = `scale(${scale}) translate(${offsetX}px, ${offsetY}px)`;
}
document.onkeydown = (e) => {
const { keyCode } = e;
if (keyCode === 79) {
// F键开关放大镜
if (keyCode === 70) {
e.preventDefault();
if (currentVideo) open(currentVideo.author);
magnifierEnabled = !magnifierEnabled;
if (magnifierEnabled) {
updateMagnifierToMouse();
} else {
magnifier.style.display = 'none';
magnifierVideo.pause();
magnifierVideo.src = '';
hoveredVideo = null;
}
}
if (keyCode === 32) {
// + 键:每次增加 40px最大 800px
if (keyCode === 107 || keyCode === 187) {
e.preventDefault();
toggleScroll();
if (magnifierSize < maxMagnifierSize) {
magnifierSize += stepSize;
updateMagnifierToMouse();
}
}
if (keyCode === 82) {
// - 键:每次减少 40px最小 400px
if (keyCode === 109 || keyCode === 189) {
e.preventDefault();
scrollSpeed = defaultSpeed;
}
if (keyCode === 40) {
e.preventDefault();
scrollSpeed += 2;
}
if (keyCode === 38) {
e.preventDefault();
scrollSpeed > defaultSpeed && (scrollSpeed -= 2);
if (magnifierSize > minMagnifierSize) {
magnifierSize -= stepSize;
updateMagnifierToMouse();
}
}
// 其他原有按键
if (keyCode === 79) { e.preventDefault(); if (currentVideo) open(currentVideo.author); }
if (keyCode === 32) { e.preventDefault(); toggleScroll(); }
if (keyCode === 82) { e.preventDefault(); scrollSpeed = defaultSpeed; }
if (keyCode === 40) { e.preventDefault(); scrollSpeed += 2; }
if (keyCode === 38) { e.preventDefault(); scrollSpeed > defaultSpeed && (scrollSpeed -= 2); }
};
let scrollTimer = null;
@@ -194,45 +268,19 @@
}, 150);
};
// ==================== 已修复:鼠标指哪放大哪 ====================
const scale = 4; // 放大倍数
ul.addEventListener('mousemove', (e) => {
if (e.target.tagName !== 'VIDEO') return;
const video = e.target;
// 切换视频时更新放大镜源
if (hoveredVideo !== video) {
hoveredVideo = video;
magnifierVideo.src = video.dataset.src || video.src;
magnifierVideo.play();
}
// 放大镜跟随鼠标(中心对齐)
magnifier.style.display = 'block';
magnifier.style.left = (e.clientX - magnifier.offsetWidth / 2) + 'px';
magnifier.style.top = (e.clientY - magnifier.offsetHeight / 2) + 'px';
// 获取视频元素的位置和尺寸
const rect = video.getBoundingClientRect();
// 鼠标在视频内的相对坐标0~1
const relativeX = (e.clientX - rect.left) / rect.width;
const relativeY = (e.clientY - rect.top) / rect.height;
// 核心修复:让鼠标位置在放大镜正中心
const offsetX = -(relativeX - 0.5) * rect.width * scale;
const offsetY = -(relativeY - 0.5) * rect.height * scale;
magnifierVideo.style.transform = `scale(${scale}) translate(${offsetX}px, ${offsetY}px)`;
if (!magnifierEnabled) return;
updateMagnifierToMouse();
});
// 移出视频区域关闭放大镜
ul.addEventListener('mouseleave', () => {
if (!magnifierEnabled) return;
magnifier.style.display = 'none';
magnifierVideo.pause();
magnifierVideo.src = '';
hoveredVideo = null;
}, true);
// 原有播放逻辑
ul.addEventListener("mouseenter", (e) => {
if (e.target.tagName === "VIDEO") {
e.target.readyState >= 2 && e.target.play();