图片(旋转缩放翻转)变换效果(ccs3滤镜canvas)

it2025-05-26  13

以前要实现图片的旋转或翻转,只能用ie的滤镜来实现,虽然canvas也实现,但ie不支持而且不是html标准。css3出来后,终于可以用标准的transform来实现变换,而canvas也已成为html5标准的一部分。css3和html5使web变得越来越强大,各种新奇的技术正等待我们发掘。本程序分别通过滤镜(ie)、ccs3和canvas来实现图片的旋转、缩放和翻转变换效果,可以用作图片查看器。有如下特色:1,用滤镜、ccs3和canvas实现相同的变换效果;2,可任意角度旋转;3,可任意角度翻转;4,可扩展滚轮缩放;5,可扩展拖动旋转。兼容:ie6/7/8, firefox 3.6.8, opera 10.6, safari 5.0.1, chrome 5.0

效果预览

程序说明

【基本原理】

变换主要是利用css3的变换样式transform的matrix方法来实现。ie不支持css3,但有Matrix滤镜也能实现类似的效果。程序还用canvas,通过画图实现相同的效果。

【模式设置】

程序包含三种模式:css3、filter和canvas,程序初始化时,会根据自定义模式进行模式设置。各个模式相关的属性和方法都存放在ImageTrans.modes中。每个模式对象都包含support属性,表示当前浏览器是否支持该模式,还有几个方法:init:初始化执行程序load:加载图片执行程序show:变换显示程序dispose:销毁程序

使用这样的格式来自定义模式:"css3|filter|canvas",判断过程主要在_initMode程序中:

代码 var  modes  =  ImageTrans.modes; this ._support  =  $$A.some(  this .options.mode.toLowerCase().split( " | " ),  function (mode){    mode  =  modes[ mode ];     if  ( mode  &&  mode.support ) {        ...         return   true ;    }},  this  );

程序会按顺序逐个判断,当浏览器支持该模式时就会用该模式的方法设置程序函数。再用_support记录浏览器是否支持指定的模式。

如果浏览器支持,才执行_initContainer容器初始化程序和_init模式初始化程序。

【加载图片】

完成初始化设置后,再执行load方法加载图片。在load方法中,主要对图片进行设置:

img.onload  ||  ( img.onload  =   this ._LOAD );img.onerror  ||  ( img.onerror  =   function (){ oThis.onError( " err image " ); } );

最后设置src加载图片。

图片加载成功后,会执行_LOAD程序,在里面会执行_load加载程序和reset方法。在reset中,会重置变换参数,并执行_show模式画图程序:

this ._y  =   this ._x  =   1 this ._radian  =   0 ; this ._show();

这时,图片会以初始状态显示。

【图片变换】

图片加载完成后,就可以对图片进行变换。

各种变换方法保存在ImageTrans.transforms中,包括旋转、垂直翻转、水平翻转、缩放等。变换结果是通过_y垂直变换参数、_x水平变换参数和_radian旋转变换参数计算得到的。变换方法就是用来修改这些参数的方法。

一般的翻转是通过把_y或_x取反来实现的,是以图片本身为坐标的翻转。但用户的习惯是按浏览器坐标来翻转的,当图片先旋转变换坐标后再翻转,就不符合用户习惯了。为了能按视觉习惯坐标来翻转,程序使用的方法是先旋转再翻转来实现。例如vertical垂直翻转是图片旋转180度,再进行一般的水平翻转:

this ._radian  =  Math.PI  -   this ._radian;  this ._x  *=   - 1 ;

而horizontal水平翻转也类似:

this ._radian  =  Math.PI  -   this ._radian;  this ._y  *=   - 1 ;

实际也是利用了一些坐标变换原理。

rotate旋转是以弧度为单位的,直接修改_radian参数。rotatebydegress是以角度为单位的旋转,其实是用degress * Math.PI/180公式把角度转换成弧度。left向左转90度是在原有弧度减Math.PI/2(即90度),而right向右转90度是加Math.PI/2。

scale缩放就是根据缩放比率分别对_y和_x进行修改。程序定义了一个getZoom修正缩放比率函数:

function  getZoom(scale, zoom) {     return     scale  >   0   &&  scale  >- zoom  ?  zoom :            scale  <   0   &&  scale  <  zoom  ?- zoom :  0 ;}

只有当比率不会导致结果是反值的情况才会返回正确的比率。这里主要是保证缩到最小时不会因为比率太大得到反值,导致图片翻转并放大。当垂直和水平比率都不是0,才会对参数进行修改:

var  hZoom  =  getZoom(  this ._x, zoom ), vZoom  =  getZoom(  this ._y, zoom ); if  ( hZoom  &&  vZoom ) {     this ._x  +=  hZoom;  this ._y  +=  vZoom;}

这样可以保证水平和垂直缩放同时进行,保持图片比例。要注意zoomin放大时要保证缩放比率为正数,zoomout缩小就要负数。

这些方法会在模式设置中扩展到程序中:

$$A.forEach( ImageTrans.transforms,  function (transform, name){     this [ name ]  =   function (){        transform.apply(  this , [].slice.call(arguments) );         this ._show();    }},  this  );

在执行完变换方法后,就会执行_show来显示变换。

【transform】

变换换流程介绍完,就进入主题,介绍三个变换方法了。先看看css3的transform,它包含以下变换方法:matrix:矩阵变形,使用它就可以做到后面所有的变换,但使用相对麻烦;translate/translateX/translateY:坐标变换,就是移动坐标的意思;scale/scaleX/scaleY:缩放变换,放大缩小,取负值可以做翻转;rotate:旋转变换,根据角度旋转;skew/skewX/skewY:拉扯变换,就是上下或左右向不同的方向扯开的效果。更详细的介绍请看w3c的CSS 2D Transforms或者MDC的-moz-transform。

要进行变换,首先要看看浏览器是否支持:

代码 var  style  =  document.createElement( " div " ).style; return  $$A.some(    [  " transform " " MozTransform " " webkitTransform " " OTransform " " msTransform "  ],     function (css){  if  ( css  in  style ) {        css3Transform  =  css;  return   true ;    }});

由于程序运行时文档可能还没载入,所以要手动创建一个元素来测试。虽然w3c标准使用的是transform,但现阶段各浏览器还是需要各自的前缀。当元素样式包含其中一个变换样式,说明该浏览器支持,再用css3Transform记录样式名字。

在css3模式的init程序中,会执行initImg方法对图片进行设置:

$$D.setStyle( img, {    position:  " absolute " ,    border:  0 , padding:  0 , margin:  0 , width:  " auto " , height:  " auto " ,    visibility:  " hidden " });container.appendChild( img );

主要是设置绝对定位、隐藏和重置样式,最后插入容器。ps:图片对象虽然是用new Image()创建的,但也可以当作img元素来操作。

在load加载程序中,再对图片样式进行设置:

$$D.setStyle( img, {    top: (  this ._clientHeight  -  img.height )  /   2   +   " px " ,    left: (  this ._clientWidth  -  img.width )  /   2   +   " px " ,    visibility:  " visible " });

设置left和top使图片在容器里居中,并显示图片。

关键的show程序,用来进行图片变换,这里用的是matrix变换。matrix有6个参数,前4个是矩阵变换参数,后两个是坐标变换参数。要根据弧度旋转,可以这样设置矩阵:cos(a) -sin(a)sin(a)  cos(a)而缩放变换就这样设置:sx 00  sy旋转同时缩放,矩阵相乘得到:cos(a)*sx -sin(a)*sysin(a)*sx  cos(a)*sy关于Matrix矩阵变换可以看w3c的Transform Matrix。

getMatrix函数就是通过以上矩阵计算matrix参数:

var  Cos  =  Math.cos(radian), Sin  =  Math.sin(radian); return  {    M11: Cos  *  x, M12: - Sin  *  y,    M21: Sin  *  x, M22: Cos  *  y};

在show程序里面,用getMatrix得到参数后,就可以设置样式:

this ._img.style[ css3Transform ]  =   " matrix( "      +  matrix.M11  +   " , "   +  matrix.M21  +   " , "      +  matrix.M12  +   " , "   +  matrix.M22  +   " , 0, 0) " ;

在实际使用中,使用matrix可能要设置一堆可读性很差的数字,所以还是推荐用其他变换方法。

【Matrix滤镜】

ie的Matrix滤镜跟css3的matrix差不多,也能实现类似的变换。Matrix滤镜有以下属性:Dx/Dy:坐标变换参数;enabled:是否可用;FilterType:定义新内容的像素的方法;M11/M12/M21/M22:矩阵变换参数;SizingMethod:容器是否改变尺寸去适应目标图像。详细参考msdn的Matrix Filter和中文Matrix说明。

判断浏览器是否支持,也是创建一个div,看它有没有"filters"属性:

function (){  return   " filters "   in  document.createElement( " div " ); }()

在init程序中也用initImg方法对图片进行设置,此外还需要设置Matrix滤镜:

this ._img.style.filter  =   " progid:DXImageTransform.Microsoft.Matrix(SizingMethod='auto expand') " ;

这里会设置SizingMethod属性,它有两个值,分别是:clip to original(容器不改变尺寸)和auto expand(容器改变尺寸以适应目标图像)。如果使用默认值clip to original,容器的大小不会变,那么变换时超出容器的部分就会隐藏不见,所以这里要设为'auto expand'才能完整显示图片。

在load程序中显示图片,为了防止ie重复加载gif的bug还要重置onload为null。ps:该bug的研究可以参考这里的显示预览部分。

而show程序也跟css3模式类似,通过getMatrix方法获取变换参数,并设置到滤镜中:

$$.extend(    img.filters.item( " DXImageTransform.Microsoft.Matrix " ),    getMatrix(  this ._radian,  this ._x,  this ._y ));

滤镜使用了'auto expand'后,变换时图片元素尺寸会随着内容变化,所以要重新设置居中:

img.style.top  =  (  this ._clientHeight  -  img.offsetHeight )  /   2   +   " px " ;img.style.left  =  (  this ._clientWidth  -  img.offsetWidth )  /   2   +   " px " ;

ie还有其他变换滤镜,例如FlipH(水平翻转)、FlipV(垂直翻转)、Wave(扭曲)等。

【canvas】

通过滤镜和css3已经能在主流的浏览器上兼容实现相同的变换,最后再用canvas来实现。canvas是一个用来绘制图形的元素,它最强大的地方在于结合js来绘制图形甚至制作动画和游戏。ps:这里推荐几个入门文章:Opera的HTML 5 canvas和深入了解canvas标签系列。

要知道浏览器是否支持canvas,可以创建一个canvas元素,看它是否有"getContext"方法来判断:

function (){  return   " getContext "   in  document.createElement( ' canvas ' ); }()

getContext方法用来获取渲染空间(也叫上下文),之后会在这个空间绘图,相当于获取画布。

在init程序中,创建并设置canvas及其上下文context:

代码 var  canvas  =   this ._canvas  =  document.createElement( ' canvas ' ),    context  =   this ._context  =  canvas.getContext( ' 2d ' );$$D.setStyle( canvas, { position:  " absolute " , left:  0 , top:  0  } );canvas.width  =   this ._clientWidth; canvas.height  =   this ._clientHeight; this ._container.appendChild(canvas);

程序中只需要2D canvas,所以用getContext('2d')就行了。ps:关于3D canvas在Opera的HTML 5 canvas有相关的介绍。还需要设置尺寸,这里要注意要用width和height来设置,我试过用样式来设置,结果画图不正常。

在show程序中进行变换和画图:

代码 context.save();context.clearRect(  0 0 , clientWidth, clientHeight );context.translate( clientWidth  /   2  , clientHeight  /   2  );context.rotate(  this ._radian );context.scale(  this ._x,  this ._y );context.drawImage( img,  - img.width  /   2 - img.height  /   2  );context.restore();

这里用到了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中记录容器的中心坐标:

var  rect  =  $$D.clientRect(  this ._container ); this ._mrX  =  rect.left  +   this ._clientWidth  /   2 ; this ._mrY  =  rect.top  +   this ._clientHeight  /   2 ;

再根据clientX/clientY当前位置坐标计算弧度:

this ._mrRadian  =  Math.atan2( e.clientY  -   this ._mrY, e.clientX  -   this ._mrX )  -   this ._radian;

这里把原来的弧度也顺便计算了。在拖动的过程中,根据移动坐标获取弧度,并调用rotate来旋转:

this .rotate( Math.atan2( e.clientY  -   this ._mrY, e.clientX  -   this ._mrX )  -   this ._mrRadian );

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就更适合做复杂的图形和动画。

【选择图片】

程序实例化之后,还需要调用load方法加载指定的图片。参数可以是图片的路径,data url(支持的话),ie6还可以用本地路径。如果是gif图片,就要注意不要用canvas,原因上面也说了,canvas只能显示一帧图片。

使用说明

实例化时,必须有容器对象或id作为参数:

var  trans  =   new  ImageTrans( container );

然后调用load方法加载图片:

trans.load(img);

可选参数用来设置系统的默认属性,包括:属性:    默认值//说明mode:  "css3|filter|canvas",zoom:  .1,//缩放比率onPreLoad: function(){},//图片加载前执行onLoad:  function(){},//图片加载后执行onError: function(err){}//出错时执行其中zoom、onPreLoad、onLoad、onError属性可以在程序初始化后动态设置。

提供以下变换方法:vertical:垂直翻转horizontal:水平翻转rotate: 旋转left:向左转90度right:向右转90度rotatebydegress:根据角度旋转scale:缩放zoomin:放大zoomout:缩小

还提供了以下方法:load:加载图片;reset:重置图像为默认状态;dispose:销毁程序。

加入拖动旋转扩展程序或滚轮缩放扩展程序后,会自动启用,可以自定义mouseRotate或mouseZoom属性为false来取消。

程序源码 

代码 var  ImageTrans  =   function (container, options){     this ._initialize( container, options );     this ._initMode();     if  (  this ._support ) {         this ._initContainer();         this ._init();    }  else  { // 模式不支持          this .onError( " not support " );    }};ImageTrans.prototype  =  {   // 初始化程序   _initialize:  function (container, options) {     var  container  =   this ._container  =  $$(container);     this ._clientWidth  =  container.clientWidth; // 变换区域宽度      this ._clientHeight  =  container.clientHeight; // 变换区域高度      this ._img  =   new  Image(); // 图片对象      this ._style  =  {}; // 备份样式      this ._x  =   this ._y  =   1 ; // 水平/垂直变换参数      this ._radian  =   0 ; // 旋转变换参数      this ._support  =   false ; // 是否支持变换      this ._init  =   this ._load  =   this ._show  =   this ._dispose  =  $$.emptyFunction;         var  opt  =   this ._setOptions(options);         this ._zoom  =  opt.zoom;         this .onPreLoad  =  opt.onPreLoad;     this .onLoad  =  opt.onLoad;     this .onError  =  opt.onError;         this ._LOAD  =  $$F.bind(  function (){         this .onLoad();  this ._load();  this .reset();         this ._img.style.visibility  =   " visible " ;    },  this  );        $$CE.fireEvent(  this " init "  );  },   // 设置默认属性   _setOptions:  function (options) {     this .options  =  { // 默认值         mode:         " css3|filter|canvas " ,        zoom:        . 1 , // 缩放比率         onPreLoad:     function (){}, // 图片加载前执行         onLoad:         function (){}, // 图片加载后执行         onError:     function (err){} // 出错时执行     };     return  $$.extend( this .options, options  ||  {});  },   // 模式设置   _initMode:  function () {     var  modes  =  ImageTrans.modes;     this ._support  =  $$A.some(  this .options.mode.toLowerCase().split( " | " ),  function (mode){        mode  =  modes[ mode ];         if  ( mode  &&  mode.support ) {            mode.init  &&  ( this ._init  =  mode.init); // 初始化执行程序             mode.load  &&  ( this ._load  =  mode.load); // 加载图片执行程序             mode.show  &&  ( this ._show  =  mode.show); // 变换显示程序             mode.dispose  &&  ( this ._dispose  =  mode.dispose); // 销毁程序              // 扩展变换方法             $$A.forEach( ImageTrans.transforms,  function (transform, name){                 this [ name ]  =   function (){                    transform.apply(  this , [].slice.call(arguments) );                     this ._show();                }            },  this  );             return   true ;        }    },  this  );  },   // 初始化容器对象   _initContainer:  function () {     var  container  =   this ._container, style  =  container.style, position  =  $$D.getStyle( container,  " position "  );     this ._style  =  {  " position " : style.position,  " overflow " : style.overflow }; // 备份样式      if  ( position  !=   " relative "   &&  position  !=   " absolute "  ) { style.position  =   " relative " ; }    style.overflow  =   " hidden " ;    $$CE.fireEvent(  this " initContainer "  );  },   // 加载图片   load:  function (src) {     if  (  this ._support ) {         var  img  =   this ._img, oThis  =   this ;        img.onload  ||  ( img.onload  =   this ._LOAD );        img.onerror  ||  ( img.onerror  =   function (){ oThis.onError( " err image " ); } );        img.style.visibility  =   " hidden " ;         this .onPreLoad();        img.src  =  src;    }  },   // 重置   reset:  function () {     if  (  this ._support ) {         this ._x  =   this ._y  =   1 this ._radian  =   0 ;         this ._show();    }  },   // 销毁程序   dispose:  function () {     if  (  this ._support ) {         this ._dispose();        $$CE.fireEvent(  this " dispose "  );        $$D.setStyle(  this ._container,  this ._style ); // 恢复样式          this ._container  =   this ._img  =   this ._img.onload  =   this ._img.onerror  =   this ._LOAD  =   null ;    }  }}; // 变换模式 ImageTrans.modes  =   function (){     var  css3Transform; // ccs3变换样式      // 初始化图片对象函数      function  initImg(img, container) {        $$D.setStyle( img, {            position:  " absolute " ,            border:  0 , padding:  0 , margin:  0 , width:  " auto " , height:  " auto " , // 重置样式             visibility:  " hidden " // 加载前隐藏         });        container.appendChild( img );    }     // 获取变换参数函数      function  getMatrix(radian, x, y) {         var  Cos  =  Math.cos(radian), Sin  =  Math.sin(radian);         return  {            M11: Cos  *  x, M12: - Sin  *  y,            M21: Sin  *  x, M22: Cos  *  y        };    }     return  {        css3: { // css3设置             support:  function (){                 var  style  =  document.createElement( " div " ).style;                 return  $$A.some(                    [  " transform " " MozTransform " " webkitTransform " " OTransform "  ],                     function (css){  if  ( css  in  style ) {                        css3Transform  =  css;  return   true ;                    }});            }(),            init:  function () { initImg(  this ._img,  this ._container ); },            load:  function (){                 var  img  =   this ._img;                $$D.setStyle( img, { // 居中                     top: (  this ._clientHeight  -  img.height )  /   2   +   " px " ,                    left: (  this ._clientWidth  -  img.width )  /   2   +   " px " ,                    visibility:  " visible "                 });            },            show:  function () {                 var  matrix  =  getMatrix(  this ._radian,  this ._y,  this ._x );                 // 设置变形样式                  this ._img.style[ css3Transform ]  =   " matrix( "                      +  matrix.M11  +   " , "   +  matrix.M21  +   " , "                      +  matrix.M12  +   " , "   +  matrix.M22  +   " , 0, 0) " ;            },            dispose:  function (){  this ._container.removeChild( this ._img); }        },        filter: { // 滤镜设置             support:  function (){  return   " filters "   in  document.createElement( " div " ); }(),            init:  function () {                initImg(  this ._img,  this ._container );                 // 设置滤镜                  this ._img.style.filter  =   " progid:DXImageTransform.Microsoft.Matrix(SizingMethod='auto expand') " ;            },            load:  function (){                 this ._img.onload  =   null ; // 防止ie重复加载gif的bug                  this ._img.style.visibility  =   " visible " ;            },            show:  function () {                 var  img  =   this ._img;                 // 设置滤镜                 $$.extend(                    img.filters.item( " DXImageTransform.Microsoft.Matrix " ),                    getMatrix(  this ._radian,  this ._y,  this ._x )                );                 // 保持居中                 img.style.top  =  (  this ._clientHeight  -  img.offsetHeight )  /   2   +   " px " ;                img.style.left  =  (  this ._clientWidth  -  img.offsetWidth )  /   2   +   " px " ;            },            dispose:  function (){  this ._container.removeChild( this ._img); }        },        canvas: { // canvas设置             support:  function (){  return   " getContext "   in  document.createElement( ' canvas ' ); }(),            init:  function () {                 var  canvas  =   this ._canvas  =  document.createElement( ' canvas ' ),                    context  =   this ._context  =  canvas.getContext( ' 2d ' );                 // 样式设置                 $$D.setStyle( canvas, { position:  " absolute " , left:  0 , top:  0  } );                canvas.width  =   this ._clientWidth; canvas.height  =   this ._clientHeight;                 this ._container.appendChild(canvas);            },            show:  function (){                 var  img  =   this ._img, context  =   this ._context,                    clientWidth  =   this ._clientWidth, clientHeight  =   this ._clientHeight;                 // canvas变换                 context.save();                context.clearRect(  0 0 , clientWidth, clientHeight ); // 清空内容                 context.translate( clientWidth  /   2  , clientHeight  /   2  ); // 中心坐标                 context.rotate(  this ._radian ); // 旋转                 context.scale(  this ._y,  this ._x ); // 缩放                 context.drawImage( img,  - img.width  /   2 - img.height  /   2  ); // 居中画图                 context.restore();            },            dispose:  function (){                 this ._container.removeChild(  this ._canvas );                 this ._canvas  =   this ._context  =   null ;            }        }    };}(); // 变换方法 ImageTrans.transforms  =  {   // 垂直翻转   vertical:  function () {     this ._radian  =  Math.PI  -   this ._radian;  this ._y  *=   - 1 ;  },   // 水平翻转   horizontal:  function () {     this ._radian  =  Math.PI  -   this ._radian;  this ._x  *=   - 1 ;  },   // 根据弧度旋转   rotate:  function (radian) {  this ._radian  =  radian; },   // 向左转90度   left:  function () {  this ._radian  -=  Math.PI / 2; },    // 向右转90度   right:  function () {  this ._radian  +=  Math.PI / 2; },    // 根据角度旋转   rotatebydegress:  function (degress) {  this ._radian  =  degress  *  Math.PI / 180; },    // 缩放   scale:  function  () {     function  getZoom(scale, zoom) {         return     scale  >   0   &&  scale  >- zoom  ?  zoom :                scale  <   0   &&  scale  <  zoom  ?- zoom :  0 ;    }     return   function (zoom) {  if ( zoom ){         var  hZoom  =  getZoom(  this ._y, zoom ), vZoom  =  getZoom(  this ._x, zoom );         if  ( hZoom  &&  vZoom ) {             this ._y  +=  hZoom;  this ._x  +=  vZoom;        }    }}  }(),   // 放大   zoomin:  function () {  this .scale( Math.abs( this ._zoom) ); },   // 缩小   zoomout:  function () {  this .scale(  - Math.abs( this ._zoom) ); }};

拖动旋转扩展

代码 ImageTrans.prototype._initialize  =  ( function (){     var  init  =  ImageTrans.prototype._initialize,        methods  =  {             " init " function (){                 this ._mrX  =   this ._mrY  =   this ._mrRadian  =   0 ;                 this ._mrSTART  =  $$F.bind( start,  this  );                 this ._mrMOVE  =  $$F.bind( move,  this  );                 this ._mrSTOP  =  $$F.bind( stop,  this  );            },             " initContainer " function (){                $$E.addEvent(  this ._container,  " mousedown " this ._mrSTART );            },             " dispose " function (){                $$E.removeEvent(  this ._container,  " mousedown " this ._mrSTART );                 this ._mrSTOP();                 this ._mrSTART  =   this ._mrMOVE  =   this ._mrSTOP  =   null ;            }        };     // 开始函数      function  start(e){         var  rect  =  $$D.clientRect(  this ._container );         this ._mrX  =  rect.left  +   this ._clientWidth  /   2 ;         this ._mrY  =  rect.top  +   this ._clientHeight  /   2 ;         this ._mrRadian  =  Math.atan2( e.clientY  -   this ._mrY, e.clientX  -   this ._mrX )  -   this ._radian;        $$E.addEvent( document,  " mousemove " this ._mrMOVE );        $$E.addEvent( document,  " mouseup " this ._mrSTOP );         if  ( $$B.ie ) {             var  container  =   this ._container;            $$E.addEvent( container,  " losecapture " this ._mrSTOP );            container.setCapture();        }  else  {            $$E.addEvent( window,  " blur " this ._mrSTOP );            e.preventDefault();        }    };     // 拖动函数      function  move(e){         this .rotate( Math.atan2( e.clientY  -   this ._mrY, e.clientX  -   this ._mrX )  -   this ._mrRadian );        window.getSelection  ?  window.getSelection().removeAllRanges() : document.selection.empty();    };     // 停止函数      function  stop(){        $$E.removeEvent( document,  " mousemove " this ._mrMOVE );        $$E.removeEvent( document,  " mouseup " this ._mrSTOP );         if  ( $$B.ie ) {             var  container  =   this ._container;            $$E.removeEvent( container,  " losecapture " this ._mrSTOP );            container.releaseCapture();        }  else  {            $$E.removeEvent( window,  " blur " this ._mrSTOP );        };    };     return   function (){         var  options  =  arguments[ 1 ];         if  (  ! options  ||  options.mouseRotate  !==   false  ) {             // 扩展钩子             $$A.forEach( methods,  function ( method, name ){                $$CE.addEvent(  this , name, method );            },  this  );        }        init.apply(  this , arguments );    }})();

滚轮缩放扩展 

代码 ImageTrans.prototype._initialize  =  ( function (){     var  init  =  ImageTrans.prototype._initialize,        mousewheel  =  $$B.firefox  ?   " DOMMouseScroll "  :  " mousewheel " ,        methods  =  {             " init " function (){                 this ._mzZoom  =  $$F.bind( zoom,  this  );            },             " initContainer " function (){                $$E.addEvent(  this ._container, mousewheel,  this ._mzZoom );            },             " dispose " function (){                $$E.removeEvent(  this ._container, mousewheel,  this ._mzZoom );                 this ._mzZoom  =   null ;            }        };     // 缩放函数      function  zoom(e){         this .scale((            e.wheelDelta  ?  e.wheelDelta  /  ( - 120 ) : (e.detail  ||   0 /   3         )  *  Math.abs( this ._zoom) );        e.preventDefault();    };     return   function (){         var  options  =  arguments[ 1 ];         if  (  ! options  ||  options.mouseZoom  !==   false  ) {             // 扩展钩子             $$A.forEach( methods,  function ( method, name ){                $$CE.addEvent(  this , name, method );            },  this  );        }        init.apply(  this , arguments );    }})();

 

完整实例下载

转载于:https://www.cnblogs.com/cloudgamer/archive/2010/08/16/ImageTrans.html

相关资源:数据结构—成绩单生成器
最新回复(0)