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