js+canvas實(shí)現(xiàn)繪制正方形并插入文字效果(居中顯示)
一、實(shí)現(xiàn)效果
二、實(shí)現(xiàn)思路
1.先根據(jù)傳入的文本內(nèi)容,計(jì)算出文本的寬度。
2.文本寬度+左右間距,得到正方形的邊長、畫布寬度。
3.在(0,0)坐標(biāo)處,繪制正方形。
4.計(jì)算文本居中的起始坐標(biāo),填充文本。
三、代碼實(shí)現(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 // 字號(hào) * @param {String} fontFace // 字體 * @param {String} text // 文本 */ drawSquare(fonSize, fontFace, text) { var canvas = document.getElementById('canvas') var ctx = canvas.getContext('2d') // 1.計(jì)算文本寬度 let txtWidth = this.getFontWidth(fonSize, fontFace, ctx, text) // 2.設(shè)置畫布寬度 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 // 字號(hào) * @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.設(shè)置文本對齊方式 ctx.textBaseline = 'middle' ctx.textAlign = 'center' // 2.設(shè)置起始坐標(biāo) 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個(gè)字符寬度 xL += s ctx.font = fonSize + 'px ' + fontFace ctx.fillText(text[i], xL, yL) } } } } </script>
四、代碼解析
- canvas語法全解析:HTML Canvas 參考手冊
getContext()
:Document.getElementById() 方法獲取 HTML 元素的引用。接著,HTMLCanvasElement.getContext() 方法獲取這個(gè)元素的 context——圖像稍后將在此被渲染。measureText()
:返回包含指定文本寬度的對象textBaseline
:設(shè)置或返回在繪制文本時(shí)使用的當(dāng)前文本基線textAlign
: 設(shè)置或返回文本內(nèi)容的當(dāng)前對齊方式font
:設(shè)置或返回文本內(nèi)容的當(dāng)前字體屬性strokeRect()
:繪制矩形(無填充)
五、問題
- 問題:文本顯示不居中;文本顯示疊在一起;具體可見下圖。
- 原因:好像是通過
measureText
測量出的文本寬度和實(shí)際渲染有差異導(dǎo)致的,但是沒有找到解決辦法。如果有解決方法可以在評論區(qū)留言,謝謝。 - 效果圖:
六、改進(jìn)后的代碼
1.效果圖
2.思路
1)去掉 textAlign='center'
2)使用 measureText
方法返回的 textMetrics
對象的 actualBoundingBoxLeft
+ actualBoundingBoxRight
屬性來計(jì)算文字的寬度。這兩個(gè)屬性表示文字的最左邊和最右邊界,可以更準(zhǔn)備地計(jì)算文字的寬度。
3)填充文字時(shí),字符坐標(biāo)應(yīng)該是加上前一字符寬度,代碼中加的是當(dāng)前字符寬度。改進(jìn)后代碼已修改。
3.代碼實(shí)現(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 // 字號(hào) * @param {String} fontFace // 字體 * @param {String} text // 文本 */ drawSquare(fonSize, fontFace, text) { var canvas = document.getElementById('canvas') var ctx = canvas.getContext('2d') // 1.計(jì)算文本寬度 let txtWidth = this.getFontWidth(fonSize, fontFace, ctx, text) // 2.設(shè)置畫布寬度 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 // 字號(hào) * @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.設(shè)置文本對齊方式 ctx.textBaseline = 'middle' // 2.設(shè)置起始坐標(biāo) 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 // 前一個(gè)字符寬度 } } } } </script>
總結(jié)
到此這篇關(guān)于js+canvas實(shí)現(xiàn)繪制正方形并插入文字效果的文章就介紹到這了,更多相關(guān)js canvas繪制正方形插入文字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)獲取dom中class的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)獲取dom中class的方法,涉及javascript操作dom節(jié)點(diǎn)的使用技巧,需要的朋友可以參考下2015-02-02uniapp基礎(chǔ)知識(shí)點(diǎn)掌握以及面試題整理
uni-app是一個(gè)使用vue.js開發(fā)所有前端應(yīng)用的框架,開發(fā)者編寫一套代碼,下面這篇文章主要給大家介紹了關(guān)于uniapp基礎(chǔ)知識(shí)點(diǎn)掌握以及面試題整理的相關(guān)資料,需要的朋友可以參考下2023-02-02js報(bào)錯(cuò) Object doesn''t support this property or method的原因分析
運(yùn)行js是出現(xiàn)Object doesn't support this property or method 錯(cuò)誤的可能原因分析。2011-03-03js實(shí)現(xiàn)鼠標(biāo)拖動(dòng)功能
本文主要介紹了js實(shí)現(xiàn)鼠標(biāo)拖動(dòng)功能的實(shí)例代碼。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-03-03javascript innerHTML、outerHTML、innerText、outerText的區(qū)別
這篇文章主要介紹了javascript innerHTML、outerHTML、innerText、outerText的區(qū)別,本文講解了它們的功能、使用實(shí)例、和不同之處,需要的朋友可以參考下2008-11-11inputSuggest文本框輸入時(shí)提示、自動(dòng)完成效果(郵箱輸入自動(dòng)補(bǔ)全插件)
inputSuggest在文本框輸入字符時(shí)提示,類似Windows的“自動(dòng)完成”功能,當(dāng)在文本框輸入字符時(shí),與此相關(guān)的內(nèi)容會(huì)顯示在文本框的下邊,你可隨時(shí)使用鍵盤或鼠標(biāo)點(diǎn)選那些提示,你就不用輸入了2012-05-05javascript實(shí)現(xiàn)全局匹配并替換的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)全局匹配并替換的方法的總結(jié),十分的簡單實(shí)用,有需要的小伙伴可以參考下。2015-04-04