鼠标位置缩放图片

这几天有空研究了一下图片定点缩放。做的过程中才发现很多坑,记录一下。

思路

  1. 首先要定放缩坐标原点,这里有容器原点与图片中心点两个坐标系,任取其一即可,以下采用的是图片中心点。
  2. 基本实现思路是将图片先移动到某个位置,放缩前后鼠标位置能刚好重叠。
  3. 计算关键变量:
js 复制代码
    ratio: 当前放缩倍数 / 上一次放缩倍数
    xOffset,yOffset: 放缩后坐标点 - 放缩前坐标点,需注意坐标系转化
  1. 缩放后计算变量并应用于transform 。

(code.juejin.cn/pen/7304582...)

一、确定放缩坐标系

1.使用容器坐标系

需更改图片css属性transform-origin: 0 0,计算偏移时需将鼠标坐标转为以图片左上角坐标系为准的数据。

js 复制代码
const changeToBoxOrigin = (x, y) => {
    let imgRect = imgDom.getBoundingClientRect();
    let imgCenterX = imgRect.left; // 如容器不在左上角,得减去容器坐标
    let imgCenterY = imgRect.top;
    return { x: x - imgCenterX, y: y - imgCenterY}
}

2.使用图片中心点

计算偏移时将坐标系转为以图片中心点为准的数据。

js 复制代码
const changeToImageOrigin = (x, y) => {
    let imgRect = imgDom.getBoundingClientRect();
    let imgCenterX = imgRect.left + imgRect.width / 2; // 如容器不在左上角,得减去容器坐标
    let imgCenterY = imgRect.top + imgRect.height / 2;
    return { x: x - imgCenterX, y: y - imgCenterY}
}

二、确定本次移动偏移量

暂时抛开偏移变化。以图片中心点缩放。 则水平方向的偏移距离是x2-x1,x2 = x1 * ratio,由此推理水平方向偏移量xOffset = x1 * (ratio - 1) 同理可得出yOffset = y1 * (ratio - 1)。

那么x1,x2坐标如何获取呢。从mouseEvent中可以获取鼠标相对于容器的坐标x, y,经由坐标转化函数changeToImageOrigin即可获取到x1,y1。

三、组合数据并应用

这里需注意transform变化顺序,先平移,后缩放

js 复制代码
const scale = ref(1)
const _offset = [0, 0]
const _scale = (s, event) => {
    let x = event.x, y = event.y;
    let { x: x1, y: y1 } = changeToImageOrigin(x, y);
    let ratio = s / scale.value;
    let xOffset = x1 * (ratio - 1);
    let yOffset = y1 * (ratio - 1);
    scale.value = s;
    
    // 设置style
    imgDom.style = `
        transform: translate(${_offset[0] + xOffset}px, ${_offset[1] + yOffset}px) scale(${s})
    `
}
相关推荐
东东5161 小时前
基于ssm的网上房屋中介管理系统vue
前端·javascript·vue.js
harrain2 小时前
什么!vue3.4开始,v-model不能用在prop上
前端·javascript·vue.js
fanruitian8 小时前
uniapp android开发 测试板本与发行版本
前端·javascript·uni-app
rayufo8 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
RANCE_atttackkk8 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
2501_944525549 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
李白你好10 小时前
Burp Suite插件用于自动检测Web应用程序中的未授权访问漏洞
前端
刘一说11 小时前
Vue 组件不必要的重新渲染问题解析:为什么子组件总在“无故”刷新?
前端·javascript·vue.js
徐同保12 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js
刘一说13 小时前
Vue 导航守卫未生效问题解析:为什么路由守卫不执行或逻辑失效?
前端·javascript·vue.js