ie的Matrix滤镜跟css3的matrix差不多,也能实现类似的变换。
Matrix滤镜有以下属性:
Dx/Dy:坐标变换参数;
enabled:是否可用;
FilterType:定义新内容的像素的方法;
M11/M12/M21/M22:矩阵变换参数;
SizingMethod:容器是否改变尺寸去适应目标图像。
详细参考msdn的Matrix Filter和中文Matrix说明。
判断浏览器是否支持,也是创建一个div,看它有没有"filters"属性:
在init程序中也用initImg方法对图片进行设置,此外还需要设置Matrix滤镜:
这里会设置SizingMethod属性,它有两个值,分别是:clip to original(容器不改变尺寸)和auto expand(容器改变尺寸以适应目标图像)。
如果使用默认值clip to original,容器的大小不会变,那么变换时超出容器的部分就会隐藏不见,所以这里要设为'auto expand'才能完整显示图片。
在load程序中显示图片,为了防止ie重复加载gif的bug还要重置onload为null。
ps:该bug的研究可以参考这里的显示预览部分。
而show程序也跟css3模式类似,通过getMatrix方法获取变换参数,并设置到滤镜中:
滤镜使用了'auto expand'后,变换时图片元素尺寸会随着内容变化,所以要重新设置居中:
ie还有其他变换滤镜,例如FlipH(水平翻转)、FlipV(垂直翻转)、Wave(扭曲)等。
【canvas】
通过滤镜和css3已经能在主流的浏览器上兼容实现相同的变换,最后再用canvas来实现。
canvas是一个用来绘制图形的元素,它最强大的地方在于结合js来绘制图形甚至制作动画和游戏。
ps:这里推荐几个入门文章:Opera的HTML 5 canvas和深入了解canvas标签系列。
要知道浏览器是否支持canvas,可以创建一个canvas元素,看它是否有"getContext"方法来判断:
getContext方法用来获取渲染空间(也叫上下文),之后会在这个空间绘图,相当于获取画布。
在init程序中,创建并设置canvas及其上下文context:
代码
程序中只需要2D canvas,所以用getContext('2d')就行了。
ps:关于3D canvas在Opera的HTML 5 canvas有相关的介绍。
还需要设置尺寸,这里要注意要用width和height来设置,我试过用样式来设置,结果画图不正常。
在show程序中进行变换和画图:
代码
这里用到了canvas几种方法:
save:保存状态;
clearRect:清除画布;
translate:水平/垂直移动坐标;
rotate:旋转坐标;
scale:缩放坐标;
drawImage:插入图像;
restore:恢复状态。
canvas没有直接清除整个画布的方法,只能用clearRect来间接实现。
它的四个参数用来定义一个矩形,只要定义一个画布大小的矩形就能清除整个画布了。
在canvas里面没有left/top,位置的变换只能用translate来设置,程序用它把坐标移到画布中心。
canvas没有Matrix那样的东西,只能用rotate和scale来变换,用法跟css3的类似。
canvas也没有css3的skew(拉扯)变换。
最后用drawImage画图,可以是img元素、Image对象或Canvas元素,另外两个参数是画图位置,程序用它来居中图像。
每次画图都可能会改变坐标,下次想还原坐标来画图要逐个恢复会很麻烦,这时应该用save和restore来保存和还原状态。
save和restore能保存和还原包括translate、rotate、scale变换后的画布状态,常常配合clearRect来做动画。
除了以上方法,canvas还有很多属性和方法来绘图,详细可以看HTML DOM CanvasRenderingContext2D 对象。
【拖动旋转/滚轮缩放】
拖动旋转效果是在容器按下鼠标并拖动的过程中,图像会跟着鼠标转动。
原理是以容器中点为中心,计算按下鼠标位置的弧度R1和拖动到达位置的弧度R2,两者的差就是根据鼠标要旋转的弧度,再加上原来的弧度R0,即R2-R1+R0,就能得到当前要设置的弧度了。
关键的地方就在于如何获取这个弧度,如果要手动计算这个值会很复杂,好在js提供了Math.atan2(y,x)方法,可以返回由 X 轴到 (y,x) 点的弧度,这样直接用坐标就可以得到弧度。
例如中心坐标是(x,y),某一点的坐标是(x1,y1),可以这样得到那个点相对中心坐标的弧度:Math.atan2(y1-y,x1-x)。
首先在鼠标的mousedown中记录容器的中心坐标:
再根据clientX/clientY当前位置坐标计算弧度:
这里把原来的弧度也顺便计算了。
在拖动的过程中,根据移动坐标获取弧度,并调用rotate来旋转:
ps:拖动效果请看这里关于拖动的研究。
滚轮缩放效果就是在容器上滚动鼠标会自动实现缩放效果。
这个比较简单,主要是一些兼容问题,相关研究可以参考这里的鼠标滚动缩放。
使用技巧
【模式选择】
模式设置中说明了自定义模式可以用这样的格式:"css3|filter|canvas"。
程序会自动按优先顺序选择支持的模式。
为了尽量保证浏览器支持选择的模式,可以把三个模式都用上。
一般filter是必须的,因为目前ie只支持这个,而css3和canvas可以自行选择。
我在自己的电脑做了效率测试(就是用鼠标狂转图片),看cpu的占用情况:
ff css3 40%
ff canvas 35%
opera css3 30%
opera canvas 35%
chrome css3 25%
chrome canvas 55%
safari css3 20%
safari canvas 55%
看来在ff和opera是canvas好一点,在WebKit就是css3快得多。
但canvas只能画静态图片,对于gif那样的动态图片只能显示一帧,所以还是选css3比较好。
还有css3的变换能用在所有元素中(ie8的滤镜也可以),适用在html的变换,而canvas就更适合做复杂的图形和动画。
【选择图片】