這篇是canvas API系列的首尾之做,這篇之後,全部的canvas的屬性和方法就將完了,哦,不對,應該是大部分經常使用的,還有部分不經常使用的屬性和方法,由於種種緣由,就不介紹了,後期的重點就是多寫一點canvas的實踐小實例了,恩,我以爲這纔是最實用的,俗話說一例抵千言啊,廢話很少說,咱們來看看剩下的一些屬性和方法吧!css
一、createPatterncanvas
createPattern(image,"repeat|repeat-x|repeat-y|no-repeat") 在指定的方向上重複指定的元素數組
參數: image指實用的圖片,畫布或者是視頻對象 第二個參數表示重複的方式app
看這後面的參數,很容易想到css中的background-repeat,第一個參數我得說一下,這裏跟background不同,不是引用的圖片地址,而是一個圖片對象,這裏特別注意,咱們分別看一下這些重複方式的表現:this
var aImg = new Image(); aImg.src = '4.jpg'; aImg.onload = function(){ draw(this); } function draw(obj){ //這裏爲了演示方便,把其餘的先註釋 //var bg = ctx.createPattern(obj,"repeat"); //var bg = ctx.createPattern(obj,"repeat-x"); //var bg = ctx.createPattern(obj,"repeat-y"); var bg = ctx.createPattern(obj,"no-repeat"); ctx.fillStyle = bg; ctx.fillRect(0,0,400,400); }
恩,跟css的background-repeat的效果是同樣的,那就好理解了,可是canvas是沒有background-position的,恩,這個效果就是這樣,沒什麼好講的!spa
具體效果看這裏 —— canvas 背景重複翻譯
二、gloableCompositeOperation3d
gloableCompositeOperation() 設置或返回新圖像如何繪製到已有的圖像上code
參數:視頻
source-over 默認,在目標圖像上顯示源圖像。
source-atop 在目標圖像頂部顯示源圖像。源圖像位於目標圖像以外的部分是不可見的。
source-in 在目標圖像中顯示源圖像。只有目標圖像內的源圖像部分會顯示,目標圖像是透明的。
source-out 在目標圖像以外顯示源圖像。只會顯示目標圖像以外源圖像部分,目標圖像是透明的。
destination-over 在源圖像上方顯示目標圖像。
destination-atop 在源圖像頂部顯示目標圖像。源圖像以外的目標圖像部分不會被顯示。
destination-in 在源圖像中顯示目標圖像。只有源圖像內的目標圖像部分會被顯示,源圖像是透明的。
destination-out 在源圖像外顯示目標圖像。只有源圖像外的目標圖像部分會被顯示,源圖像是透明的。
lighter 顯示源圖像 + 目標圖像,即相交部分圖形前後填充來增長亮度
copy 顯示源圖像。忽略目標圖像,即只顯示源圖像
xor 使用異或操做對源圖像與目標圖像進行組合,即相交部分爲透明
不經常使用的:
multiply 源圖像的像素乘以目標圖像的像素
screen
overlay
darken 加深,相交部分圖形前後填充來下降亮度
lighten 加亮,相交部分圖形前後填充來增長亮度
color-dodge 將底層調到頂層,即將目標圖像調到源圖像上方
color-burn 將底層調到頂層,而後反轉
hard-light 將底層調到頂層,而後 multiply效果與screen疊加
soft-light
difference
exclusion
hue
saturation
color
luminosity
因爲英文很差,部分的經常使用的參數的意思不太好解釋,爲了避免誤導你們,我就不翻譯了,若是有英文比較好的,看看這裏 gloableCompositeOperation參數解釋 ,要是能比較清楚的翻譯的話,但願你能把翻譯的意思告訴我,不勝感謝,英語是硬傷啊!不事後面的運行結果我會給到你們參考!
參數不少,咱們先看看經常使用的,前面八個很好理解,就是一個反的,首先咱們須要理解,什麼是目標圖形?什麼是源圖形?
目標圖像 = 您已經放置在畫布上的繪圖;源圖像 = 您打算放置到畫布上的繪圖。這是官方的解釋,若是你對這個解釋不理解,咱們能夠這麼理解,就是先畫的圖像是目標圖形,後畫的圖像是源圖像,例如:
//目標圖像 ctx.fillStyle="red"; ctx.fillRect(20,20,75,50); ctx.globalCompositeOperation="source-over"; //源圖像 ctx.fillStyle="blue"; ctx.fillRect(50,50,75,50);
固然這個gloableCompositeOperation的位置不是固定的,能夠放到目標圖像前面,也能夠放到目標圖像後面,可是不能放到源圖像後面(大家懂的),參數意思如很差理解,看下圖,看看是什麼表現:
var arr = ['source-over','source-atop','source-in','source-out','destination-over','destination-atop','destination-in','destination-out','lighter','copy','xor','multiply','screen','overlay','darken','lighten','color-dodge','color-burn','hard-light','soft-light','difference','exclusion','hue','saturation','color','luminosity']; for(var i=0;i<arr.length;i++){ document.write("<div id='p_" + i + "' style='float:left;'>" + arr[i] + ":<br>"); var canvas = document.createElement("canvas"); canvas.width = 120; canvas.height = 100; canvas.style.border = "1px solid #000"; canvas.style.marginRight = '10px'; document.getElementById("p_" + i).appendChild(canvas); var ctx = canvas.getContext("2d"); ctx.fillStyle="red"; ctx.fillRect(10,10,50,50); ctx.globalCompositeOperation=arr[i]; ctx.beginPath(); ctx.fillStyle="green"; ctx.fillRect(30,30,50,50); ctx.fill(); document.write("</div>"); }
紅與綠
紅與藍
具體效果你也能夠看這裏 —— canvas圖形組合模式
裏面的代碼我故意把canvas的代碼留在上面,方便大家查看,不知道你看到這些參數有什麼感想,個人第一感受就是有些熟悉比clip好用,也讓我第一時間想到了這一個效果:
ctx.fillStyle="red"; ctx.arc(150,150,100,0,360*Math.PI/180,false); ctx.fill(); ctx.globalCompositeOperation="xor"; ctx.beginPath(); ctx.arc(150,150,80,0,360*Math.PI/180,false); ctx.fill();
若是配合前面的扇形方法,很容易作一個圓形進度條什麼的,固然,還有不少屬性能夠有大的做用,好比說裁切一個圖形,發揮的發達的大腦吧,這裏我就不演示了
三、setLineDash
setLineDash(arr) 在畫布上畫一條虛線
參數:arr 表示的是一個數組集合,裏面的參數能夠有多個,這裏面的參數頗有意思,舉個栗子說明:
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10,20]); ctx.stroke();
對比代碼看圖,若是有2個參數,則第一個參數表示虛線的線寬,第二個參數表示虛線的線與線的距離,後面一直循環
若是是3個參數呢?
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10,20,30]); ctx.stroke();
此時會這樣,第一條線長爲10,而後間距爲20,第2條線長爲30,而後間距爲10,第3條線長20,而後間距爲30,處處爲一個循環,後面重複
那麼4個參數就好理解了,
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10,20,30,40]); ctx.stroke();
規律和上面的同樣,只是循環的長度要長一些,更多參數的規則也是這樣的,那麼一個參數是否有效呢
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10]); ctx.stroke();
顯然是有效的,此時線寬爲10,間距爲10,這就是華麗的分割線的作法
它還有一個兄弟用法,這個是設置虛線,那麼就會有一個獲取虛線
getLineDash() 獲取當前虛線的樣式
它沒有參數,它獲得的結果就是設置虛線的線寬數組arr,咱們看一下怎麼用:
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10]); var txt = ctx.getLineDash(); ctx.stroke(); ctx.fillStyle = 'red'; ctx.font = "30px Arial"; ctx.fillText(txt,180,140);
ctx.beginPath(); ctx.moveTo(0,100); ctx.lineTo(400, 100); ctx.setLineDash([10,20]); var txt = ctx.getLineDash(); ctx.stroke(); ctx.fillStyle = 'red'; ctx.font = "30px Arial"; ctx.fillText(txt,180,140);
從這兩組圖能夠看出,當只有一個參數數,會默認爲2個同樣的參數
四、isPointInPath
isPointInPath(x,y) 指定點是否在路徑區域中,若是在則返回true,不在則返回false
參數: x,y表示指定的座標點
舉個栗子:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.fillStyle = 'red'; ctx.rect(50,50,100,100); ctx.fill(); canvas.onclick = function(ev){ var ev = ev || event; ctx.clearRect(200,0,200,200); var l = ev.clientX - canvas.offsetLeft; var t = ev.clientY - canvas.offsetTop; if(ctx.isPointInPath(l,t)){ ctx.font = "40px Arial"; ctx.fillText((l+','+t),200,120); } }
看看這個gif圖,當點擊紅色區域時,我將座標打印出來,若是點擊的地方不在紅色區域,則不顯示座標,具體效果看這裏 —— canvas判斷是否在路徑區域
這裏有一點須要注意,就是在繪製矩形時,不能用fillRect或strokeRect,爲何呢?由於這裏判斷是是否在指定的路徑中,而fillRect或strokeRect此時已經不是路徑了,而是變成了填充過的圖形,因此這裏必須先用Rect()定義一下路徑,再填充,這樣才能回去到指定圖形的路徑,此點須知!
還有一個方法:
isPointInStroke(x,y) 指定點是否在路徑中,若是在則返回true,不在則返回false
此方法跟上面的方法很類似,不一樣點在於,isPointInPath是在一個區域中,不論是用fill仍是stroke,可是isPointInStroke只能用stroke填充,且指定的區域是在線框上,看下面的例子:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.strokeStyle = 'red'; ctx.lineWidth = 5; ctx.rect(50,50,100,100); ctx.stroke(); canvas.onclick = function(ev){ var ev = ev || event; ctx.clearRect(200,0,200,200); var l = ev.clientX - canvas.offsetLeft; var t = ev.clientY - canvas.offsetTop; if(ctx.isPointInStroke(l,t)){ ctx.font = "40px Arial"; ctx.fillText((l+','+t),200,120); } }
從這個gif中能夠看出端倪來,只有點到線框纔會觸發,具體效果看這裏 —— canvas 判斷是否在線框中
這2個方法的基本用法就是這樣,可是會有一個問題,就是目前只有一個圖形在上面,若是有2個圖形在上面,並且分別的方法不同,好比說,一個是區域路徑,一個是線框路徑,分別點擊他們,彈出不一樣的值,咱們看行不行:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.strokeStyle = 'red'; ctx.lineWidth = 5; ctx.rect(50,50,100,100); ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.fillStyle = 'green'; ctx.rect(200,50,100,100); ctx.fill(); ctx.closePath(); canvas.onclick = function(ev){ var ev = ev || event; var l = ev.clientX - canvas.offsetLeft; var t = ev.clientY - canvas.offsetTop; if(ctx.isPointInStroke(l,t)){ console.log('線框路徑'); } } canvas.onclick = function(ev){ var ev = ev || event; var l = ev.clientX - canvas.offsetLeft; var t = ev.clientY - canvas.offsetTop; if(ctx.isPointInPath(l,t)){ console.log('區域路徑'); } }
看看console裏面的提示,當點擊區域路徑的時候,觸發了操做,可是點擊線框路徑時,不管我怎麼點擊,都無濟於事,這是爲何呢?把2圖形的執行順序顛倒一下,發現效果也相反了,說明誰最後繪製就執行誰,其實這也是能夠理解的,由於此時的ctx指的是當前的路徑,它不能分當前路徑一,路徑二什麼的,若是要實現多個圖形執行不一樣的事件,又改如何作呢?因爲實現方法有點複雜,就在這裏留一個思考題?大家先思考一下,該怎麼弄?我會到後期單獨寫一篇文章,專門來講這個的解決方案,供你們參考!
恩,處處全部該講的canvas API就所有講完了,看了這一系列的文章,不知道你是否對canvas有了那麼一點點的感受,是否canvas已經不那麼神祕了,若是你嘴上不說,內心以爲,恩,好像有點感受了,那個人目的就達到了,要是你還能寫一些效果,那恭喜你,距離大神你有近了一步,若是有時間,有能力,我但願能多寫一下有點深度的canvas實例給你們參考,希望能對你們有幫助!
就這樣吧,感謝你們的關注,謝謝!