再看最后一眼青春的星空

灿烂火光就像盛夏的烟火

欢送挣扎万年文明的巅峰

我们啊

将变星辰永远飘在黑暗宇宙

这个男人来自三体

Tirion

导航

roc-charts 开发笔记:canvas——根据鼠标位置进行缩放的实现原理

以任一点 A 缩放的基本原理:

A 点为鼠标位置,正常放大是以原点放大,那么放大后 A 点就会变到 A1 点的位置 x1, y1。然后再将画布进行位移,将 A1 的位置移动到 A,则完成以 A 点缩放的功能。

 

 

 

 代码示例:

this.scale 是当前缩放比例,this.offsetX, this.offsetY 是当前原点位移距离,step 是每次缩放的增量

            if (wheelDelta > 0) {  // 放大
                if (this.scale < max) {  // 缩放值小于设定的最大值,则可以继续放大
                    this.scale += step;  // 累加后 this.scale 为放大后的缩放值
                    if (this.scale > max) {  // 越界处理
                        this.scale = max;
                    }
                    this.painter.scale(this.scale);  // 进行缩放
                    // 要根据鼠标位置缩放,则要在缩放后再次移动,将缩放点的位置移动到鼠标位置
                    const x = e.offsetX;
                    const y = e.offsetY;
                    offsetX = (x - this.offsetX) * this.scale / (this.scale - step) - (x - this.offsetX);
                    offsetY = (y - this.offsetY) * this.scale / (this.scale - step) - (y - this.offsetY);
                    this.move(-offsetX, -offsetY);
                }

为什么是 x - this.offsetX?因为代码中,当画布左移后,this.offsetX 是负数,所以使用减号得到的才是正确的坐标。

this.scale / (this.scale - step) 是缩放后的缩放值除以缩放前的缩放值,得到缩放率。

this.move() 对画布进行移动,并累加 this.offsetX 和 this.offsetY

化简得:

        const move = (e) => {
            const x = e.offsetX - this.offsetX;  // 鼠标位置换算到相对原点的坐标
            const y = e.offsetY - this.offsetY;
            const offsetX = x * (this.scale - preScale) / preScale;  // x * 绝对缩放率 得到位移
            const offsetY = y * (this.scale - preScale) / preScale;
            this.move(-offsetX, -offsetY);
        };

 

 

posted on 2018-08-07 14:38  Tirion  阅读(1341)  评论(2编辑  收藏  举报

The Man from 3body