摘要:但需要注意的是,需在使用前調(diào)用。當(dāng)然,你愿意的話也可以兩者結(jié)合著用。繪制圖像相信很多入門(mén)的,都看不到這個(gè)地方,不就是繪制圖像的嘛,啊不準(zhǔn)確,是繪制圖形的。明確的說(shuō),是指圍繞原點(diǎn)圖像旋轉(zhuǎn)弧度。
前言
本文寫(xiě)在七月底,進(jìn)來(lái)不加班就整理了一下,一些非?;A(chǔ)的知識(shí),對(duì)于canvas剛?cè)腴T(mén)的人來(lái)說(shuō),值得閱讀一下。
來(lái)個(gè)氣勢(shì)如虹的開(kāi)頭與看各種文章相比,我更喜歡數(shù)學(xué)里的邏輯;與學(xué)習(xí)各種日新月異的框架相比,我更喜歡基礎(chǔ)扎實(shí)帶給人的那種踏實(shí);與拼湊頁(yè)面頁(yè)面來(lái)回跳轉(zhuǎn)相比,我更喜歡動(dòng)畫(huà),圖形在頁(yè)面中表現(xiàn)的直觀。
也許你和我一樣,沖著對(duì)H5的好奇,沖著對(duì)圖形的熱愛(ài),學(xué)了一下canvas,沒(méi)有熟練,只是簡(jiǎn)單入了個(gè)門(mén),或許你在入門(mén)的門(mén)檻上就絆倒了,同學(xué)不哭,站起來(lái)繼續(xù)擼。我把我入門(mén)兩天的積累寫(xiě)下來(lái),有些門(mén)檻,絆倒了數(shù)百次,有些應(yīng)該也適合你。下文的ctx指的是canvas創(chuàng)建的2d圖形化實(shí)例,代碼:
var canvas = document.querySelector("#test"); //test是Html中一個(gè)canvas元素的ID,其寬為600,高為400; var ctx = canvas.getContext("2d");說(shuō)件重要的事
2d上下文(畫(huà)布)坐標(biāo)開(kāi)始于
四個(gè)基本方法 描邊:stroke與strokeStylectx.strokeStyle = "red"; ctx.arc(200,200,50,0,PI*2,false); ctx.stroke();
lineTo,moveTo方法,很基礎(chǔ),這里特別說(shuō)一下arc(x,y,r,startAngle,endAngle,direction)畫(huà)圓的方法,這個(gè)方法接受6個(gè)參數(shù),前五個(gè)是必須的,分別是圓心位置(x坐標(biāo),y坐標(biāo)),然后是圓的半徑r,再然后是起始位置角和終止位置角,這兩個(gè)很重要,結(jié)合前面那張圖理解更,我們可知,上面這段代碼繪制的第一個(gè)點(diǎn)是(0,50),終止位置也是(0,50)。后面direction是一個(gè)可選參數(shù),默認(rèn)為false,表示順時(shí)針繪制,為true時(shí),為逆時(shí)針繪制。
特別說(shuō)明:
紅寶書(shū)上說(shuō)繪制路徑,都應(yīng)該以beginPath()方法開(kāi)始,但實(shí)踐證明,這并不需要,你只需要在stroke這個(gè)方法來(lái)結(jié)束這段路徑的繪制,但加了也不壞事,所以還是加上吧;
只調(diào)用一次lineTo(0,50)方法,你是看不到一條直線繪制出來(lái)的,因?yàn)椋?,0)并不是默認(rèn)的起點(diǎn),除非你先用moveTo()方法設(shè)置一個(gè)起點(diǎn),這個(gè)簡(jiǎn)單的道理叫兩點(diǎn)確定一條直線;
closePath()并不是一個(gè)與beginPath對(duì)照使用的方法,其作用是繪制閉合路徑,比如下圖所示??梢钥吹轿覀冎徽{(diào)用了兩次lineTo方法,但最后繪制除了三條線,最后這一條線就是closePath作用出來(lái)的。但需要注意的是,closePath需在stroke使用前調(diào)用。
填充:fillStyle與fillctx.fillStyle = "red" ctx.arc(200,200,50,0,PI/3,false); ctx.fill();
與描邊對(duì)應(yīng)的就是填充,但這個(gè)方法很不講究,通常來(lái)講,只有封閉區(qū)間才有資格填充,但fill這個(gè)方法不需要,只要你的路徑不是一條直線,那它就能被填充,也就是不在同一條直線上的三點(diǎn),能確定一個(gè)面,這個(gè)方法真的很牛逼,我是必須服氣的。
繪制文本:stokeText與fillText以上兩個(gè)方法都能寫(xiě)出一個(gè)字,但推薦的用法是fillText,因?yàn)槠鋵?xiě)出來(lái)的是實(shí)心字,而stokeText寫(xiě)出來(lái)的是描邊空心字,絕大多數(shù)藝術(shù)字會(huì)采用這種寫(xiě)法。當(dāng)然,你愿意的話也可以兩者結(jié)合著用。
ctx.fillStyle = "red" ctx.font= "bold 12px Arial"; ctx.fillText("Test",300,200); ctx.strokeStyle = "red" ctx.font= "bold 12px Arial"; ctx.strokeText("Test",400,200);繪制圖像:drawImage
相信很多入門(mén)的,都看不到這個(gè)地方,canvas不就是繪制圖像的嘛,啊,不準(zhǔn)確,canvas是繪制圖形的。具體說(shuō)來(lái)就是drawImage,它不只能把圖片繪制到畫(huà)布上,他還能繪制canvas圖形,這個(gè)在星空,雨滴等案列中應(yīng)用最多,也是canvas離屏優(yōu)化用的最多的,看下面這個(gè)示例。
var cache = document.createElement("canvas");
cache.width = 50;
cache.height = 50;
var cacheCtx = cache.getContext("2d"); //這是一塊虛擬畫(huà)布,因?yàn)槲刺砑拥絛om節(jié)點(diǎn)中;
cacheCtx.beginPath(); cacheCtx.strokeStyle = "red"; cacheCtx.moveTo(5,5); cacheCtx.lineTo(20,40); cacheCtx.lineTo(40,20); cacheCtx.closePath(); cacheCtx.stroke(); ctx.drawImage(cache,50,50); ctx.drawImage(cache,50,100); ctx.drawImage(cache,100,50); ctx.drawImage(cache,100,100);
通過(guò)上例,我們就能看出drawImage在離屏優(yōu)化中的應(yīng)用。為什么這樣可以,因?yàn)椋裆厦嬉粯?,我們要在一塊畫(huà)布上,畫(huà)四個(gè)相同的三角形,這在瀏覽器表現(xiàn)上,你看不出任何卡頓,那如果你是要在屏幕上繪制一千個(gè)或萬(wàn)個(gè)這樣的圖形,且每一幀還要有規(guī)律的變換他們的位置,這時(shí)你就能明顯感覺(jué)出瀏覽器的卡頓,因?yàn)槟阋恢痹诓僮鱠om中的元素,使瀏覽器一直在不停的重新繪制,渲染網(wǎng)頁(yè)。但如果你在每一幀繪制下一個(gè)狀態(tài)前,在js中,通過(guò)在虛擬的canvas中先繪制好下一幀的背景狀態(tài),然后通過(guò)drawImage這個(gè)方法,來(lái)更新瀏覽器中的畫(huà)布狀態(tài),這樣網(wǎng)頁(yè)在一幀中就只需要渲染一次,而不是時(shí)時(shí)在渲染,這就達(dá)到了離屏優(yōu)化的目的,所以這也是drawImage用的最多的場(chǎng)景。
過(guò)完以上知識(shí),就算是復(fù)習(xí)一下入門(mén)知識(shí)了,至于為什么沒(méi)提fillRect與strokeRect,其實(shí)那就是stroke與fill提供給繪制矩形的一個(gè)語(yǔ)法糖。
奇妙的變換也許你和我一樣,不習(xí)慣自己的坐標(biāo)系是從左上角開(kāi)始的,我們更習(xí)慣坐標(biāo)原點(diǎn)在左下角或者正中心。
坐標(biāo)原點(diǎn)變換 translate方法原點(diǎn)變換到畫(huà)布中心:ctx.translate(WIDTH/2,HEIGHT/2),WIDTH與HEIGHT分別指畫(huà)布的寬與高,為了將坐標(biāo)變換表現(xiàn)得更明顯,我在同一塊區(qū)域,畫(huà)了兩塊大小相似的畫(huà)布,然后讓一塊使用原始坐標(biāo)系,一塊采用translate變換后的,具體看代碼,和結(jié)果圖;
坐標(biāo)系旋轉(zhuǎn)變換 rotate方法var ctx = document.querySelector("#test").getContext("2d"); var crx = document.querySelector("#testa").getContext("2d"); ctx.beginPath(); ctx.strokeStyle = "blue"; ctx.arc(0,0,5,0,PI*2,false); ctx.moveTo(0,0); ctx.lineTo(0,150); ctx.moveTo(0,0); ctx.lineTo(150,0); ctx.stroke(); crx.beginPath(); crx.translate(300,200); crx.arc(0,0,5,0,PI*2,false); crx.strokeStyle = "red"; crx.moveTo(0,0); crx.lineTo(0,150); crx.moveTo(0,0); crx.lineTo(150,0); crx.stroke();
也許你接觸canvas很久了,但rotate方法始終沒(méi)有機(jī)會(huì)用,只記得紅寶書(shū)上在繪制鐘表時(shí)針,分針時(shí),提到了rotate的用法,但只要你熟悉,用法就能千奇百怪。API明確的說(shuō)rotate(angle),是指圍繞原點(diǎn)圖像旋轉(zhuǎn)angle弧度。所以,你需要記住兩點(diǎn)。第一:圖像是圍繞原點(diǎn)旋轉(zhuǎn);第二:與其說(shuō)是圖像旋轉(zhuǎn),不如說(shuō)是整個(gè)坐標(biāo)系旋轉(zhuǎn)了。看示例,還是和上面一樣,有對(duì)比,才有說(shuō)服力:
ctx.beginPath(); ctx.strokeStyle = "blue"; ctx.translate(300,200); ctx.arc(0,0,5,0,PI*2,false); ctx.moveTo(0,0); ctx.lineTo(0,150); ctx.moveTo(0,0); ctx.lineTo(150,0); ctx.stroke(); ctx.moveTo(0,0); ctx.lineTo(0,-150); ctx.stroke(); crx.beginPath(); crx.strokeStyle = "red"; crx.translate(300,200); crx.rotate(PI/3); //旋轉(zhuǎn)60* crx.arc(0,0,5,0,PI*2,false); crx.moveTo(0,0); crx.lineTo(0,150); crx.moveTo(0,0); crx.lineTo(150,0); crx.stroke(); crx.moveTo(0,0); crx.lineTo(0,-150); crx.stroke();
與上個(gè)圖相比,我將兩塊畫(huà)布的中心都先變換到了畫(huà)布的中心,作為對(duì)比,紅色畫(huà)筆的做了旋轉(zhuǎn)變換,在分別繪制了正x,正y軸以后,在stoke方法結(jié)束一段繪制以后,又繪制了負(fù)y軸,可以看到,上一段繪制路徑的rotate仍然起作用,所以rotate是對(duì)畫(huà)布坐標(biāo)系做了變換,而不是狹義上的繪制圖像,這個(gè)區(qū)別很重要。后面在上一段代碼,不用sin,cos計(jì)算,就能繪制一個(gè)正多邊形,這里以6邊形為例。
ctx.beginPath(); ctx.translate(300,200); ctx.strokeStyle = "red"; var a=0; for(var i=1;i<7;i++){ ctx.lineTo(0,150); ctx.rotate(PI/3); a =a + PI/3 ; } ctx.closePath(); ctx.stroke(); ctx.lineTo(0,0); ctx.stroke();不重要,但很點(diǎn)題的API
繪制一個(gè)普通的圖形,也許上面的API也已足夠,但要讓你的圖形有亮點(diǎn),你可能還需要多了解一些,我個(gè)人覺(jué)得非常有用的兩個(gè)就是陰影的繪制(shadow)與漸變色的添加(createLinearGradient)。在用canvas做星星背景時(shí),或者飛行的流星周?chē)拈W光,這些都是用shadow做出來(lái)的特效。而消逝的流星,頭部亮,尾部暗的效果就是用漸變色做的,在以后的系列中,會(huì)結(jié)合實(shí)例多講一些。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/92281.html
摘要:前言月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議那么今天我就把看過(guò)的一些學(xué)習(xí)資源主要是博客,博文推薦分享給大家。 1.前言 6月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多9月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了!一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議!那么今天我就...
摘要:百煉成仙走紅該書(shū)于年月出版,作者楊逸飛是一名從事開(kāi)發(fā)六年的程序員,寫(xiě)過(guò)諸多技術(shù)博客。作者在博客上對(duì)粉絲提出關(guān)于百煉成仙的問(wèn)題進(jìn)行了統(tǒng)一回復(fù),該博文持續(xù)占據(jù)熱榜第二,熱度達(dá)。 剛接觸編程的小伙伴,估計(jì)都想過(guò)把枯燥無(wú)聊的編程教材變成小說(shuō)讀的念頭,這不,說(shuō)曹操曹操就來(lái)了,真的有程序員用寫(xiě)修仙小說(shuō)的...
摘要:功能三滴滴費(fèi)用計(jì)算古人云細(xì)節(jié)決定成敗,一個(gè)良好的微信小程序往往就是一些細(xì)節(jié)打動(dòng)人心,居然是模仿,雖做不到百分百,至少還是很希望一模一樣。 最近時(shí)常感嘆道:時(shí)間總是那么的快,轉(zhuǎn)瞬即逝。對(duì)于像我這種剛?cè)腴T(mén)的小生來(lái)講,技術(shù)每天都在更新,框架也層出不窮,有時(shí)候還沒(méi)弄懂這個(gè)知識(shí)大牛們又推出了更好的技術(shù)。當(dāng)然學(xué)習(xí)好的技術(shù)也是十分重要的。但是在學(xué)習(xí)之后怎樣才能夠得到自己想要的呢,一個(gè)好的建議便是靜...
閱讀 2930·2021-11-25 09:43
閱讀 1149·2021-10-11 10:57
閱讀 2621·2020-12-03 17:20
閱讀 3889·2019-08-30 14:05
閱讀 2526·2019-08-29 14:00
閱讀 2058·2019-08-29 12:37
閱讀 1757·2019-08-26 11:34
閱讀 3299·2019-08-26 10:27