Canvas學習:繪製文本

2021-02-15 W3cplus

前面的課程我們學習的都是如何在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這兩個繪圖環境對象的屬性。

textAlign

CanvasRenderingContext2D.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的寬度的一半。

textBaseline

CanvasRenderingContext2D.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

相關焦點

  • canvas文本繪製自動換行、字間距、豎排等實現
    yy是文本繪製的垂直參考點坐標。隨著CanvasRenderingContext2D.textBaseline的設置不同,y的坐標位置也不同。支持多種基線類型(CSS中也有對應概念),MDN上有一張圖可以很好地表示文本基線和文本垂直位置的關係。
  • html中繪製圖形標籤的詳細介紹
    本篇將介紹的是html中<canvas>標籤的用法,感興趣的朋友可以一起研究一下!在html5中,新增了很多實用的標籤,今天為大家介紹的是html5新增標籤<canvas>,<canvas>標籤只是一個容器,對內容並沒有樣式的更改。那它在html中有什麼用,接下來我們就一起來看看吧!
  • 「強烈建議收藏」小程序canvas繪製帶二維碼海報全流程(枚舉踩坑,詳解解決方案)
    ✅② taro-vue 初始化獲取不到canvas上下文怎麼辦,完全繪製不出來圖片?✅小程序canvas遇到的坑③ 關於canvas 寬高以及縮放比問題,繪製的元素變形,畫布的高度真得等於cavans標籤設置的寬高麼?✅④ canvas怎麼繪製疊在一起的兩張圖片,並控制層級?✅⑤ 如何用canvas繪製,多行文本?
  • html5 canvas畫布繪製矩形和圓形
    html5為我們提供了非常有特色的標籤,canvas標籤為我們可以實現在網頁中畫畫提供了便利,接下來我們列舉他的常用操作。新建一個html5的文檔,建立一個canvas畫布,設置長寬,這裡需要特別注意,canvas標籤可以在標籤內設置width,height,也能通過css來設置,但是通過css來設置的標籤,當繪製圖形的時候會變形,所以我們建議直接在標籤內設置。
  • Canvas 教程:如何繪製帶箭頭的曲線
    我們只有兩個點的相對偏移量(offset),思路就是以這兩個點作為對角,創建一個絕對定位的 Canvas,然後在兩點中繪製一條曲線(Curve),最後在終點處繪製箭頭(Arrow)。創建適當的 Canvas 代碼繪製曲線Canvas 中繪製曲線很簡單,API 中已經提供了貝塞爾曲線(Bezier Curve)的繪製方法。
  • H5的新功能,canvas畫布的矩形繪製,看了就會!
    繪製矩形canvas提供了三種方法繪製矩形: ---->繪製一個填充的矩形(填充色默認為黑色) fillRect(x, y, width, height)> ---->繪製一個矩形的邊框(默認邊框為:一像素實心黑色) strokeRect(x, y, width, height) ---->清除指定矩形區域,讓清除部分完全透明。
  • 微信小程序canvas繪製海報並保存本地相冊
    在做微信小程序電商項目中,想要分享一款商品,使用最多並且最簡便的方法就是使用小程序自帶的分享api進行分享,但是分享出去的頁面比較難看;另一種方法就是自己使用小程序canvas繪製分享的海報,這個海報可以保存在相冊裡,而且可以按照自己的需求效果進行頁面繪製。
  • matplotlib如何實現圖形繪製在tkinter的Canvas中?
    matplotlib如何實現圖形繪製在tkinter的Canvas中?今天番茄加速就來分享一下。下面就是最重要的tkinter和matplotlib集成部分,matplotlib提供FigureCanvasTkAgg對象,只需三行代碼,實現圖形繪製在tkinter的Canvas中:canvas_l = FigureCanvasTkAgg(figure_l, frame_l)# 用draw代替canvas_l.draw()canvas_l.get_tk_widget
  • File、Blob、dataURL 和 canvas 的應用與轉換
    它的數據可以按文本或二進位的格式進行讀取,也可以轉換成 ReadableStream 來用於數據操作。(2) Blob 表示的不一定是JavaScript原生格式的數據。File 接口基於Blob,繼承了 blob 的功能並將其擴展使其支持用戶系統上的文件。
  • 用HTML5把Canvas緩衝區內容輸出到屏幕
    幾乎每個遊戲平臺都有不同版本的sokoban,但是我還沒有看到任何使用canvas元素的應用。${PageNumber}  canvas入門  讓我們僅使用單個canvas元素,開始創建我們的HTML5頁面。
  • HTML5新標籤——canvas
    canvas簡介HTML5 標籤用於繪製圖像(通過腳本,通常是 JavaScript)。不過, 元素本身並沒有繪製能力(它僅僅是圖形的容器) - 您必須使用腳本來完成實際的繪圖任務。bold 12px arialtextAlign作用:設置或返回文本內容的當前對齊方式取值:center:文本的中心被放置在指定的位置。
  • 用一天入門 canvas 和 JavaScript
    相對適宜的等級和學習曲線,使我寫下整個過程。HTML canvas 用最簡單的方式,使web 開發者能夠通過JavaScript在網頁上繪製圖形。這樣,HTML 元素變得更加有趣。<canvas> 元素只是個容器,你總是需要使用 JavaScript 來準確繪製圖形。有人可能會說,我們總是可以添加這些點,也可以添加SVG,但這又會多麼有趣?
  • 開發者值得關注的HTML5新特性Canvas
    本文將帶領初學者學習Canvas的入門知識。  走近Canvas 元素標籤  官方對Canvas元素標籤的定義為:Canvas(畫布)可以用來進行繪製圖形,繪製遊戲的圖案或者其他圖形圖案,允許使用腳本動態渲染點陣圖像。簡單來說,Canvas就是允許你在HTML5中,使用Javascript去繪製你喜歡的任何圖形了,包括文字,圖片、線、點、各種形狀等。
  • Canvas學習:繪製箭頭 主標籤
    在這篇文章中主要來聊在Canvas中怎麼繪製箭頭。在Canvas的CanvasRenderingContext2D對象中是沒有提供繪製箭頭的方法,言外之意,在Canvas中要繪製箭頭是需要自己封裝函數來處理。那今天的主題就是來看怎麼封裝繪製箭頭的函數。了解一些基礎知識平常我們常常看到的一些箭頭樣式如下圖所示:在繪製箭頭最關鍵之處就是處理箭頭:
  • 用 Canvas 編織璀璨星空圖
    是不是還蠻酷的呢?本文我們就來一點一點分析怎麼實現它!首先我們要得到那個 canvas 並得到繪製上下文:var canvasEl = document.getElementById('canvas');var ctx = canvasEl.getContext('2d');var mousePos = [0, 0];緊接著我們聲明兩個變量,分別用於存儲
  • Canvas入門實戰之實現一個圖形驗證碼
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫本文主要介紹用canvas實現圖形驗證碼的一些思路以及如何用javascript面向對象的方式更友好的實現canvas的功能,關於canvas的一些基本使用方法和API我整理了一個思維導圖,大家感興趣的可以參考學習
  • HTML5 canvas繪圖基本使用方法
    font:繪製文本的時候css字體globalAlpha:繪製像素時添加的透明度gloablCompositeOperation:合併新的像素點和下面的像素點lineCap:渲染線段的末端lineJoin:渲染頂點lineWidth:邊框的寬度
  • Canvas框架-FabricJS簡介
    一個簡單的canvas demo通過fabric.Canvas獲取到canvas元素,並可以對canvas進行相應的設置,既可以通過獲取已存在的canvas元素,fabric也支持創建canvas元素,同樣也能對其進行相應操作與原生的異同之前有一個需求是點滑鼠左鍵並進行拖動,要實現實時在canvas上進行畫圖於是分別用元生canvas和fabric製作了該功能,接下來我們對比下兩者的異同
  • R導入自建文本繪製詞雲圖
    最近小編和小夥伴們在一起學習如何用R繪製詞雲圖,前面的文章也介紹了詞雲圖的基本繪製方法,包括自定義詞雲圖形狀。但是,之前我們都是使用的內置數據集。那麼,我們能不能用自己建立的文本作為數據集,來繪製詞雲圖呢?答案是肯定的!今天,小編就和大家一起來學習下如何完成自建文本繪製詞雲圖。
  • canvas 入門實戰--邀請卡生成與下載
    canvas的用途非常的廣,特別是html5遊戲以及數據可視化這兩個方面。現在canvas給我的感覺就和css3一樣,可以不用太厲害,但是必須要會基礎的用法。但是以後對canvas的需求,肯定會越來越大。所以canvas很值得學習,而且學好canvas,就是很好的一個加分項。對於這篇文章,我也是以canvas初學者的角度寫的,會有很多改善的地方。