【问题标题】:How to transform the image pattern in JavaScript canvas fillingStyle?如何在 JavaScript 画布填充样式中转换图像模式?
【发布时间】:2017-12-15 13:49:59
【问题描述】:

我目前正在用 JavaScript 开发一个 2D 图形库,现在我坚持处理背景纹理转换问题。

我想将画布上下文 (CanvasRenderingContext2D) 的背景纹理 (属性 fillStyle) 设置为图像 (CanvasPattern)。 将图像分配给fillStyle 很容易。 但唯一的问题是,图像实际上无法平移、缩放或倾斜。

我查了 MDN,上面说有一个原型叫做setTransform()。 使用此 API,您可以通过 SVGMatrix 转换图像,这似乎有点烦人。 您不仅需要创建一个冗余的 <svg> 元素,而且它还是一个实验性 API,并且无法在 Google Chrome 中运行。

使用常规方法是不可能解决的。 有什么“hacky”方法可以做到这一点吗?

【问题讨论】:

  • 您可以通过单独使用变换来独立于路径变换填充,首先创建路径,然后在创建路径后将变换设置为您想要的模式然后填充..例如@ 987654328@

标签: javascript canvas svg transform ecmascript-5


【解决方案1】:

先绘制路径,然后设置变换。路径在填充变换时保持在原来的位置。

该示例在两个框内旋转图案。

const ctx = canvas.getContext('2d');
var pattern;

const img = new Image();
img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
img.onload = () =>  pattern = ctx.createPattern(img, 'repeat');



 requestAnimationFrame(mainLoop);
 function mainLoop(time){
     ctx.setTransform(1,0,0,1,0,0);
     ctx.clearRect(0,0,canvas.width,canvas.height);

     ctx.fillStyle = pattern;

     ctx.beginPath();
     ctx.setTransform(1,0,0,1,0,0);  
     ctx.rect(100,100,200,200); // create the path for rectangle
     ctx.setTransform(1,0,0,1,300,200);  // Set the transform for the pattern
     ctx.rotate(time / 1000);
     ctx.fill();


     ctx.beginPath();
     ctx.setTransform(1,0,0,1,0,0);
     ctx.rect(150,0,100,400); // create the path for the rectangle
     ctx.setTransform(0.2,0,0,0.2,150,200); // Set the transform for the pattern
     ctx.rotate(-time / 1000);
     ctx.fill();

     requestAnimationFrame(mainLoop);
 }
<canvas id="canvas" width="400" height="400" style="border:2px solid black;"></canvas>

【讨论】:

    【解决方案2】:

    在 CanvasRenderingContext2D 上设置变换,而不是在 CanvasPattern 上。这得到了更好的支持,而且您不需要 SVGMatrix 对象。

    生成的绘制区域是转换后的区域,因此这可能仅在您希望整个画布具有统一图案时才有用。

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    
    var img = new Image();
    img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
    img.onload = function() {
      var pattern = ctx.createPattern(img, 'repeat');
      ctx.fillStyle = pattern;
      ctx.setTransform(0.8, 0.3, 0, 0.8, 0, 0)
      ctx.fillRect(0, -172, 450, 700); //make sure the whole canvas is covered
    };
    <canvas id="canvas" width="400" height="400"></canvas>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-07
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多