Canvas绘图应用按下Enter后下划线残留问题求助
Canvas绘图应用Enter后下划线残留问题
我正在开发一款Canvas绘图应用,按下Enter后日志显示流程符合预期,但下划线仍残留在画布上(仅颜色变淡)。按预期此时isDrawingText已设为false,下划线本应停止绘制,求问题原因及解决办法。
文本类代码
const Text = class { constructor(ctx, colorPicker, text, coordinates) { this.ctx = ctx, this.colorPicker = colorPicker, this.text = text || "Text...", this.coordinates = coordinates, this.measure = this.ctx.measureText(this.text), this.underline = { x1: undefined, } } draw() { this.ctx.font = `normal 20px Lora` this.ctx.textBaseline = 'alphabetic' this.ctx.fillStyle = "red" this.ctx.textAlign = "left" this.ctx.textBaseline = "bottom" this.ctx.fillText(this.text, this.coordinates.x, this.coordinates.y ) this.ctx.stroke() // 问题根源之一 } update() { this.draw() } drawUnderline() { this.ctx.beginPath() this.ctx.moveTo(this.coordinates.x - this.measure.actualBoundingBoxLeft, this.coordinates.y) this.ctx.lineTo(this.coordinates.x + this.measure.actualBoundingBoxRight, this.coordinates.y) this.ctx.stroke() } } export default Text
动画函数代码
function animate() { requestAnimationFrame(animate) ctx.clearRect(0, 0, innerWidth, innerHeight) if (texts[0]) { console.log("texts 0") texts.forEach(text => { text.update() }) } if (currentText && isDrawingText) { console.log("is drawing text") drawText(ctx, colorPicker, textToPlace, { x: textCoordinates.x, y: textCoordinates.y }) currentText.drawUnderline() } }
画布点击逻辑
const start = (event) => { isDrawingText = true textCoordinates.x = event.offsetX textCoordinates.y = event.offsetY drawText(ctx, colorPicker, textToPlace, { x: textCoordinates.x, y: textCoordinates.y }) }
绘图函数
import Text from '../classes/Text.js' let texts = [] let currentText = null const drawText = (ctx, colorPicker, textToPlace, coordinates) => { let textCoordinates = { x: undefined, y: undefined } if (coordinates.x && coordinates.y) { textCoordinates.x = coordinates.x, textCoordinates.y = coordinates.y } currentText = new Text(ctx, colorPicker.value, textToPlace, textCoordinates) currentText.update(true) } export { texts, drawText, currentText }
回车键逻辑
if (e.key === 'Enter') { texts.push(currentText) isDrawingText = false } else if (e.key === 'Backspace') { textToPlace = textToPlace.substring(0, textToPlace.length - 1) } else if (e.key !== 'Shift' && e.location === 0) { textToPlace = textToPlace + e.key }
问题原因
- Canvas上下文路径残留:
clearRect()仅清除画布像素,不会重置绘图上下文的路径状态。绘制下划线时创建的路径会保留在ctx中,后续绘制会复用该路径。 - 多余的
stroke()调用:Text类的draw()方法末尾的this.ctx.stroke()属于无效调用——fillText不会生成路径,此调用会意外绘制之前残留的下划线路径。 - 样式未隔离:
drawUnderline()未设置专属strokeStyle,后续绘制时使用默认样式,导致下划线呈现“颜色变淡”的异常视觉效果。
解决办法
- 删除
draw()中多余的stroke()
修改Text类的draw方法,移除末尾无意义的stroke()调用:draw() { this.ctx.font = `normal 20px Lora` this.ctx.textBaseline = 'alphabetic' this.ctx.fillStyle = "red" this.ctx.textAlign = "left" this.ctx.textBaseline = "bottom" this.ctx.fillText(this.text, this.coordinates.x, this.coordinates.y ) // 删除此行:this.ctx.stroke() } - 在
draw()开头添加路径重置
每次绘制文本前重置路径,彻底避免残留路径干扰:draw() { this.ctx.beginPath() // 新增:重置当前路径 this.ctx.font = `normal 20px Lora` this.ctx.textBaseline = 'alphabetic' this.ctx.fillStyle = "red" this.ctx.textAlign = "left" this.ctx.textBaseline = "bottom" this.ctx.fillText(this.text, this.coordinates.x, this.coordinates.y ) } - 给下划线设置专属样式
在drawUnderline()中明确指定下划线颜色,避免样式污染:drawUnderline() { this.ctx.beginPath() this.ctx.strokeStyle = "red" // 设置下划线颜色,与文本颜色一致 this.ctx.moveTo(this.coordinates.x - this.measure.actualBoundingBoxLeft, this.coordinates.y) this.ctx.lineTo(this.coordinates.x + this.measure.actualBoundingBoxRight, this.coordinates.y) this.ctx.stroke() }
内容的提问来源于stack exchange,提问作者DuchSuvaa
相关产品推荐
相关产品推荐

