【问题标题】:js canvas create pattern repeat issuesjs画布创建模式重复问题
【发布时间】:2022-09-26 13:28:57
【问题描述】:

目前将其绘制到画布上:

我想使用仅在红色矩形所在的 Y 轴上重复的纹理。

但是,在绘制纹理时,如果指定了repeat-y,则不会显示任何内容。但是,当重复值为 repeat 时,它可以工作。

ctx.fillStyle = ctx.createPattern(assets.grassRightTexture, \'repeat-y\');
ctx.fillRect(dimensions.left + dimensions.width, dimensions.top, 5, dimensions.height);

assets.grassRightTexture 是一个预加载的 img 元素,具有 4px x 32px sprite。

不确定我是否做错了什么,但在阅读 moz canvas 文档时我没有注意到任何事情。

谢谢你。

    标签: html5-canvas


    【解决方案1】:

    CanvasPattern 对象始终与上下文的当前变换矩阵 (CTM) 相关,而不是与您希望绘制它的形状相关。

    因此,在这里,由于您确实从将其 width 设置为 4px 的 <img> 元素创建了模式,因此您的 CanvasPattern 实例将仅覆盖从坐标 (0, -∞) 到 (4, ∞) 的矩形.
    由于您绘制的矩形没有覆盖该区域,因此您正在填充透明像素。

    const canvas = document.querySelector("canvas");
    const ctx = canvas.getContext("2d");
    // prepare the CanvasPattern
    canvas.width = 4;
    canvas.height = 32;
    ctx.fillStyle = "red";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    const pattern = ctx.createPattern(canvas, "repeat-y");
    // try to use the pattern
    canvas.width = 300;
    canvas.height = 150;
    ctx.fillStyle = pattern;
    ctx.fillRect(24, 50, 50, 50); // doesn't draw anything
    ctx.strokeRect(24, 50, 50, 50); // to show we did draw something
    
    setTimeout(() => {
      ctx.fillRect(0, 75, 50, 50); // doesn't draw anything
      ctx.strokeRect(0, 75, 50, 50); // to show we did draw something
    }, 1000);
    <canvas></canvas>

    为了克服这个问题,您可以通过 setTransform() 方法转换您的 CanvasPattern 对象,

    const canvas = document.querySelector("canvas");
    const ctx = canvas.getContext("2d");
    // prepare the CanvasPattern
    canvas.width = 4;
    canvas.height = 32;
    ctx.fillStyle = "red";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    const pattern = ctx.createPattern(canvas, "repeat-y");
    // try to use the pattern
    canvas.width = 300;
    canvas.height = 150;
    ctx.fillStyle = pattern;
    // we translate the CanvasPattern so that our shape is covered
    // setTransform accepts a DOMMatrixInit dictionnary
    // `e` represents the x-axis translate
    pattern.setTransform({e: 24}); 
    ctx.fillRect(24, 50, 50, 50);
    ctx.strokeRect(24, 50, 50, 50);
    <canvas></canvas>

    或者您可以使用 2 个不同的 CTM 分两步绘制您的上下文,以跟踪形状和绘制形状。

    const canvas = document.querySelector("canvas");
    const ctx = canvas.getContext("2d");
    // prepare the CanvasPattern
    canvas.width = 4;
    canvas.height = 32;
    ctx.fillStyle = "red";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    const pattern = ctx.createPattern(canvas, "repeat-y");
    // try to use the pattern
    canvas.width = 300;
    canvas.height = 150;
    ctx.fillStyle = pattern;
    // we trace at identity CTM
    ctx.rect(24, 50, 50, 50);
    // we move only the fillStyle & strokeStyle
    ctx.translate(24, 0);
    ctx.fill();
    ctx.stroke();
    <canvas></canvas>

    虽然我现在看到 Firefox 中有一个错误,导致第二个选项在那里失败。

    【讨论】:

      猜你喜欢
      • 2011-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-16
      • 2021-08-05
      • 1970-01-01
      • 2019-11-12
      相关资源
      最近更新 更多