
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.container {
width: 500px;
height: 500px;
margin: auto;
overflow: hidden;
border: 1px solid;
}
</style>
</head>
<body>
<div class="container">
<video
id="videoEl"
autoplay
controls
width="500"
height="500"
src="https://v26-web.douyinvod.com/18f2b18702db6744e33d7cc87f731bdf/636cc632/video/tos/cn/tos-cn-ve-15c001-alinc2/b21ddffbd734459f931ae2289eeb5449/?a=6383&ch=5&cr=3&dr=0&lr=all&cd=0%7C0%7C0%7C3&cv=1&br=1692&bt=1692&cs=0&ds=6&ft=rVWEerwwZRcZseFo3PDS6kFgAX1tG0ynnS9eFEj5tJr12ni7t&mime_type=video_mp4&qs=0&rc=OWZpOTg3aGZmZzU0OjQ2M0BpM3lkbzQ6ZjNtZjMzNGkzM0BgY2EuLi0yXl8xLV8wLTQwYSNpc15scjRfb2JgLS1kLS9zcw%3D%3D&l=2022111016363401015015410227004C29"
></video>
</div>
<div class="log"></div>
<script type="text/javascript">
const container = document.querySelector(".container");
const videoEl = document.getElementById("videoEl");
const log = document.querySelector(".log");
let result = {},
x = 0,
y = 0,
scale = 1,
minScale = 1,
maxScale = 4,
isPointerdown = false,
diff = { x: 0, y: 0 },
lastPointermove = { x: 0, y: 0 };
const getSize = (videoWidth, videoHeight, maxWidth, maxHeight) => {
const videoRatio = videoWidth / videoHeight;
const maxRatio = maxWidth / maxHeight;
let width, height;
if (videoRatio >= maxRatio) {
if (videoWidth > maxWidth) {
width = maxWidth;
height = (maxWidth / videoWidth) * videoHeight;
} else {
width = videoWidth;
height = videoHeight;
}
} else {
if (videoHeight > maxHeight) {
width = (maxHeight / videoHeight) * videoWidth;
height = maxHeight;
} else {
width = videoWidth;
height = videoHeight;
}
}
return { width: width, height: height };
};
result = getSize(
videoEl.width,
videoEl.height,
container.clientWidth,
container.clientHeight
);
const wheelZoom = () => {
container.addEventListener("wheel", (e) => {
let ratio = 1.1;
if (e.deltaY > 0) {
ratio = 1 / 1.1;
}
const _scale = scale * ratio;
if (_scale > maxScale) {
ratio = maxScale / scale;
scale = maxScale;
} else if (_scale < minScale) {
ratio = minScale / scale;
scale = minScale;
} else {
scale = _scale;
}
console.log(ratio);
if (e.target.tagName === "VIDEO") {
const origin = {
x: (ratio - 1) * result.width * 0.5,
y: (ratio - 1) * result.height * 0.5,
};
x -= (ratio - 1) * (e.offsetX - x) - origin.x;
y -= (ratio - 1) * (e.offsetY - y) - origin.y;
}
videoEl.style.transform =
"translate3d(" + x + "px, " + y + "px, 0) scale(" + scale + ")";
if (scale === 1) {
videoEl.style.transform = "scale(" + scale + ")";
}
log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(
0
)}<br>scale = ${scale.toFixed(5)}`;
e.preventDefault();
});
};
const drag = () => {
videoEl.addEventListener("pointerdown", (e) => {
isPointerdown = true;
lastPointermove = { x: e.clientX, y: e.clientY };
});
videoEl.addEventListener("pointermove", (e) => {
if (isPointerdown) {
const current1 = { x: e.clientX, y: e.clientY };
diff.x = current1.x - lastPointermove.x;
diff.y = current1.y - lastPointermove.y;
lastPointermove = { x: current1.x, y: current1.y };
x += diff.x;
y += diff.y;
videoEl.style.transform = `translate3d(${x}px,${y}px, 0) scale(${scale})`;
log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(
0
)}<br>scale = ${scale.toFixed(5)}`;
}
e.preventDefault();
});
videoEl.addEventListener("pointerup", (e) => {
if (isPointerdown) {
isPointerdown = false;
}
});
};
drag();
wheelZoom();
</script>
</body>
</html>