ie旋转滤镜Matrix

news/2024/7/8 6:52:51

旋转一个元素算是一个比较常见的需求了吧,在支持CSS3的浏览器中可以使用transform很容易地实现,这里有介绍:http://www.css88.com/archives/2168,这里有演示http://www.css88.com/tool/css3Preview/Transform.html,就不再介绍了。

在IE下旋转一个元素,则只能靠滤镜了。

如果只是以90度为单位旋转的话,简单地使用这个滤镜就好:

filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=i)

其中i取0,1,2,3,分别代表旋转90度、180度、270度、360度。

而如果要实现任意角度旋转,则要使用Matrix(矩阵)滤镜。

网上介绍的方法都是这样:

filter:progid:DXImageTransform.Microsoft.Matrix(M11=m11,M12=m12,M21=m21,M22=m22,sizingMethod="auto expand");

设旋转角为x,用弧度表示。那么m11=cos(x),m12=-sin(x),m21=sin(x),m22=cos(x)

正弦sin的诱导公式(对边比斜边)

sin(2kπ+α)=sin α 
sin(π/2-α)=cos α
sin(π/2+α)=cos α 
sin(-α)=-sin α
sin(π+α)=-sin α 
sin(π-α)=sin α

余弦cos的诱导公式(邻边比斜边)

cos(2kπ+α)=cos α 
cos(π/2-α)=sin α 
cos(π/2+α)=-sin α
cos(-α)=cos α
cos(π+α)=-cos α 
cos(π-α)=-cos α

实测这个方法有效,但是它会绕元素原来轮廓的左边和上边转动,还是画个图示意一下:

IE非中心点旋转

如图所示,图形会贴着上边和左边旋转。

那如果我们要绕中间点旋转的话要怎么做呢?这就说来话长了,得讲到几何的向量方法。

坐标系中,每个点有一个坐标,比如点p(3,4),横坐标为3,纵坐标为4。

接下来,向量:简单理解为有方向的线段。

将点和原点连接起来,方向从原点指向点,即构成一个向量op。

通过这样的方式,我们就将向量与点一一映射起来了,研究点的时候就可以用向量来研究啦。

点到坐标映射

 

接下来,研究旋转的实质,P点绕原点O(顺时针)旋转角度α,即向量OP旋转α,新的点P‘坐标变为(3cosα-4sinα,4sinα+3cosα).

为什么会是这个值,

(x,y) 被旋转了 \theta 并希望知道旋转后的坐标 (x',y'):

\begin{bmatrix} x' \\ y' \end{bmatrix} =  \begin{bmatrix} \cos \theta & -\sin \theta \\ +\sin \theta & \cos \theta \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix}.

x'=x\cos\theta-y\sin\theta\,
y'=+x\sin\theta+y\cos\theta\,

请参阅http://zh.wikipedia.org/wiki/%E6%97%8B%E8%BD%AC(数学里面以逆时针为正方向,所以公式在符号上略有不同)

上面新坐标中,在原坐标上进行的计算的数cosα,-sinα,sinα,cosα刚好就是上上面IE的matrix中的参数m11,m12,m21,m22!

事实上,上面的计算一般会写成矩阵的方式来进行,见维基百科的表示方法。

所以,matrix滤镜的实质是对图形进行坐标的矩阵运算。

上面说的是绕原点O旋转,如果绕的是非原点呢?情况比较复杂,详见http://hi.baidu.com/windsion/blog/item/b4a41951699aa0c9b645ae4f.html。

大致分为三步:

  1. 整体位移,即把中心点和向量做相应位移,使旋转点变为原点
  2. 绕原点旋转,和上面说的一样
  3. 整体位移,再将中心点移回原来的地方去

这个时候,计算的矩阵就变得复杂了(上面文章的最下方)。

而事实上,这个矩阵是可以化简的,详见这里http://stackoverflow.com/questions/5051451/javascript-ie-rotation-transform-maths

最终,我们得到除了上面的m11,m12,m21,m22之外的另外两个数,这两个数在IE的matrix滤镜中表示为Dx,Dy。

将这六个参数写入matrix滤镜,即可绕中心点旋转了。

完整的写法:

progid:DXImageTransform.Microsoft.Matrix(Dx=dx,Dy=dy,M11=m11,M12=m12,M21=m21,M22=m22);

其中

dx=-width/2*cosdeg+height/2*sindeg+width/2, dy=-width/2*sindeg-height/2*cosdeg+height/2 m11,m12,m21,m22与前面说的一样。

哦哦,对了,微软官方说了http://msdn.microsoft.com/en-us/library/ms532872(v=vs.85).aspx,如果sizingMethod=”auto expand”,那么Dx、Dy是无效的哦。所以去掉就好啦。

最后的最后,sizingMethod是什么意思呢,如果不设它的话,旋转对象的容器大小会是固定的,所以可能有遮挡的情况,自己要调整好大小,而如果它被设为auto expand,就是自动扩展的意思,即旋转时外面的容器大小会自动调整,以便不遮挡正在旋转的元素。

转载于:https://www.cnblogs.com/zhishaofei/p/4420571.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pgtn.cn/news/15577.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

【C++】四种类型的转换

C四种类型的转换 包括这四种:const_cast , static_cast , dynamic_cast , reinterpret_cast 先来说下C语言中的类型转换,非常的暴力,就是耍流氓: float a 12.23; int b (int)a; 下面我写的都是最基础的,简单的&am…

【C++】满二叉树、完全二叉树等概念解释

二叉树中的判断有以下几种: 是否完全二叉树、是否满二叉树、是否为BST树、是否为平衡二叉树、是否为对称二叉树、完美二叉树 满二叉树: 除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。 上述所示图除最外一层节点之外…

【C++】多线程(链式、循环队列)实现生产者消费者模式

生产者消费者模式: 生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了…

添加引用方式抛出和捕获干净的WebService异常

转载:http://www.cnblogs.com/ahdung/p/3953431.html 说明:【干净】指的是客户端在捕获WebService(下称WS)抛出的异常时,得到的ex.Message就是WS方法中抛出的异常消息,不含任何“杂质”。 前提:…

基数排序(桶排序)

基数排序又叫桶排序: 先按照个位数排序,第一次排序好之后;再次按照十位数进行排序,第二次排序好之后;第三次对百位进行排序.................. 实现原理图:拿出一些个类似“桶”的东西 将分别按照个位&am…

如何用两个栈实现一个队列?

先看分析 来看代码,因为代码量巨大,其中包括两个头文件,两个实现函数 , 这块就写一个两个栈实现按一个队列的头文件以及函数名,填补代码不难的,有需要的话,我在评论区发出来: 这部分…

堆排序(超详细的原理图以及代码注释)

在了解学习堆排序之前,我们必须清楚以下的概念: 上述概念搞清楚之后,来看下面的原理图: 然后原理部分就讲完了 下面来看如何由子节点下标推出父节点和父节点下标推出子节点下标 下面这个原理图来展现一下为什么在调整大顶堆的时候…

【C++】模拟实现多线程中的信号量

信号量: 二元信号量和一般信号量 二元信号量是最简单的一种锁,适合那种被唯一线程访问的资源,而一般信号量就允许多线程并发的访问资源。 二元信号量类似于互斥量,但是有一点不同的是,互斥量只能被上锁的那个线程释…