IE下及标准浏览器下的图片旋转(二)—— Canvas(1)
?
??????文章過長,一篇無法保存。
??????IE下及標(biāo)準(zhǔn)瀏覽器下的圖片旋轉(zhuǎn)(一)——濾鏡,CSS3
?
3.?canvas
?
??????canvas 是html5中的新標(biāo)簽,使用canvas之前我們先看下它的定義:<canvas>?標(biāo)簽只是圖形容器,您必須使用腳本來繪制圖形。這個標(biāo) 簽是用來繪圖的,包括2d和3d,擁有很多方法,因為我們只是拿來實(shí)現(xiàn)圖片的旋轉(zhuǎn),所以只需要了解其中的3個方法即可,關(guān)于canvas的詳細(xì)使用會寫在 以后的篇幅中。
?
??????先講下canvas實(shí)現(xiàn)旋轉(zhuǎn)圖片的原理:canvas標(biāo)簽相當(dāng)于創(chuàng)建一個畫布,不僅可以在上面畫圖,還可以插入圖片,當(dāng)我們在canvas中插入了圖片,并使用其提供的旋轉(zhuǎn)方法對畫布旋轉(zhuǎn),即可實(shí)現(xiàn)旋轉(zhuǎn)圖片的目的。
?
??????canvas畫布旋轉(zhuǎn)式圍繞圓點(diǎn)進(jìn)行的,示例如圖:
?
??????假 定藍(lán)色方塊是canvas標(biāo)簽,當(dāng)我們對其內(nèi)容進(jìn)行旋轉(zhuǎn)時,是旋轉(zhuǎn)的整個畫布,但是canvas本身的位置和大小是不會發(fā)生變化的,當(dāng)內(nèi)容旋轉(zhuǎn)后如果超出 了畫布,就會被遮擋住,默認(rèn)旋轉(zhuǎn)的原點(diǎn)是00坐標(biāo),也就是畫布的左上角,并且,無論怎樣旋轉(zhuǎn),它的X軸和Y軸都不會改變,即使我們旋轉(zhuǎn)90度或者180 度。會ps的同學(xué)可以參考圖層旋轉(zhuǎn),把中心點(diǎn)定在左上角即可。
?
??????來看個形象店的圖示:
?
?
??????默認(rèn)旋轉(zhuǎn)90度后,內(nèi)容全部超出畫布,將不會顯示,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標(biāo)簽并使用2D畫圖模式
?
??????(2)?var?img?=?new?Image();?
??????創(chuàng)建一個圖片對象
?
??????(3)?img.onload?=?function(){?}?
??????圖片加載完后執(zhí)行函數(shù)
?
??????(4)?canvas.drawImage(img,0,0);?
??????drawImage()方法允許在canvas中插入其他圖像。參數(shù)可以使3個(位移)5個(位移,縮放)或9個(位移,縮放,裁剪)。我們用3個就夠了,第一個參數(shù)是圖片地址,第二個是X軸位移,第三個是Y軸位移,我們讓圖片和原點(diǎn)(0,0)對齊就可以了。
?
??????如果我們把canvas的大小設(shè)置的和圖片大小一樣的話,那么久相當(dāng)于圖片充滿了canvas畫布,上例中我們的圖片是120*90,我們把canvas標(biāo)簽的大小也設(shè)成120*90就會成這樣:
?
?
??????可以看到?jīng)]有了灰色區(qū)域,只有圖片。
?
??????如果我們要對它旋轉(zhuǎn)就需要用到rotate()方法,rotate(Math.PI)代表順時針旋轉(zhuǎn)180度,也即是說Math.PI=180度,-Math.PI=-180度,Math.PI/2=90度,以此類推。我們以旋轉(zhuǎn)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()方法方法旋轉(zhuǎn)后,就如前面的原理如所示,canvas標(biāo)簽大小不變,內(nèi)容會圍繞原點(diǎn)(0,0)旋轉(zhuǎn)整個畫布。超出的部分會隱藏掉。由此我們可以推斷,當(dāng)旋轉(zhuǎn)90度時,圖片會完全看不到。我們需要把圖片再拉回來,并且改變canvas標(biāo)簽的大小為圖片旋轉(zhuǎn)后的大小,也就是寬高互換。
?
??????因此我們需要使用translate()方法重新設(shè)定原點(diǎn)位置。以下以90度旋轉(zhuǎn)為例,如有不明白translate()取值的同學(xué),認(rèn)真揣摩上面關(guān)于原點(diǎn),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>
?
????效果如圖:
?
??????如果我們需要多次旋轉(zhuǎn),則需要在每次旋轉(zhuǎn)前將原點(diǎn)復(fù)位到原始狀態(tài)。例如我們進(jìn)行90度旋轉(zhuǎn):
??????canvas.rotate(Math.PI/2);
??????canvas.translate(0,-90);
?
??????當(dāng)我們再次旋轉(zhuǎn)90度時,需要先復(fù)位原點(diǎn),再旋轉(zhuǎn):
??????canvas.translate(0,90);
??????canvas.rotate(Math.PI/2);
??????canvas.translate(-120,-90);
?
??????完整的順時針旋轉(zhuǎn)360度代碼:
??????canvas.rotate(Math.PI/2);???//順時針旋轉(zhuǎn)90度
??????canvas.translate(0,-90);???//位移,顯示在畫布上
??????canvas.translate(0,90);???//復(fù)位原點(diǎn)(0,0)
??????canvas.rotate(Math.PI/2);???//再次旋轉(zhuǎn)90度,此時即是180度
??????canvas.translate(-120,-90);???//位移
??????canvas.translate(120,90);???//復(fù)位原點(diǎn)
??????canvas.rotate(Math.PI/2);???//繼續(xù)旋轉(zhuǎn)90度,此時270度
??????canvas.translate(-120,0);???//位移
??????canvas.translate(120,0);???//復(fù)位原點(diǎn)
??????canvas.rotate(Math.PI/2);??//繼續(xù)旋轉(zhuǎn)90度,此時360度,無需位移
?
??????當(dāng)然,我們也可以先改變中心點(diǎn),然后旋轉(zhuǎn)畫布,最后再插入圖片,以旋轉(zhuǎn)90度為例:
?
??????translate(90,0);canvas.rotate(Math.PI/2);我們看到如果這樣的話,translate的 數(shù)值與之前是不同的,原因在于,之前先旋轉(zhuǎn),中心點(diǎn)是原點(diǎn),旋轉(zhuǎn)后圖片超出被隱藏,我們需要把中心點(diǎn)移動旋轉(zhuǎn)后的視覺位置,在視覺上是向右向下移動(正 數(shù)),實(shí)際上相對于旋轉(zhuǎn)后的畫布是向左向上移動(負(fù)數(shù)),而先旋轉(zhuǎn)畫布的話,我們要提前算好旋轉(zhuǎn)后這個點(diǎn)的位置,然后向右向下移動,因為并未旋轉(zhuǎn),所以相 對于原點(diǎn)向右向下移動與視覺上的移動方向一致,所以是正數(shù)。不明白的同學(xué)好好體會體會,看看上面的示例圖,自己拿個方形的東西轉(zhuǎn)轉(zhuǎn),呵呵。
?
??????如果每次旋轉(zhuǎn)后都需要手動復(fù)位原點(diǎn),這樣也有點(diǎn)太復(fù)雜了,算起來有點(diǎn)暈,其實(shí)大可不必這樣,因為canvas給我們提供了一種復(fù)位方法save()和restore()。
?
?????save()用來保存canvas的狀態(tài)(注意是canvas畫布,而不是我們畫的圖或者對圖片等的操作),restore()用來恢復(fù)。restore()總是會尋找離它最近的save()恢復(fù),并且restore()的個數(shù)不能多于save()的個數(shù),這個不難理解,你保存10次恢復(fù)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>
?
????效果如圖:
?
?
??????如果我們?nèi)サ?img1.onload?=?function(){?}中的context.restore();??就會變成這樣:
?
?
??????我 們看到,img1旋轉(zhuǎn)了90度,不加restore(),img2也是旋轉(zhuǎn)90度,加上后img2不受影響,為什么呢?我們往上看,創(chuàng)建canvas畫布 后,我們就進(jìn)行了一次save(),這時我們并沒有對canvas畫布做任何操作,當(dāng)img1進(jìn)行旋轉(zhuǎn)后,畫布就成為了旋轉(zhuǎn)90度,如果我們直接加入 img2,那么img2也是在畫布旋轉(zhuǎn)90的狀態(tài)下插入的,如果我們使用restore(),那么canvas畫布就會恢復(fù)到上一次save()狀態(tài)(注意,是canvas畫布恢復(fù),我們對img1進(jìn)行的操作不會受影響),這時我們再加入img2,就不會受影響了,這是個很關(guān)鍵的使用方法,復(fù)雜的畫圖都要用到多次save()和restore()。
?
??????文章過長,一篇無法保存
??????IE下及標(biāo)準(zhǔn)瀏覽器下的圖片旋轉(zhuǎn)(二)——?Canvas(2)
?
轉(zhuǎn)載于:https://www.cnblogs.com/k13web/p/4139482.html
總結(jié)
以上是生活随笔為你收集整理的IE下及标准浏览器下的图片旋转(二)—— Canvas(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu 串口转usb使用
- 下一篇: 从HTML5移动应用现状谈发展趋势