前面的課程我們學習的都是如何在Canvas中繪製圖形,但很多時候,除了繪製圖形之外還有很多情景要同文本打交道。不過在Canvas中到目前為止只提供了一些必備的基本功能,例如文本的描邊與填充,向Canvas之中放置文本,以及用像素為單位來計算任意字符串的寬度等。接下來的內容,我們就來了解在Canvas中怎麼繪製文本以及一些基本的操作。
Canvas的繪圖環境對象提供了兩種方法來渲染文本:
fillText(text, x, y, [maxWidth]):繪製填充文本
strokeText(text, x, y, [maxWidth]):繪製描邊文本
在Canvas中同樣提供了類似CSS的一些font屬性,用來修飾在Canvas中繪製的文本,比如:
font = value:用來修飾繪製文本的樣式,類似於CSS中的font
textAlign = value:文本對齊設置
textBaseline = value: 文本基線對齊設置
direction = value: 文本方向的設置
除此之外,很多時候我們還需要對已繪製文本寬度的度量,在Canvas中提供了一個measureText(text)方法,該方法所返回的對象中,包含一個名為width的屬性,它的值代表你傳遞給該方法的文本所佔據的寬度。
在接下來的內容,我們將詳細的針對上述內容做相關的闡述。
文本的填充和描邊在Canvas中的CanvasRenderingContext2D對象提供了兩個方法來繪製文本:fillText()和strokeText()方法。先來看fillText()方法。
fillText()方法用來繪製填充文本,其語法如下:
fillText()方法接受四個參數:
來看個簡單的示例:
效果如下:
可以點擊這裡在CodePen上查看Demo效果。
在繪製文本時,同樣可以使用fillStyle屬性來設置填充文本的顏色。另外,上面的示例,我們只用了其中三個參數,並沒有使用maxWidth參數。在fillText()方法中,這個參數是可選參數。這個參數的主要功能是用來控制繪製文本的最大寬度。如果繪製的文本內容超過了maxWidth的寬度的時候,將會壓縮文本,讓繪製的文本寬度和maxWidth值一樣。
來個小示例:
效果如下:
可以點擊這裡在CodePen上查看Demo效果。
上示中,繪製的第一個文本,設置了maxWidth,而第二個文本並未設置maxWidth。通過ctx.measureText(text).width)可以得出未設置maxWidth的值是474,也就是說文本Hello! W3cplus.com!從474壓縮到了200。
上面介紹的是fillText()繪製填充文本,在Canvas中還可以通過strokeText()方法來繪製描邊文本。該方法具有的參數和使用方法與fillText()一樣,只是最終在Canvas中渲染的效果不一樣。比如將上示中的fillText()換成strokeText(),同時將fillStyle換成strokeStyle:
最終效果如下:
可以點擊這裡在CodePen上查看Demo效果。
在實際中,我們可以同時使用fillText()和strokeText()方法繪製一個具有填充的邊框的文本,這也是我們最常見的描邊文本,但它們的起始位置應該在同一個點:
最終效果如下:
可以點擊這裡在CodePen上查看Demo效果。
為了便於更靈活的使用fillText()和strokeText()繪製文本,可以將其封裝成一個函數,比如drawText():
使用的時候,像下面這樣調用即可:
設置文本樣式在上面的示例中,我們看到了代碼中有ctx.font屬性的使用。其實在Canvas中,可以通過繪圖環境對象的font屬性,來設置繪製在Canvas之中的文本所採用的字型。該屬性是一個CSS3格式的字型字符串,它和CSS font屬性相同的語法,默認的字型是10px sans-serif。
Canvas中font屬性的各個分量如下表所示:
通過CSS3與Canvas來指定字型屬性時的區別:繪製環境對象的font屬性也支持CSS3格式的字型語法,除了樣式語法所特有的屬性,例如inherit或initial等。如果你不巧剛好用到了inherit或initial的話,那麼瀏覽器在執行到那行代碼時會悄然地失敗,並不拋出任何異常,同時也不會將該值設定給font屬性。通過Canvas來設置字型屬性與通過CSS3來設置相比,還有一個區別:在Canvas中設置line-height屬性時,瀏覽器將忽略其值,因為規範要求瀏覽器必須將該值設置為normal。
文本定位(對齊方式)這裡所說的文本定位,其實指的是對齊方式,在CSS中我們可以使用text-align設置文本水平對齊方式,vertical-align設置文本垂直方向的對齊方式。在Canvas中也有對應的屬性。
通過前面的知識我們得知,在Canvas中使用fillText()或fillText()繪製文本時,需要指定所繪文本的x與y坐標,然而,瀏覽器具體會將文本繪製在何處(文本定位),則要看textAlign與textBaseline這兩個繪圖環境對象的屬性。
textAlignCanvasRenderingContext2D.textAlign是Canvas中繪製文本時文本的對齊方式的屬性。其對齊是基於fillText()或strokeText()方法的x值。textAlign屬性有點類似於CSS中的text-align,用來設置文本水平對齊方式。其主要包括:
默認值是start。在Canvas中使用textAlign時同樣會受direction屬性值的影響。當Canvas的direction的值為ltr時,也就是說瀏覽器是按照由左至右的方向來顯示文本時,textAlign的left的效果與start相同,而right的效果則與end相同。同理,如果direction的值為rtl時,也就是說瀏覽器是從右至左來顯示文本的,那麼textAlign的right的效果則與start一致,而left則與end一致。下例演示了textAlign每個值在瀏覽器中渲染的效果(其中direction的值為默認值ltr):
效果如下:
可以點擊這裡在CodePen上查看Demo效果。
示例中繪製的文本,其起始點是畫布的中心位置w / 2,也就是上圖中的黑色豎線。left則讓文本左側在x點處(在豎線右側),right則文本右側在x點處(在豎線左側),center則文本中間點在x點處(在豎線中間)。start和left等同,end和right等同。
這裡的textAlign='center'比較特殊。textAlign的值為center時候文本的居中是基於你在fillText的時候所給的x的值,也就是說文本一半在x的左邊,一半在x的右邊(上圖展示看得更清楚些)。所以,如果你想讓文本在整個Canvas居中,就需要將fillText的x值設置成canvas的寬度的一半。
textBaselineCanvasRenderingContext2D.textBaseline是Canvas中描述繪製文本時,當前文本基線的屬性,類似CSS中的vertical-align屬性,在介紹textBaseline屬性之前,先來下圖,下圖展示了textBaseline屬性支持的不同的基線情況:
上圖是不是非常熟悉呀,那我們回到Canvas的textBaseline屬性的使用:
textBaseline的默認值是alphabetic,該值用於繪製由基於拉丁字母的語言所組成的字符串,ideographic值則用於繪製日文或中文字符串,hanging值用於繪製各種印度語字符串,top、bottom和middle這三個值與特定的語言不相關,它們代表文本周圍的邊界框之內的某個位置,這個邊界框也叫做「字符方框」。
同樣來看一個示例,用效果來幫助我們理解textBaseline各個值的效果。
效果如下:
可以點擊這裡在CodePen上查看Demo效果。
文本度量只要你做的事情與文本有關,你就得設法獲取某個字符串的像素寬度和高度。在Canvas中提供了measureText()方法,這個方法返回一個TextMetrics對象,這個對象中包含了一個名為width的屬性,這個屬性就是字符串的寬度。
在使用measureText()方法時,常見的錯誤就是在調用完該方法之後,才去設置字型。請注意:measureText()方法是根據當前的字型來計算字符串寬度的,因此,如果你在調用measureText()方法之後才去改變字型,那麼該方法所返回的寬度並不能反映出以那種字型來度量的實際文本寬度。
上述的內容就是有關於Canvas中繪製文本所涉及到的一些方法和屬性。接下來我們來看兩個簡單的示例。
示例前面的示例,我們看到的是通過fillText()或strokeText()方法繪製填充文本或描邊文本,可以說是最簡單的繪製文本效果,但實際當中,我們要的效果不僅僅是這些普通的效果。比如我們需要一個圓形的文本效果,3D的文本效果等。那咱們就藉助以前所學的一些基礎知識來實現這兩種效果。
環形文本直接上代碼,這裡封裝了一個簡單的函數,比如drawCircleText(),並且根據繪製弧形文本所需要的參數傳給這個函數,具體代碼如下:
在使用的時候,只需要調用這個函數,並傳入相應的值:
效果如下:
3D文本效果3D文本效果在CSS中通過text-shadow來實現,具體怎麼實現這裡就不多說了,必竟我們這裡是聊Canvas。其實在Canvas中實現的原理也有點類似,將會使用到shadowBluer、shadowColor等陰影屬性(這個我們前面沒有接觸過,但後面我們也會深入學習),和前面的圓形文本一樣,同樣將繪製3D文本的效果封裝成一個簡單的函數,比如draw3DText(),具體的代碼如下:
調用也非常的簡單:
得到的效果如下:
這個示例通過將fillText()或者strokeText()的(x, y)設置為canvas寬度和高度的一半(w / 2, h / 2)再配合ctx.textAlign = 'center'和ctx.textBaseline= 'middle'可以實現所繪文本在畫布的中間,也就是實現了我們常說的水平垂直居中的效果。
另外,把上面兩外效果結合起來,就可以實現圓形的3D文本效果,要是再添加一點動畫功能,效果就不一樣了:
總結這篇文章我們主要介紹了在Canvas中繪製文本的一些基礎知識,在Canvas中可以通過ctx.fillText()繪製填充文本,ctx.strokeText()可以繪製描邊文本,另外通過ctx.textAlign和ctx.textBaseline設置所繪製文本的位置,並且使用ctx.measureText('text').width可以得到所繪製文本text的寬度值,雖然這個值並不精確,但在Canvas中有方法可以解決,至於怎麼解決我們後續的內容將會介紹。
雖然這些功能是繪製文本的基本功能,但結合Canvas其他的功能,我們可以繪製出很多不同的文本效果,至於繪製出什麼樣的效果,則需要大家去思考,因為創意是自己的,有了創意,然後結合自己所掌握的Canvas知識,能做的事情就更多了。如果你有更好的創意,希望在下面的評論中與我們一起分享。
文章涉及到圖片和代碼,如果展示不全給您帶來不好的閱讀體驗,歡迎點擊文章底部的 閱讀全文。如果您覺得小站的內容對您的工作或學習有所幫助,歡迎關注此公眾號。
W3cplus.com
————————————
記述前端那些事,引領web前沿
長按二維碼,關注W3cplus
▼