web版本的视频video标签缩放项目
- 支持 mp4 flv m3u8等视频播放
- 支持任意缩放比例的鼠标手势,以及在缩放条件的拖拽手势
- 支持最大化下的视频缩放
- 当前进度标签的定义属性
- 支持步进缩略图
- 全面超越xgplayer
- 工业化场景适用
- 100%还原视频影像
已经开源 项目地址
影片为
《网络谜踪2》索尼
部分项目截图
全屏模式
项目参考
Canvas鼠标滚轮缩放以及画布拖动(图文并茂版)本文会带大家认识Canvas中常用的坐标变换方法 translate - 掘金
GitHub - astonishqft/scanvas-translate-and-scale: Canvas画布实现鼠标滚轮缩放和画布拖动
部分源代码的参考
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Canvas鼠标滚轮缩放和拖放</title> <style> canvas { border: solid 1px #000; margin: 0px auto; display: block; } .options { display: flex; justify-content: center; height: 44px; align-items: center; } button { margin-left: 15px; } </style> </head> <body> <div class="options"> <button onclick="zoomIn()">放大 +</button> <button onclick="zoomOut()">缩小 -</button> <button onclick="reset()">还原</button> </div> <canvas id="canvas"></canvas> <script> class Scene { offset = { x: 0, y: 0 }; // 拖动偏移 curOffset = { x: 0, y: 0 }; // 记录上一次的偏移量 mousePosition = { x: 0, y: 0 }; // 记录鼠标滚轮点击时的坐标位置 maxScale = 8; minScale = 0.4; scaleStep = 0.2; scale = 1; preScale = 1; x = 0; // 记录鼠标点击Canvas时的横坐标 y = 0; // 记录鼠标点击Canvas时的纵坐标 constructor(id, options = { width: 600, height: 400 }) { this.canvas = document.querySelector('#' + id) this.width = options.width; this.height = options.height; this.canvas.width = options.width; this.canvas.height = options.height; this.ctx = this.canvas.getContext('2d'); this.onMousedown = this.onMousedown.bind(this); this.onMousemove = this.onMousemove.bind(this); this.onMouseup = this.onMouseup.bind(this); this.onMousewheel = this.onMousewheel.bind(this); this.canvas.addEventListener('mousewheel', this.onMousewheel); this.canvas.addEventListener('mousedown', this.onMousedown); } onMousewheel(e) { e.preventDefault(); this.mousePosition.x = e.offsetX; // 记录当前鼠标点击的横坐标 this.mousePosition.y = e.offsetY; // 记录当前鼠标点击的纵坐标 if (e.wheelDelta > 0) { // 放大 this.scale = parseFloat((this.scaleStep + this.scale).toFixed(2)); // 解决小数点运算丢失精度的问题 if (this.scale > this.maxScale) { this.scale = this.maxScale; return; } } else { // 缩小 this.scale = parseFloat((this.scale - this.scaleStep).toFixed(2)); // 解决小数点运算丢失精度的问题 if (this.scale < this.minScale) { this.scale = this.minScale; return; } } this.zoom(); } zoom() { this.offset.x = this.mousePosition.x - (this.mousePosition.x - this.offset.x) * this.scale / this.preScale; this.offset.y = this.mousePosition.y - (this.mousePosition.y - this.offset.y) * this.scale / this.preScale; this.paint(this.ctx); this.preScale = this.scale; this.curOffset.x = this.offset.x; this.curOffset.y = this.offset.y; } onMousedown(e) { if (e.button === 0) { // 鼠标左键 this.x = e.x; this.y = e.y window.addEventListener('mousemove', this.onMousemove); window.addEventListener('mouseup', this.onMouseup) } } onMousemove(e) { this.offset.x = this.curOffset.x + (e.x - this.x); this.offset.y = this.curOffset.y + (e.y - this.y); this.paint(); } onMouseup() { this.curOffset.x = this.offset.x; this.curOffset.y = this.offset.y; window.removeEventListener('mousemove', this.onMousemove); window.removeEventListener('mouseup', this.onMouseup); } zoomIn() { this.scale += this.scaleStep; if (this.scale > this.maxScale) { this.scale = this.maxScale; return; } this.mousePosition.x = this.width / 2; this.mousePosition.y = this.height / 2; this.zoom(); } zoomOut() { this.scale -= this.scaleStep; if (this.scale < this.minScale) { this.scale = this.minScale; return; } this.mousePosition.x = this.width / 2; this.mousePosition.y = this.height / 2; this.zoom(); } // 重置 reset = function () { this.clear(); this.scale = 1; // 当前缩放 this.preScale = 1; // 上一次缩放 this.offset = { x: 0, y: 0 }; // 拖动偏移 this.curOffset = { x: 0, y: 0 }; // 当前偏移 this.mousePosition = { x: 0, y: 0 }; this.draw(); }; draw() { this.ctx.fillStyle = 'red'; this.ctx.fillRect(50, 50, 50, 50); this.ctx.fillStyle = 'green'; this.ctx.fillRect(150, 150, 50, 50); } clear() { this.canvas.width = this.width; } paint() { this.clear(); this.ctx.translate(this.offset.x, this.offset.y); this.ctx.scale(this.scale, this.scale); this.draw(); } } let scene = new Scene('canvas'); scene.draw(); // 放大 function zoomIn() { scene.zoomIn(); } // 缩小 function zoomOut() { scene.zoomOut(); } // 还原 function reset() { scene.reset(); } </script> </body> </html>
漫思
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
2024-02-19 c# WPF 布局控件
2024-02-19 C# 12 中的新增功能
2023-02-19 10年磨一剑,.net 公共类库,终于初版
2019-02-19 回车登录页面的问题