js 实现以鼠标位置为中心滚轮旋转图片

1,668 阅读1分钟

前言

不知道各位小伙伴PS用的多不多,我自己呢也就会一点简单的抠图,去水印,裁剪,自由变换啥的。在使用自由变换的时候,觉得能随意调节变换中心再结合旋转实现的效果还挺有意思的。于是就花了点时间研究了一下。同时简化了操作方式,以鼠标的位置为中心滚轮旋转。

点绕点旋转公式

在讲之前还请小伙伴们先理解一个数学公式,在平面坐标系中,任意点P0(x0,y0),绕一个坐标点O(x,y)旋转θ角度后,新的坐标设为P1(x1,y1)的计算公式:

x1=(x0x)cos(θ)(y0y)sin(θ)+xx1 = (x0 - x) * cos(θ) - (y0 - y) * sin(θ) + x

y1=(x0x)sin(θ)+(y0y)cos(θ)+yy1 = (x0 - x) * sin(θ) + (y0 - y) * cos(θ) + y

实现

HTML

<div class="container">
    <img id="image" src="../images/liya.jpg" alt="">
</div>
<div class="log"></div>

js

// 获取dom
const image = document.getElementById('image');
const log = document.querySelector('.log');
// 全局变量
let result = { width: 400, height: 320 },
    x = (window.innerWidth - result.width) * 0.5,
    y = (window.innerHeight - result.height) * 0.5,
    rotate = 0;
// 居中显示
image.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) rotate(' + rotate + 'deg)';
log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(0)}<br>rotate = ${rotate}`;
// 绑定wheel事件
image.addEventListener('wheel', function (e) {
    let angle = 10;
    // 逆时针旋转
    if (e.deltaY > 0) {
        angle = -10;
    }
    // transform-origin相对于视口左上角的坐标
    const origin = {
        x: result.width * 0.5 + x,
        y: result.height * 0.5 + y
    };
    // 计算点图片变换中心绕鼠标位置旋转angle度后的坐标,设为点a
    const a = {
        x: (origin.x - e.clientX) * Math.cos(angle * Math.PI / 180) - (origin.y - e.clientY) * Math.sin(angle * Math.PI / 180) + e.clientX,
        y: (origin.x - e.clientX) * Math.sin(angle * Math.PI / 180) + (origin.y - e.clientY) * Math.cos(angle * Math.PI / 180) + e.clientY
    }
    // 计算偏移量
    x -= origin.x - a.x;
    y -= origin.y - a.y;
    rotate = (rotate + angle) % 360;
    this.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) rotate(' + rotate + 'deg)';
    log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(0)}<br>rotate = ${rotate}`;
});

Demo:jsdemo.codeman.top/html/wheelR…