IE下及标准浏览器下的图片旋转(二)—— Canvas(1)
文章过长,一篇无法保存。
3. canvas
canvas 是html5中的新标签,使用canvas之前我们先看下它的定义:<canvas> 标签只是图形容器,您必须使用脚本来绘制图形。这个标 签是用来绘图的,包括2d和3d,拥有很多方法,因为我们只是拿来实现图片的旋转,所以只需要了解其中的3个方法即可,关于canvas的详细使用会写在 以后的篇幅中。
先讲下canvas实现旋转图片的原理:canvas标签相当于创建一个画布,不仅可以在上面画图,还可以插入图片,当我们在canvas中插入了图片,并使用其提供的旋转方法对画布旋转,即可实现旋转图片的目的。
canvas画布旋转式围绕圆点进行的,示例如图:
假 定蓝色方块是canvas标签,当我们对其内容进行旋转时,是旋转的整个画布,但是canvas本身的位置和大小是不会发生变化的,当内容旋转后如果超出 了画布,就会被遮挡住,默认旋转的原点是00坐标,也就是画布的左上角,并且,无论怎样旋转,它的X轴和Y轴都不会改变,即使我们旋转90度或者180 度。会ps的同学可以参考图层旋转,把中心点定在左上角即可。
来看个形象店的图示:
默认旋转90度后,内容全部超出画布,将不会显示,X轴和Y轴不变。如下图所示:
先来个示例:
javascript:
$(function () {
var canvas = document.getElementById("img_box").getContext('2d');
var img = new Image();
img.onload = function(){
canvas.drawImage(img,0,0);
}
img.src = '12.jpg';
})
css:
#img_box { background: #e5e5e5; }
html:
<canvas id="img_box" width="400px" height="200px"></canvas>
效果如图:
稍微讲解下代码:
(1) var canvas = document.getElementById("img_box").getContext('2d');
获取canvas标签并使用2D画图模式
(2) var img = new Image();
创建一个图片对象
(3) img.onload = function(){ }
图片加载完后执行函数
(4) canvas.drawImage(img,0,0);
drawImage()方法允许在canvas中插入其他图像。参数可以使3个(位移)5个(位移,缩放)或9个(位移,缩放,裁剪)。我们用3个就够了,第一个参数是图片地址,第二个是X轴位移,第三个是Y轴位移,我们让图片和原点(0,0)对齐就可以了。
如果我们把canvas的大小设置的和图片大小一样的话,那么久相当于图片充满了canvas画布,上例中我们的图片是120*90,我们把canvas标签的大小也设成120*90就会成这样:
可以看到没有了灰色区域,只有图片。
如果我们要对它旋转就需要用到rotate()方法,rotate(Math.PI)代表顺时针旋转180度,也即是说Math.PI=180度,-Math.PI=-180度,Math.PI/2=90度,以此类推。我们以旋转45度为例:
javascript:
$(function () {
var canvas = document.getElementById("img_box").getContext('2d'); ;
var img = new Image();
img.onload = function(){
canvas.drawImage(img,0,0);
}
canvas.rotate(Math.PI/4);
img.src = '12.jpg';
})
css:
#img_box { background: #e5e5e5; }
html:
<canvas id="img_box" width="120px" height="90px"></canvas>
效果如图:
我们可以看到使用rotate()方法方法旋转后,就如前面的原理如所示,canvas标签大小不变,内容会围绕原点(0,0)旋转整个画布。超出的部分会隐藏掉。由此我们可以推断,当旋转90度时,图片会完全看不到。我们需要把图片再拉回来,并且改变canvas标签的大小为图片旋转后的大小,也就是宽高互换。
因此我们需要使用translate()方法重新设定原点位置。以下以90度旋转为例,如有不明白translate()取值的同学,认真揣摩上面关于原点,XY轴的原理图,XY轴不变。
javascript:
$(function () {
var canvas = document.getElementById("img_box").getContext('2d'); ;
var img = new Image();
img.onload = function(){
canvas.drawImage(img,0,0);
}
canvas.rotate(Math.PI/2);
canvas.translate(0,-90);
img.src = '12.jpg';
})
css:
#img_box { background: #e5e5e5; }
html:
<canvas id="img_box" width="90px" height="120px"></canvas>
效果如图:
如果我们需要多次旋转,则需要在每次旋转前将原点复位到原始状态。例如我们进行90度旋转:
canvas.rotate(Math.PI/2);
canvas.translate(0,-90);
当我们再次旋转90度时,需要先复位原点,再旋转:
canvas.translate(0,90);
canvas.rotate(Math.PI/2);
canvas.translate(-120,-90);
完整的顺时针旋转360度代码:
canvas.rotate(Math.PI/2); //顺时针旋转90度
canvas.translate(0,-90); //位移,显示在画布上
canvas.translate(0,90); //复位原点(0,0)
canvas.rotate(Math.PI/2); //再次旋转90度,此时即是180度
canvas.translate(-120,-90); //位移
canvas.translate(120,90); //复位原点
canvas.rotate(Math.PI/2); //继续旋转90度,此时270度
canvas.translate(-120,0); //位移
canvas.translate(120,0); //复位原点
canvas.rotate(Math.PI/2); //继续旋转90度,此时360度,无需位移
当然,我们也可以先改变中心点,然后旋转画布,最后再插入图片,以旋转90度为例:
translate(90,0);canvas.rotate(Math.PI/2);我们看到如果这样的话,translate的 数值与之前是不同的,原因在于,之前先旋转,中心点是原点,旋转后图片超出被隐藏,我们需要把中心点移动旋转后的视觉位置,在视觉上是向右向下移动(正 数),实际上相对于旋转后的画布是向左向上移动(负数),而先旋转画布的话,我们要提前算好旋转后这个点的位置,然后向右向下移动,因为并未旋转,所以相 对于原点向右向下移动与视觉上的移动方向一致,所以是正数。不明白的同学好好体会体会,看看上面的示例图,自己拿个方形的东西转转,呵呵。
如果每次旋转后都需要手动复位原点,这样也有点太复杂了,算起来有点晕,其实大可不必这样,因为canvas给我们提供了一种复位方法save()和restore()。
save()用来保存canvas的状态(注意是canvas画布,而不是我们画的图或者对图片等的操作),restore()用来恢复。restore()总是会寻找离它最近的save()恢复,并且restore()的个数不能多于save()的个数,这个不难理解,你保存10次恢复11次,肯定会出错嘛。
我们看个示例:
javascript:
window.onload = function(){
var canvas = document.getElementById("cv");
canvas.height = 250;
canvas.width = 400;
var context = canvas.getContext("2d");
context.save();
var img1 = new Image();
img1.onload = function(){
context.translate(90,0);
context.rotate(Math.PI/2);
context.drawImage(img1,0,0);
context.restore();
}
img1.src = '12.jpg';
var img2 = new Image();
img2.onload = function(){
context.drawImage(img2,0,0);
}
img2.src = '13.jpg';
};
css:
#cv { background: #e5e5e5; }
html:
<canvas id="cv"></canvas>
效果如图:
如果我们去掉 img1.onload = function(){ }中的context.restore(); 就会变成这样:
我 们看到,img1旋转了90度,不加restore(),img2也是旋转90度,加上后img2不受影响,为什么呢?我们往上看,创建canvas画布 后,我们就进行了一次save(),这时我们并没有对canvas画布做任何操作,当img1进行旋转后,画布就成为了旋转90度,如果我们直接加入 img2,那么img2也是在画布旋转90的状态下插入的,如果我们使用restore(),那么canvas画布就会恢复到上一次save()状态(注意,是canvas画布恢复,我们对img1进行的操作不会受影响),这时我们再加入img2,就不会受影响了,这是个很关键的使用方法,复杂的画图都要用到多次save()和restore()。
文章过长,一篇无法保存
IE下及标准浏览器下的图片旋转(二)—— Canvas(2)