vue.js html canvas -多个svg图像,它们都具有不同的填充样式颜色

7dl7o3gd  于 2022-12-19  发布在  Vue.js
关注(0)|答案(1)|浏览(130)

对于一个数字艺术作品,我在Vue中生成了一个canvas元素,它从一个由多个图像组成的数组中进行绘制。图像可以分为两类:

  • SVG(带有填充颜色)
  • PNG(只需要绘制为常规图像)

"我想到了这个"

const depict = (options) => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      const myOptions = Object.assign({}, options);
      if (myOptions.ext == "svg") {
        return loadImage(myOptions.uri).then((img) => {
          ctx.drawImage(img, 0, 0, 100, 100);
          ctx.globalCompositeOperation = "source-in";
          ctx.fillStyle = myOptions.clr;
          ctx.fillRect(0, 0, 100, 100);
          ctx.globalCompositeOperation = "source-over";
        });
      } else {
        return loadImage(myOptions.uri).then((img) => {
          ctx.fillStyle = myOptions.clr;
          ctx.drawImage(img, 0, 0, 100, 100);
        });
      }
    };
    this.inputs.forEach(depict);

上下文:

myOptions.clr =颜色
myOptions.uri =图像的URL
myOptions.ext =图像的扩展名
虽然所有的图像都画得很好,但我不明白为什么最后一个填充样式会覆盖整个图像。我只是希望所有的SVG都有附加的填充样式。
我尝试了不同顺序的多个globalCompositeOperation。我还尝试在ctx.savectx.restore之间绘制svg。没有成功...我可能在这里遗漏了一些逻辑。

pgky5nke

pgky5nke1#

所以!在此期间我自己想通了:)
我创建了一个带有promise的异步循环,在其中我为每个图像创建了一个临时画布,然后将其绘制到一个画布上,我从这个解决方案中获得了灵感:https://stackoverflow.com/a/6687218/15289586
下面是最终代码:

// create the parent canvas
    let parentCanv = document.createElement("canvas");
    const getContext = () => parentCanv.getContext("2d");
    const parentCtx = getContext();
    parentCanv.classList.add("grid");

    // det the wrapper from the DOM
    let wrapper = document.getElementById("wrapper");

    // this function loops through the array
    async function drawShapes(files) {
      for (const file of files) {
        await depict(file);
      }
      // if looped > append parent canvas to to wrapper
      wrapper.appendChild(parentCanv);
    }

    // async image loading worked best
    const loadImage = (url) => {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.onload = () => resolve(img);
        img.onerror = () => reject(new Error(`load ${url} fail`));
        img.src = url;
      });
    };

    // depict the file
    const depict = (options) => {
      // make a promise
      return new Promise((accept, reject) => {
        const myOptions = Object.assign({}, options);
        var childCanv = document.createElement("canvas");
        const getContext = () => childCanv.getContext("2d");
        const childCtx = getContext();
        if (myOptions.ext == "svg") {
          loadImage(myOptions.uri).then((img) => {
            childCtx.drawImage(img, 0, 0, 100, parentCanv.height);
            childCtx.globalCompositeOperation = "source-in";
            childCtx.fillStyle = myOptions.clr;
            childCtx.fillRect(0, 0, parentCanv.width, parentCanv.height);
            parentCtx.drawImage(childCanv, 0, 0);
            accept();
          });
        } else {
          loadImage(myOptions.uri).then((img) => {
            // ctx.fillStyle = myOptions.clr;
            childCtx.drawImage(img, 0, 0, 100, parentCanv.height);
            parentCtx.drawImage(childCanv, 0, 0);
            accept();
          });
        }
      });
    };

    drawShapes(this.inputs);

相关问题