如何使用fabric.js画布库在画布上的矩形内部书写文本

问题描述 投票:-1回答:3

是否可以在HTML5画布上的创建矩形上写文本?并在移动矩形时也移动文本。

javascript canvas html5-canvas
3个回答
1
投票

避免在动画画布上分层HTML

[现有答案都建议您使用HTML并将文本添加到画布上。

这可能在代码方面更容易,但是要警告,即使仅更改画布上的单个像素,或者在画布上有一个像素,包含动画或更改内容的画布上的文本也需要呈现(合成)覆盖的文本。在页面上重排。

在画布上具有多个项目并更改这些项目中的任何一项都可以在某些编码样式下强制将所有项目与底层帆布元素重新组合。

如果定期(或实时)更改内容以避免不必要的页面内容合成,请始终使用requestAnimationFrame。>

Box文本并发症?

由于您没有提供有关文本,大小,框数的上下文,如果要对其进行动画处理(实时或次实时),是否需要进行任何转换,是否使用了渐变,图案,滤镜,复合操作或阴影。所有这些都需要使用不同的技术才能在质量和性能方面获得最佳结果。

简单框文字

最基本。一个文本框居中的文本框可以通过简单的功能完成。

所有参数均具有默认值,您只需要传递一个对象即可设置要更改的参数。

const myTextBox = {text: "Hi World!!", x: 100, y: 20, background: "#08F8"};
boxText(myTextBox);

function boxText({
        c = ctx, 
        text, x, y, 
        font = "arial", 
        size = 32, 
        padding = 4, 
        color = "#FFF", 
        boxStyle = "#000", 
        background = "", 
        lineWidth = 2
    }) {    
    c.font = size + "px " + font;
    c.textAlign = "center";
    c.textBaseline = "middle";
    const width = c.measureText(text).width;
    if (background) {
        c.fillStyle = background;
        c.fillRect(x, y, width + padding * 2, size + padding * 2);
    }
    if (boxStyle) {
        c.strokeStyle = boxStyle;
        c.lineWidth = lineWidth;
        c.strokeRect(
            x - lineWidth / 2, y - lineWidth / 2,
            width + padding * 2 + lineWidth, size + padding * 2 + lineWidth
        );
    }
    c.fillStyle = color;
    c.fillText(text, x + width / 2 +  padding, y + padding + size / 2 + size / 16);
}

请注意,在这段代码中我将文本向下移动了一点,您可能不想这样做,所以只需将最后一行更改为c.fillText(text, x + width / 2 + padding, y + padding + size / 2);

演示

在动画示例中使用上述功能。

requestAnimationFrame(renderLoop);
const ctx = canvas.getContext("2d");

const textA = {text: "Hi World!!", x: 100, y: 20, background: "#08F8"};
const textB = {text: "Example 2", x: 100, y: 80, size: 26, color: "black", background: "#F808"};

function renderLoop(time) {
   ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
   textA.x = Math.sin(time / 2500) * 150 + 160;
   textB.x = Math.cos(time / 2500) * 150 + 160;
   textB.text = "Time: " + (time / 1000).toFixed(3);
   boxText(textA);
   boxText(textB);
   requestAnimationFrame(renderLoop);
}


function boxText({
        c = ctx, text, x, y, 
        font = "arial", size = 32, color = "#FFF",
        padding = 4, background = "", 
        boxStyle = "#000", lineWidth = 2
    }) {    
    c.font = size + "px " + font;
    c.textAlign = "center";
    c.textBaseline = "middle";
    const width = c.measureText(text).width;
    if (background) {
        c.fillStyle = background;
        c.fillRect(x, y, width + padding * 2, size + padding * 2);
    }
    if (boxStyle) {
        c.strokeStyle = boxStyle;
        c.lineWidth = lineWidth;
        c.strokeRect(
            x - lineWidth / 2, y - lineWidth / 2,
            width + padding * 2 + lineWidth, size + padding * 2 + lineWidth
        );
    }
    c.fillStyle = color;
    c.fillText(text, x + width / 2 +  padding, y + padding + size / 2 + size / 16);
}
<canvas id = "canvas" width=500 height=150></canvas>

0
投票

是,有两种方法:


0
投票

您可以创建一个名为TextBox的类,该类使用.fillText()和一个框.fillRect()执行将文本分组的逻辑。该类跟踪要绘制的文本以及背景颜色和文本本身的颜色。然后,每次绘制都会为您绘制框和文本。然后,您可以通过更改框xy属性来移动框。

© www.soinside.com 2019 - 2024. All rights reserved.