当前位置: 首页 > news >正文

Vue 框选区域放大(纯JavaScript实现)

需求:长按鼠标左键框选区域,松开后放大该区域,继续框选继续放大,反向框选恢复原始状态
实现思路:根据鼠标的落点,放大要显示的内容(内层盒子),然后利用水平偏移和垂直偏移,让外层展示的窗口(外层盒子)只看到刚刚框选的大概区域,具体代码如下
<template><div><divclass="selectable_container"@mousedown="handleMouseDown"@mousemove="handleMouseMove"@mouseup="handleMouseUp"><divclass="zoomable_element":style="{userSelect: 'none',left: innerLeft + 'px',top: innerTop + 'px',width: innerWidth + 'px',height: innerHeight + 'px',}"><imgsrc="./img/test1.jpg"style="width: 100%;height: 100%;user-select: none;pointer-events: none;"alt=""/></div><div class="selectable_element" id="selectable_element"></div></div></div>
</template><script>
export default {data() {return {startX: 0,startY: 0,endX: 0,endY: 0,isSelecting: false, //是否正在款选closeFlag: false, //是否退出放大状态offsetinner_left: 0, //外层容器水平偏移offsetinner_top: 0, //外层容器垂直偏移outerWidth: 0, //外层盒子宽度outerHeight: 0, //外层盒子高度zoomRatio: 1,innerWidth: "100%", //内层盒子宽度 初始状态等于外层盒子innerHeight: "100%", //内层盒子高度innerTop: 0, //内层盒子垂直偏移innerLeft: 0, //内层盒子水平偏移selectionLeft: 0, //框选区域水平偏移selectionTop: 0, //框选区域垂直偏移selectionWidth: 0, //框选区域宽度selectionHeight: 0, //框选区域高度,};},mounted() {const dom_mask = window.document.querySelector(".selectable_container");const rect_select = dom_mask.getClientRects()[0];this.offsetinner_left = rect_select.left; //水平偏移this.offsetinner_top = rect_select.top; //垂直偏移this.outerWidth = Math.ceil(rect_select.width);this.outerHeight = Math.ceil(rect_select.height);this.innerWidth = this.outerWidth;this.innerHeight = this.outerHeight;},methods: {handleMouseDown(event) {if (event.button === 0) {// 判断是否为鼠标左键按下this.startX = event.clientX - this.offsetinner_left;this.startY = event.clientY - this.offsetinner_top;this.isSelecting = true;var dom = document.getElementById("selectable_element");if (dom) {dom.style.left = this.startX + "px";dom.style.top = this.startY + "px";}}},handleMouseMove(event) {if (this.isSelecting) {this.closeFlag = false;this.endX = event.clientX - this.offsetinner_left;this.endY = event.clientY - this.offsetinner_top;var selectionLeft, selectionTop, selectionWidth, selectionHeight;selectionWidth = Math.abs(this.endX - this.startX);selectionHeight = Math.abs(this.endY - this.startY);// 右下if (this.endY >= this.startY && this.endX >= this.startX) {selectionLeft = this.startX;selectionTop = this.startY;}// 左下else if (this.endY >= this.startY && this.endX <= this.startX) {selectionLeft = this.endX;selectionTop = this.startY;}// 右上else if (this.endY <= this.startY && this.endX >= this.startX) {selectionLeft = this.startX;selectionTop = this.endY;}// 左上else if (this.endY <= this.startY && this.endX <= this.startX) {selectionLeft = this.endX;selectionTop = this.endY;this.closeFlag = true;}selectionLeft = Math.ceil(selectionLeft);selectionTop = Math.ceil(selectionTop);selectionWidth = Math.ceil(selectionWidth);selectionHeight = Math.ceil(selectionHeight);var dom = document.getElementById("selectable_element");if (dom) {dom.style.left = selectionLeft + "px";dom.style.top = selectionTop + "px";dom.style.width = selectionWidth + "px";dom.style.height = selectionHeight + "px";}this.selectionLeft = 0 - this.innerLeft + selectionLeft;this.selectionTop = 0 - this.innerTop + selectionTop;this.selectionWidth = selectionWidth;this.selectionHeight = selectionHeight;}},handleMouseUp(event) {// 判断是否为鼠标左键松开if (event.button === 0 && this.isSelecting) {// 左上清除if (this.closeFlag) {this.isSelecting = false;this.closeFlag = false;var dom = document.getElementById("selectable_element");if (dom) {dom.style.left = "0px";dom.style.top = "0px";dom.style.width = "0px";dom.style.height = "0px";}this.innerWidth = this.outerWidth;this.innerHeight = this.outerHeight;this.innerLeft = 0;this.innerTop = 0;return;}this.isSelecting = false;this.zoomRatio = Math.min(this.outerWidth / this.selectionWidth,this.outerHeight / this.selectionHeight).toFixed(2);this.zoomRatio = Number(this.zoomRatio);// console.log(this.zoomRatio);var innerWidth = Math.ceil(this.innerWidth * this.zoomRatio);var innerHeight = Math.ceil(this.innerHeight * this.zoomRatio);var innerLeft = 0 - this.selectionLeft * this.zoomRatio;var innerTop = 0 - this.selectionTop * this.zoomRatio;// 居中处理innerLeft =innerLeft +(this.outerWidth - this.selectionWidth * this.zoomRatio) / 2;innerTop =innerTop +(this.outerHeight - this.selectionHeight * this.zoomRatio) / 2;// 补位处理if (innerWidth + innerLeft < this.outerWidth) {// console.log("水平补位");innerLeft = innerLeft + this.outerWidth - (innerWidth + innerLeft);}if (innerHeight + innerTop < this.outerHeight) {// console.log("垂直补位");innerTop = innerTop + this.innerHeight - (innerHeight + innerTop);}this.innerWidth = innerWidth;this.innerHeight = innerHeight;this.innerLeft = innerLeft;this.innerTop = innerTop;var dom = document.getElementById("selectable_element");if (dom) {dom.style.left = "0px";dom.style.top = "0px";dom.style.width = "0px";dom.style.height = "0px";}}},},
};
</script>
<style lang="scss" scoped>
// 外层可视窗口
.selectable_container {position: relative;width: 800px;height: 450px;border: 1px solid #ccc;overflow: hidden;
}
// 框选动作临时盒子
.selectable_element {position: absolute;border: 1px solid red;
}
// 内层内容盒子 需要缩放
.zoomable_element {position: absolute;left: 0;top: 0;
}
</style>

在这里插入图片描述

相关文章:

Vue 框选区域放大(纯JavaScript实现)

需求&#xff1a;长按鼠标左键框选区域&#xff0c;松开后放大该区域&#xff0c;继续框选继续放大&#xff0c;反向框选恢复原始状态 实现思路&#xff1a;根据鼠标的落点&#xff0c;放大要显示的内容&#xff08;内层盒子&#xff09;&#xff0c;然后利用水平偏移和垂直偏…...

C#加密与java 互通

文章目录 前言对方接口签名要求我方对接思路1.RSA 加密2.AES256加密 完整的加密帮助类 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 在我们对接其他公司接口的时候&#xff0c;时常会出现对方使用的开发语言和我方使用的开发语言不同的情况&#xff…...

C#【进阶】特殊语法

特殊语法、值和引用类型 特殊语法 文章目录 特殊语法1、var隐式类型2、设置对象初始值3、设置集合初始值4、匿名类型5、可空类型6、空合并操作符7、内插字符串8、单句逻辑简略写法 值和引用类型1、判断值和引用类型2、语句块3、变量的生命周期4、结构体中的值和引用5、类中的值…...

c语言之向文件读写数据块

c语言需要向文件读写数据块需要用到fread语句和fwrite语句 fread语句的语法格式 fread(butter,size,count,fp) butter&#xff1a;读取的数据存入内存地址 size:读取的字节大小 count:读取数据的个数 fp:读取的文件指针 fwrite语句语法格式 fwrite(butter,size,count,fp…...

6键编程智能照明:编程指南与深度解析

6键编程智能照明&#xff1a;编程指南与深度解析 随着智能家居的普及&#xff0c;智能照明系统逐渐成为现代家庭不可或缺的一部分。而6键编程智能照明&#xff0c;以其高度的灵活性和个性化设置&#xff0c;受到了越来越多消费者的青睐。那么&#xff0c;如何对6键编程智能照明…...

sql server 中的6种约束

一、约束定义 约束是用于定义和实施表的规则和限制&#xff0c;以确保数据的完整性和一致性。 即对一张表中的属性操作进行限制。 二、约束分类 通过定义约束&#xff0c;可以对数据库中的数据进行限制&#xff0c;以下是常见的约束&#xff1a; 1. 主键约束&#xff08;Pr…...

师彼长技以助己(2)产品思维

师彼长技以助己&#xff08;2&#xff09;产品思维 前言 我把产品思维称之为&#xff1a;人生底层的能力以及蹉跎别人还蹉跎自己的能力&#xff0c;前者说明你应该具备良好产品思维原因&#xff0c;后者是你没有好的产品思维去做产品带来的灾难。 人欲即天理 请大家谈谈看到这…...

Redis学习笔记【基础篇】

SQL vs NOSQL SQL&#xff08;Structured Query Language&#xff09;和NoSQL&#xff08;Not Only SQL&#xff09;是两种不同的数据库处理方式&#xff0c;它们在多个维度上有所差异&#xff0c;主要区别包括&#xff1a; 数据结构: SQL&#xff08;关系型数据库&#xff09;…...

【文献阅读】基于模型设计的汽车软件质量属性

参考文献&#xff1a;《基于模型设计满足汽车软件质量和快速交付的挑战》&#xff0c;深向科技在2024年MATLAB XEPO大会的演讲 Tips&#xff1a;KISS原则&#xff0c;全称为“Keep It Simple, Stupid”&#xff0c;直译为“保持简单&#xff0c;愚蠢的人也能懂”...

撸广告赚金币小游戏app开发

在app上投放广告有哪些注意事项&#xff1f; 在app上投放广告需要注意以下几个方面。 首先&#xff0c;要选择合适的广告形式。根据自己的需求和目标受众&#xff0c;选择合适的广告形式&#xff0c;如横幅广告、插屏广告、视频广告等。不同的广告形式适用于不同的场景和目标…...

海外高清短视频:四川京之华锦信息技术公司

海外高清短视频&#xff1a;探索世界的新窗口 在数字化时代的浪潮下&#xff0c;海外高清短视频成为了人们探索世界、了解异国风情的新窗口。四川京之华锦信息技术公司这些短视频以其独特的视角、丰富的内容和高清的画质&#xff0c;吸引了无数观众的目光&#xff0c;让人们足…...

16:00面试,16:08就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到8月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…...

Android MediaCodec 简明教程(九):使用 MediaCodec 解码到纹理,使用 OpenGL ES 进行处理,并编码为 MP4 文件

系列文章目录 Android MediaCodec 简明教程&#xff08;一&#xff09;&#xff1a;使用 MediaCodecList 查询 Codec 信息&#xff0c;并创建 MediaCodec 编解码器Android MediaCodec 简明教程&#xff08;二&#xff09;&#xff1a;使用 MediaCodecInfo.CodecCapabilities 查…...

Neo4j安装部署及python连接neo4j操作

Neo4j安装部署及python连接neo4j操作 Neo4j安装和环境配置 安装依赖库&#xff1a; sudo apt-get install wget curl nano software-properties-common dirmngr apt-transport-https gnupg gnupg2 ca-certificates lsb-release ubuntu-keyring unzip -y 增加Neo4 GPG key&…...

一维时间序列信号的改进小波降噪方法(MATLAB R2021B)

目前国内外对于小波分析在降噪方面的方法研究中&#xff0c;主要有小波分解与重构法降噪、小波阈值降噪、小波变换模极大值法降噪等三类方法。 (1)小波分解与重构法降噪 早在1988 年&#xff0c;Mallat提出了多分辨率分析的概念&#xff0c;利用小波分析的多分辨率特性进行分…...

Java整合EasyExcel实战——3(上下列相同合并单元格策略)

参考&#xff1a;https://juejin.cn/post/7322156759443095561?searchId202405262043517631094B7CCB463FDA06https://juejin.cn/post/7322156759443095561?searchId202405262043517631094B7CCB463FDA06 准备条件 依赖 <dependency><groupId>com.alibaba</gr…...

dmdts连接kingbase8报错

dmdts连接kingbase报错 环境介绍1 人大金仓jdbc配置2 dmdts 人大金仓jdbc默认配置3 dmdts 修改jdbc配置4 达梦产品学习使用列表 环境介绍 dts版本 使用dmdts连接kingbase金仓数据库报错 无效的URL 对比jdbc连接串,修改配置解决 1 人大金仓jdbc配置 配置URL模版信息等 类名…...

【算法训练 day44 分割等和子集】

目录 一、分割等和子集-LeetCode 416思路实现代码1.二维dp代码2.一维dp代码 问题总结 一、分割等和子集-LeetCode 416 Leecode链接: leetcode 416 文章链接: 代码随想录 视频链接: B站 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&…...

前端实习记录——git篇(一些问题与相关命令)

1、版本控制 &#xff08;1&#xff09;版本回滚 git log // 查看版本git reset --mixed HEAD^ // 回滚到修改状态&#xff0c;文件内容没有变化git reset --soft HEAD^ // 回滚暂存区&#xff0c;^的个数代表几个版本git reset --hard HEAD^ // 回滚到修改状态&#xff…...

XML Web 服务技术解析:WSDL 与 SOAP 原理、应用案例一览

XML Web服务是一种用于在网络上发布、发现和使用应用程序组件的技术。它基于一系列标准和协议&#xff0c;如WSDL、SOAP、RDF和RSS。下面是一些相关的内容&#xff1a; WSDL&#xff08;Web服务描述语言&#xff09;&#xff1a;用于描述Web服务的基于XML的语言&#xff0c;定义…...

AI驱动代码审查:Cursor与Git工作流融合实践

1. 项目概述&#xff1a;当AI代码助手遇上代码审查最近在GitHub上看到一个挺有意思的项目&#xff0c;叫guinacio/cursor-review。光看名字&#xff0c;你可能会觉得这又是一个普通的代码审查工具&#xff0c;但点进去仔细研究&#xff0c;你会发现它的核心思路非常巧妙&#x…...

从单一AI到智能体集群:构建模块化AI协作系统的核心原理与实践

1. 项目概述&#xff1a;当AI学会“开会”&#xff0c;一个开源智能体集群的诞生最近在GitHub上看到一个挺有意思的项目&#xff0c;叫daveshap/OpenAI_Agent_Swarm。光看名字&#xff0c;你可能会觉得这又是一个调用OpenAI API的简单封装库。但如果你点进去&#xff0c;花上十…...

Git Worktree CLI工具:告别分支切换焦虑,实现高效并行开发

1. 项目概述与核心价值如果你和我一样&#xff0c;长期在多个Git分支间穿梭&#xff0c;同时维护着几个不同的功能特性或修复补丁&#xff0c;那你一定对那种在分支间反复切换、代码状态混乱、甚至不小心提交到错误分支的“切分支焦虑症”深有体会。传统的git checkout或git sw…...

DOM 浏览器

DOM 浏览器 引言 DOM(文档对象模型)是浏览器中处理HTML和XML文档的标准方式。它允许开发人员通过编程方式访问和操作网页内容。本文将详细介绍DOM的概念、其在浏览器中的运用以及相关的编程技巧。 DOM简介 什么是DOM? DOM(Document Object Model)是一种跨平台和语言独…...

从肌电信号到Arduino控制:MyoWare传感器实战指南

1. 项目概述&#xff1a;当肌肉“说话”&#xff0c;我们如何“倾听”&#xff1f;如果你玩过一些体感游戏&#xff0c;或者看过科幻电影里用意念控制机械臂的场景&#xff0c;心里大概会闪过一个念头&#xff1a;这玩意儿到底是怎么做到的&#xff1f;其实&#xff0c;很多酷炫…...

TPU材料3D打印iPad Pro保护框:从设计到成品的完整实践指南

1. 项目概述&#xff1a;为什么选择TPU为iPad Pro打造专属保护框&#xff1f;作为一名折腾过几十公斤耗材的3D打印老玩家&#xff0c;我始终认为&#xff0c;这项技术最迷人的地方不在于复刻网上的模型&#xff0c;而在于为手头的心爱之物量身定制解决方案。就拿我手边的这台iP…...

【Midjourney极简艺术风格终极指南】:20年视觉设计专家亲授3大构图法则、5类禁用提示词与1套可复用Prompt模板

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;极简艺术风格的本质与Midjourney适配原理 极简艺术风格并非简单地“减少元素”&#xff0c;而是通过精准的留白、克制的色彩、几何化的形态与高度凝练的视觉语法&#xff0c;实现信息密度与情绪张力的平…...

用Circuit Playground Express制作可穿戴互动闪光T恤:零焊接图形化编程入门

1. 项目概述&#xff1a;一件会“跳舞”的闪光T恤几年前&#xff0c;当我第一次把微控制器缝进衣服里时&#xff0c;那感觉既兴奋又麻烦——满桌子的电线、烙铁&#xff0c;还有对洗衣机深深的恐惧。但现在&#xff0c;像Adafruit的Circuit Playground Express&#xff08;后面…...

暗黑破坏神II终极角色编辑器:Diablo Edit2完全使用指南

暗黑破坏神II终极角色编辑器&#xff1a;Diablo Edit2完全使用指南 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit Diablo Edit2是暗黑破坏神II玩家必备的角色存档编辑器&#xff0c;这款开源工具…...

从零到一:在MissionPlanner中配置与可视化RC接收器RSSI

1. 什么是RSSI&#xff1f;为什么需要监控它&#xff1f; 如果你玩过无人机或者遥控模型&#xff0c;肯定遇到过信号突然中断的情况。那种眼睁睁看着爱机失控坠落的无力感&#xff0c;我深有体会。RSSI&#xff08;Received Signal Strength Indicator&#xff09;就是帮助我们…...