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 // 字號
* @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 // 字號
* @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 // 字號
* @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 // 字號
* @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)文章
Bootstrap基本插件學(xué)習(xí)筆記之輪播幻燈片(23)
這篇文章主要為大家詳細(xì)介紹了Bootstrap基本插件學(xué)習(xí)筆記之輪播幻燈片的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
JavaScript前端靜態(tài)資源加載失敗的多級解決方案
這篇文章主要為大家詳細(xì)介紹了JavaScript前端靜態(tài)資源加載失敗的多級解決方案,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2025-07-07
網(wǎng)頁運(yùn)行時(shí)提示對象不支持abigimage屬性或方法
網(wǎng)頁中用了一個(gè)js插件,js文件引用的沒有錯(cuò)但是運(yùn)行時(shí)ie的調(diào)試工具報(bào)了一個(gè)錯(cuò),提示對象不支持abigimage屬性或方法2014-08-08
js通過location.search來獲取頁面?zhèn)鱽淼膮?shù)
js獲取通過window.location.search來獲取頁面?zhèn)鱽淼膮?shù),經(jīng)測試可用,大家可以學(xué)習(xí)下2014-09-09

