js旋转后元素的缩放

说到js的缩放,每个人都有自己不同的看法,有的觉得简单,有得可能又觉得没有那么容易,在我看来,对于大部分真正实现过这个功能的人来说,这个小功能还是有一些挑战的(当然算法大神除外)。

对于没有任何旋转的元素来说,要单纯的实现缩放功能确实不难,只需要考虑好鼠标再往不同方向移动的时候元素x,y,width,height的变化情况基本就没啥问题,但是如果是旋转后的元素呢?

我们先想象一下,正常的旋转是这样的,如果我拖动元素右边的某一个点进行缩放,那么其对边是不应该有变化的,再精确点就是其对角的那个点是不应该有变化的,而在css和canvas中旋转是基于中心点的,不管元素怎么旋转其实其位置和宽高都是固定的,也就是旋转其实只是视觉上的,而不是实际的坐标改变,基于这种现状,如果我们直接用作未旋转物体的缩放思路来实现旋转后元素的缩放,就会很怪异,你往一个方向缩放,其对边的各个点也会跟着改变向相反的方向运动,而这并不是我们所期望的。

其实这个问题之前也曾困扰了我们团队一小段儿时间,不是说它难的难以时间,主要是我们都没时间去研究,后来我也是花了差不多快一个星期才做好的。

那么到底怎么做呢?

做这个效果有两个问题需要解决:

1、元素旋转后真实坐标的转化

对于元素的坐标转化其实有很多方法,最简单的就是利用坐标转换公式可以轻松实现(有兴趣的可以百度一下,这个东西蛮有用的)。这里我用的是一个笨办法,通过三角函数计算的出的旋转后坐标,下面的图演示了一个点的转化的推导过程:

我们要求的是为旋转状态下左上角的点旋转后对应的点(i, j)的坐标,其实也就是求图中dx,dy,而两条蓝线的长也就是标示的r我们是知道的就是对角线长度的一半,而图中的角度a我们也是可以求出来的,sw是高的一半,sh是宽的一半,他们两个反正切就可以求出a角度,进而我们就可以得出dx = Math.cos(旋转角度+a), dy = Math.sin(旋转角度+a)。猛戳这里查看效果

2、缩放过程的拆分

首先我们看一下我们需要的正常的旋转缩放的过程:

我们再看一下我们拆分后的旋转缩放过程:

拆分后我们先将原始元素进行了缩放,再旋转相应的角度,记录这个状态为A,然后与原始元素元素直接旋转的状态B作比较,将A状态中需要定住的点平移到B状态对应的点,这样结果就和正常的旋转一致了。

其实原理说明白了,实现就是分分钟的事情了。

最后附上最终的效果,猛戳这里查看

猛戳这里下载本文案例源码包
  • 支付宝二维码 支付宝
  • 微信二维码 微信
相关文章