js+canvas實現(xiàn)繪制正方形并插入文字效果(居中顯示)
一、實現(xiàn)效果
二、實現(xiàn)思路
1.先根據(jù)傳入的文本內(nèi)容,計算出文本的寬度。
2.文本寬度+左右間距,得到正方形的邊長、畫布寬度。
3.在(0,0)坐標處,繪制正方形。
4.計算文本居中的起始坐標,填充文本。
三、代碼實現(xiàn)
<template> <div> <canvas id="canvas" style="margin:10px;></canvas> </div> </template> <script> export default { mounted() { this.drawSquare(20, 'Microsoft YaHei', '我是居中的文字..') }, methods: { /** * 繪制正方形并添加文本 * @param {Number} fonSize // 字號 * @param {String} fontFace // 字體 * @param {String} text // 文本 */ drawSquare(fonSize, fontFace, text) { var canvas = document.getElementById('canvas') var ctx = canvas.getContext('2d') // 1.計算文本寬度 let txtWidth = this.getFontWidth(fonSize, fontFace, ctx, text) // 2.設置畫布寬度 let ctxWidth = txtWidth + 20 canvas.width = ctxWidth canvas.height = ctxWidth console.log(txtWidth,'txtWidth'); // 3.繪制正方形 ctx.strokeRect(0, 0, txtWidth + 10, txtWidth + 10) // 4.填充文字 this.fillTextCenter( fonSize, fontFace, txtWidth, ctx, text, txtWidth + 10 ) }, /** * 獲取文本寬度 * @param {Object} ctx // CanvasRenderingContext2D * @param {String} text // 文本內(nèi)容 */ getFontWidth(fonSize, fontFace, ctx, text) { ctx.font = fonSize + 'px ' + fontFace let txtWidth = 0 for (let i = 0; i < text.length; i++) { txtWidth += ctx.measureText(text[i]).width } return txtWidth }, /** * 在圖形中心位置添加文本 * @param {Number} fonSize // 字號 * @param {String} fontFace // 字體 * @param {Number} txtWidth // 文本寬度 * @param {Object} ctx // CanvasRenderingContext2D * @param {String} text // 文本 * @param {Number} width // 畫布的寬度 * @param {Number} height // 畫布的高度 */ fillTextCenter( fonSize, fontFace, txtWidth, ctx, text, width ) { // 1.設置文本對齊方式 ctx.textBaseline = 'middle' ctx.textAlign = 'center' // 2.設置起始坐標 let s = 0 let xL = (width - txtWidth-2) / 2 + s let yL = width / 2 // 3.繪制文本 for (let i = 0; i < text.length; i++) { s = ctx.measureText(text[i]).width // 第i個字符寬度 xL += s ctx.font = fonSize + 'px ' + fontFace ctx.fillText(text[i], xL, yL) } } } } </script>
四、代碼解析
- canvas語法全解析:HTML Canvas 參考手冊
getContext()
:Document.getElementById() 方法獲取 HTML 元素的引用。接著,HTMLCanvasElement.getContext() 方法獲取這個元素的 context——圖像稍后將在此被渲染。measureText()
:返回包含指定文本寬度的對象textBaseline
:設置或返回在繪制文本時使用的當前文本基線textAlign
: 設置或返回文本內(nèi)容的當前對齊方式font
:設置或返回文本內(nèi)容的當前字體屬性strokeRect()
:繪制矩形(無填充)
五、問題
- 問題:文本顯示不居中;文本顯示疊在一起;具體可見下圖。
- 原因:好像是通過
measureText
測量出的文本寬度和實際渲染有差異導致的,但是沒有找到解決辦法。如果有解決方法可以在評論區(qū)留言,謝謝。 - 效果圖:
六、改進后的代碼
1.效果圖
2.思路
1)去掉 textAlign='center'
2)使用 measureText
方法返回的 textMetrics
對象的 actualBoundingBoxLeft
+ actualBoundingBoxRight
屬性來計算文字的寬度。這兩個屬性表示文字的最左邊和最右邊界,可以更準備地計算文字的寬度。
3)填充文字時,字符坐標應該是加上前一字符寬度,代碼中加的是當前字符寬度。改進后代碼已修改。
3.代碼實現(xiàn)
<template> <div> <canvas id="canvas" style="margin:10px;"></canvas> </div> </template> <script> export default { mounted() { this.drawSquare(20, 'Microsoft YaHei', '我是居中的文字..') }, methods: { /** * 繪制正方形并添加文本 * @param {Number} fonSize // 字號 * @param {String} fontFace // 字體 * @param {String} text // 文本 */ drawSquare(fonSize, fontFace, text) { var canvas = document.getElementById('canvas') var ctx = canvas.getContext('2d') // 1.計算文本寬度 let txtWidth = this.getFontWidth(fonSize, fontFace, ctx, text) // 2.設置畫布寬度 let ctxWidth = txtWidth + 20 canvas.width = ctxWidth canvas.height = ctxWidth // 3.繪制正方形 ctx.strokeRect(0, 0, txtWidth + 10, txtWidth + 10) // 4.填充文字 this.fillTextCenter( fonSize, fontFace, txtWidth, ctx, text, txtWidth + 10 ) }, /** * 獲取文本寬度 * @param {Object} ctx // CanvasRenderingContext2D * @param {String} text // 文本內(nèi)容 */ getFontWidth(fonSize, fontFace, ctx, text) { ctx.font = fonSize + 'px ' + fontFace let txtWidth = 0 for (let i = 0; i < text.length; i++) { txtWidth += (ctx.measureText(text[i]).actualBoundingBoxLeft + ctx.measureText(text[i]).actualBoundingBoxRight) } return txtWidth }, /** * 在圖形中心位置添加文本 * @param {Number} fonSize // 字號 * @param {String} fontFace // 字體 * @param {Number} txtWidth // 文本寬度 * @param {Object} ctx // CanvasRenderingContext2D * @param {String} text // 文本 * @param {Number} width // 畫布的寬度 * @param {Number} height // 畫布的高度 */ fillTextCenter( fonSize, fontFace, txtWidth, ctx, text, width ) { // 1.設置文本對齊方式 ctx.textBaseline = 'middle' // 2.設置起始坐標 let s = 0 let xL = (width - txtWidth - 2) / 2 + s let yL = width / 2 // 3.繪制文本 for (let i = 0; i < text.length; i++) { xL += s ctx.font = fonSize + 'px ' + fontFace ctx.font = fonSize + 'px ' + fontFace ctx.fillText(text[i], xL, yL) s = ctx.measureText(text[i]).actualBoundingBoxLeft + ctx.measureText(text[i]).actualBoundingBoxRight // 前一個字符寬度 } } } } </script>
總結(jié)
到此這篇關(guān)于js+canvas實現(xiàn)繪制正方形并插入文字效果的文章就介紹到這了,更多相關(guān)js canvas繪制正方形插入文字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實現(xiàn)獲取dom中class的方法
這篇文章主要介紹了JavaScript實現(xiàn)獲取dom中class的方法,涉及javascript操作dom節(jié)點的使用技巧,需要的朋友可以參考下2015-02-02js報錯 Object doesn''t support this property or method的原因分析
運行js是出現(xiàn)Object doesn't support this property or method 錯誤的可能原因分析。2011-03-03javascript innerHTML、outerHTML、innerText、outerText的區(qū)別
這篇文章主要介紹了javascript innerHTML、outerHTML、innerText、outerText的區(qū)別,本文講解了它們的功能、使用實例、和不同之處,需要的朋友可以參考下2008-11-11inputSuggest文本框輸入時提示、自動完成效果(郵箱輸入自動補全插件)
inputSuggest在文本框輸入字符時提示,類似Windows的“自動完成”功能,當在文本框輸入字符時,與此相關(guān)的內(nèi)容會顯示在文本框的下邊,你可隨時使用鍵盤或鼠標點選那些提示,你就不用輸入了2012-05-05