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

前端的拖拽和缩放(缩放以鼠标为中心)

效果:

拖拽和缩放(缩放以鼠标为中心)

代码具体实现如下:

但是有几个注意点

(1)为什么需要设置 transform-origin: 0 0;

缩放时以鼠标为中心进行缩放。这意味着需要手动计算缩放过程中元素的位移,以确保缩放是以鼠标为中心的。如果不设置 transform-origin,缩放和位移的计算将变得更加复杂。

设置 transform-origin: 0 0; 后,所有的位移和缩放都是基于左上角进行的,这使得计算变换的位移量更加直观和简单。只需要考虑从左上角开始的平移和缩放,而不需要考虑元素的中心点。

如果不设置 transform-origin: 0 0;,在缩放和位移时需要考虑变换原点的位置,这会增加计算的复杂性。

(2)关于代码中的(scale / prevScale - 1)

在缩放过程中需要计算新的平移值,使得缩放以鼠标为中心。(scale / prevScale - 1) 计算出相对于原始缩放比例的变化量。

例如,如果 scale 增加了10%,那么 scale / prevScale 会是1.1,减去1后得到0.1,表示增加的10%。

offsetX * (scale / prevScale - 1) 计算出由于缩放而导致的水平偏移量。类似地,offsetY * (scale / prevScale - 1) 计算出由于缩放而导致的垂直偏移量。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>移动和缩放容器</title><style>body {margin: 0;height: 100vh;display: flex;justify-content: center;align-items: center;background-color: #f0f0f0;overflow: hidden;}#container {width: 200px;height: 200px;background-color: #4caf50;cursor: grab;user-select: none;transform-origin: 0 0; /* 设置原点为左上角 */}</style></head><body><div id="container">ABC</div><script>const container = document.getElementById("container");let isDragging = false;let startX, startY, initialX, initialY;let scale = 1;let translateX = 0,translateY = 0;container.addEventListener("mousedown", (e) => {isDragging = true;startX = e.clientX;startY = e.clientY;initialX = translateX;initialY = translateY;container.style.cursor = "grabbing";});document.addEventListener("mousemove", (e) => {if (isDragging) {const dx = e.clientX - startX;const dy = e.clientY - startY;translateX = initialX + dx;translateY = initialY + dy;container.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;}});document.addEventListener("mouseup", () => {isDragging = false;container.style.cursor = "grab";});container.addEventListener("wheel", (e) => {e.preventDefault();const minScale = 0.5;const maxScale = 3;const rect = container.getBoundingClientRect();const offsetX = e.clientX - rect.left;const offsetY = e.clientY - rect.top;const prevScale = scale;const delta = e.deltaY || e.detail || e.wheelDelta;// console.log(delta, "delta");scale += delta * -0.01;scale = Math.min(Math.max(minScale, scale), maxScale);const newX = offsetX * (scale / prevScale - 1);const newY = offsetY * (scale / prevScale - 1);console.log(newX);translateX -= newX;translateY -= newY;container.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;});</script></body>
</html>

相关文章:

前端的拖拽和缩放(缩放以鼠标为中心)

效果&#xff1a; 拖拽和缩放&#xff08;缩放以鼠标为中心&#xff09; 代码具体实现如下&#xff1a; 但是有几个注意点 &#xff08;1&#xff09;为什么需要设置 transform-origin: 0 0; 缩放时以鼠标为中心进行缩放。这意味着需要手动计算缩放过程中元素的位移&#…...

【Vue】单向和双向数据绑定

在 Vue.js 中&#xff0c;数据绑定可以分为单向数据绑定和双向数据绑定两种类型。 单向数据绑定 单向数据绑定是指数据从模型流向视图&#xff0c;即数据的变化会自动反映到视图中&#xff0c;但视图中的变化不会自动反映回模型。Vue.js 中的单向数据绑定主要通过以下方式实现…...

HDFS学习

3.5 HDFS存储原理 3.5.1 冗余数据保存 作为一个分布式文件系统&#xff0c;为了保证系统的容错性和可用性&#xff0c;HDFS采用了多副本方式对数据进行冗余存储&#xff0c;通常一个数据块的多个副本会被分布到不同的数据节点上。 如图所示&#xff0c;数据块1被分别存放到…...

Winform使用HttpClient调用WebApi的基本用法

Winform程序调用WebApi的方式有很多&#xff0c;本文学习并记录采用HttpClient调用基于GET、POST请求的WebApi的基本方式。WebApi使用之前编写的检索环境检测数据的接口&#xff0c;如下图所示。 调用基于GET请求的无参数WebApi 创建HttpClient实例后调用GetStringAsync函数获…...

python–基础篇–正则表达式–是什么

文章目录 定义一&#xff1a;正则表达式就是记录文本规则的代码定义一&#xff1a;正则表达式是一个特殊的字符序列&#xff0c;用于判断一个字符串是否与我们所设定的字符序列是否匹配&#xff0c;也就是说检查一个字符串是否与某种模式匹配。初识 Python 正则表达式 定义一&a…...

15 个适用于企业的生成式 AI 用例

作者&#xff1a;来自 Elastic Jennifer Klinger 关于生成式人工智能及其能做什么&#xff08;和不能做什么&#xff09;有很多讨论。生成式人工智能&#xff08;例如大型语言模型 - LLMs&#xff09;利用从大量训练数据中学习到的模式和结构来创建原创内容&#xff0c;而无需存…...

若依框架中组件使用教程

...

秋招力扣刷题——数据流的中位数

一、题目要求 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。 例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFinder() 初始化 …...

51单片机学习——LED功能一系列实现

目录 一、开发前准备 二、点亮LED 三、LED闪烁 四、LED流水灯 五、LED流水灯plus 一、开发前准备 开发工具软件 烧录软件 其次还需要一块51单片机学习开发板及原理图 keil创造project文件及开启生成.hex文件 二、点亮LED 看二位进制对照原理图&#xff1b; #include <…...

互联网大厂核心知识总结PDF资料

我们要敢于追求卓越&#xff0c;也能承认自己平庸&#xff0c;不要低估3&#xff0c;5&#xff0c;10年沉淀的威力 hi 大家好&#xff0c;我是大师兄&#xff0c;大厂工作特点是需要多方面的知识和技能。这种学习和积累一般人需要一段的时间&#xff0c;不太可能一蹴而就&…...

设计模式-状态模式和策略模式

1.状态模式 1.1定义 当一个对象的内在状态改变时允许根据当前状态作出不同的行为&#xff1b; 1.2 适用场景 (1)一个对象的行为取决于它的状态,并且它必须在运行时根据状态来决定其行为. (2)代码中包含了大量的与状态有关的条件语句,例如:一个操作含有庞大的多分值语句(if…...

Java NIO Buffer概念

针对每一种基本类型的 Buffer &#xff0c;NIO 又根据 Buffer 背后的数据存储内存不同分为了&#xff1a;HeapBuffer&#xff0c;DirectBuffer&#xff0c;MappedBuffer。 HeapBuffer 顾名思义它背后的存储内存是在 JVM 堆中分配&#xff0c;在堆中分配一个数组用来存放 Buffe…...

Kubernetes在Java应用部署中的最佳实践

Kubernetes在Java应用部署中的最佳实践 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Java应用程序中使用Kubernetes进行最佳部署实践。K…...

IOS Swift 从入门到精通:@escaping 和PreferenceKey

@escaping 在Swift中,@escaping是一个属性关键字,用于标记闭包参数。当一个闭包在函数返回之后才被调用时,这个闭包被称为逃逸闭包(Escaping Closure)。使用@escaping关键字可以告诉Swift编译器,传递给函数的闭包可能会在函数执行完毕后被调用,因此它需要“逃逸”函数的…...

基于PHP技术的校园论坛设计的设计与实现-计算机毕业设计源码08586

摘 要 本项目旨在基于PHP技术设计与实现一个校园论坛系统&#xff0c;以提供一个功能丰富、用户友好的交流平台。该论坛系统将包括用户注册与登录、帖子发布与回复、个人信息管理等基本功能&#xff0c;并结合社交化特点&#xff0c;增强用户之间的互动性。通过利用PHP语言及其…...

开机弹窗缺失OpenCL.dll如何解决?分享5种靠谱的解决方法

在电脑使用过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“开机提示找不到OpenCL.dll”。那么&#xff0c;这个错误提示到底是怎么回事呢&#xff1f;它又对电脑有什么影响&#xff1f;我们又该如何解决这个问题并预防OpenCL.dll再次丢失呢&#xff1…...

IIS 服务器安装SSL证书

IIS 服务器安装SSL证书 步骤一&#xff1a;准备好 SSL 证书 准备好.pfx 格式的证书文件。 步骤二&#xff1a;安装 SSL 证书 1、打开【开始】菜单&#xff0c;找到【管理工具】&#xff0c;打开【Internet 信息服务&#xff08;IIS&#xff09;管理器】。 2、单击服务器名…...

二叉树第二期:堆的实现与应用

若对树与二叉树的相关概念&#xff0c;不太熟悉的同学&#xff0c;可移置上一期博客 链接&#xff1a;二叉树第一期&#xff1a;树与二叉树的概念-CSDN博客 本博客目标&#xff1a;对二叉树的顺序结构&#xff0c;进行深入且具体的讲解&#xff0c;同时学习二叉树顺序结构的应用…...

python-求出 e 的值

[题目描述] 利用公式 e11/1!1/2!1/3!⋯1/&#x1d45b;!&#xff0c;求 e 的值&#xff0c;要求保留小数点后 10 位。输入&#xff1a; 输入只有一行&#xff0c;该行包含一个整数 n&#xff0c;表示计算 e 时累加到1/n!。输出&#xff1a; 输出只有一行&#xff0c;该行包含计…...

模型微调方法

文章目录 LoRADoRAMoRA 以下部分参考自: https://mp.weixin.qq.com/s/OxYNpXcyHF57OShQC26n4g LoRA LoRA是微软于2021年推出的一种经济型微调模型参数的方法。 它在冻结大部分的模型参数的情况下&#xff0c;仅仅更新额外的部分参数。其性能与全参数微调相似。 LoRA假设微调期间…...

用ESP32和Arduino打造你的专属F1蓝牙方向盘(附完整3D打印文件)

用ESP32和Arduino打造你的专属F1蓝牙方向盘&#xff08;附完整3D打印文件&#xff09; 模拟赛车爱好者们对沉浸式体验的追求从未停止&#xff0c;而一款高度定制化的F1风格方向盘往往是提升操控感的关键。本文将带你从零开始&#xff0c;利用ESP32开发板和Arduino生态&#xff…...

三步搞定图片文字提取:Umi-OCR免费离线OCR工具全攻略

三步搞定图片文字提取&#xff1a;Umi-OCR免费离线OCR工具全攻略 【免费下载链接】Umi-OCR Umi-OCR: 这是一个免费、开源、可批量处理的离线OCR软件&#xff0c;适用于Windows系统&#xff0c;支持截图OCR、批量OCR、二维码识别等功能。 项目地址: https://gitcode.com/GitHu…...

OpCore Simplify:智能高效的OpenCore EFI配置工具技术指南

OpCore Simplify&#xff1a;智能高效的OpenCore EFI配置工具技术指南 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify OpCore Simplify是一款专为简化…...

手机号查询QQ技术解析与实战指南

手机号查询QQ技术解析与实战指南 【免费下载链接】phone2qq 项目地址: https://gitcode.com/gh_mirrors/ph/phone2qq 问题&#xff1a;数字化时代的身份关联困境 在现代社会&#xff0c;手机号与QQ号作为重要的数字身份标识&#xff0c;其关联查询需求日益凸显。当用户…...

Python:图解 NumPy

NumPy 是 Python 中最受欢迎的第三方库之一。本文将通过图示和更具实践性的方式介绍其使用方法&#xff0c;使你能够通过直观理解来加深记忆。一、导入 NumPyimport numpy as np二、NumPy 数组的创建NumPy 支持从列表、元组、字符串、缓冲区、迭代器等多种数据来源创建数组。1、…...

AI头像生成器与SpringBoot集成实战:企业级应用开发指南

AI头像生成器与SpringBoot集成实战&#xff1a;企业级应用开发指南 你有没有想过&#xff0c;为什么现在很多电商平台的新用户注册后&#xff0c;头像都那么有个性&#xff0c;而且风格还挺统一&#xff1f;这背后其实不是设计师在加班加点&#xff0c;而是AI头像生成器在默默…...

Cobar高可用性实现:心跳检测与故障转移的完整教程

Cobar高可用性实现&#xff1a;心跳检测与故障转移的完整教程 【免费下载链接】cobar a proxy for sharding databases and tables 项目地址: https://gitcode.com/gh_mirrors/co/cobar Cobar作为阿里巴巴开源的分布式数据库中间件&#xff0c;其高可用性实现是保障企业…...

提升效率神器:快马AI生成批量视频号下载与处理自动化脚本

提升效率神器&#xff1a;快马AI生成批量视频号下载与处理自动化脚本 手动下载和处理视频号内容确实是个耗时又枯燥的活儿。每次都要复制链接、打开下载工具、等待下载完成&#xff0c;再手动转换格式&#xff0c;一套流程下来&#xff0c;半天时间就没了。最近我发现用InsCod…...

数字古籍下载工具使用指南:从入门到精通

数字古籍下载工具使用指南&#xff1a;从入门到精通 【免费下载链接】bookget bookget 数字古籍图书下载工具 项目地址: https://gitcode.com/gh_mirrors/bo/bookget 数字古籍下载工具是一款专为古籍爱好者和研究者设计的资源获取软件&#xff0c;能够帮助用户高效检索、…...

Flutter控制麦克风的方法

Flutter本身不直接提供麦克风控制的原生API&#xff0c;需借助第三方插件实现&#xff0c;核心围绕「权限申请」「麦克风开启/关闭」「音频采样/录音」「资源释放」四大场景。以下是最常用、兼容性最强的实现方案&#xff0c;覆盖多平台适配&#xff0c;附完整代码示例。 一、核…...