SOURCE

console 命令行工具 X clear

                    
>
console
 // 将网路 url 转化为本地 url
    async function fetchToLocalUrl(url) {
      try {
        // 使用 fetch 请求图片
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        // 将响应转换为 Blob
        const blob = await response.blob();

        const reader = new FileReader();
        reader.readAsDataURL(blob);

        await new Promise((resolve) => {
          reader.onloadend = resolve;
        });

        return reader.result;
      } catch (error) {
        console.error("Error:", error);
        return null; // 返回 null 或原始 URL 以防出错
      }
    }

    // 点击下载
    document.querySelector("button").addEventListener("click", async () => {
      const svg = document.querySelector("svg");
      const canvas = document.querySelector("canvas");
      const context = canvas.getContext("2d");
      const dpr = window.devicePixelRatio ?? 1;


      // 处理清晰度
      const { width, height } = svg.getBoundingClientRect();
      canvas.width = width * dpr;
      canvas.height = height * dpr;
      context.scale(dpr, dpr);

      // 注入 css
      const style = document.querySelector("style").cloneNode(true);
      svg.insertBefore(style, svg.firstChild);

      // 网络图片 url 转化为本地 url
      const onlineImg = svg.querySelector("img");
      const localUrl = await fetchToLocalUrl(onlineImg.src);
      onlineImg.src = localUrl;
      // 确保图片加载完成
      await new Promise((resolve) => (onlineImg.onload = resolve));

      // 将 svg 序列化为 string:其实就是 html 代码文本
      const data = new XMLSerializer().serializeToString(svg);
      const img = new Image();
      // svg string 转化为 base64
      img.src = `data:image/svg+xml;charset=utf-8,${data}`;

      // 等待 img 加载完后绘制 canvas 并执行下载
      img.onload = async () => {
        context.drawImage(img, 0, 0);
        const a = document.createElement("a");
        a.download = "image.png";
        a.href = canvas.toDataURL("image/png");
        a.click();
      };
    });
 <svg width="470" height="320" viewBox="0 0 470 320">
      <foreignObject width="100%" height="100%">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="card">
            <div class="cover">
              <img src="./bgc.png" />
            </div>
            <div class="text">
              <h1>生活哲学</h1>
              <p>珍惜当下每一刻,</p>
              <p>用心去感受生活。</p>
              <p>用行动去追求梦,</p>
              <p>幸福在于微小瞬间。</p>
            </div>
          </div>
        </div>
      </foreignObject>
    </svg>
    <button>生成图片</button>
    <canvas></canvas>
.card {
      background-color: white;
      margin: 2em;
      display: flex;
      box-shadow: 0 0 1em rgba(0, 0, 0, 0.2);
      border-radius: 0.5em;
      width: 400px;
    }

    .cover {
      width: 180px;
    }

    .cover img {
      display: block;
      height: 100%;
      width: 100%;
      border-radius: 0.5em 0 0 0.5em;
    }

    .text {
      flex: 1;
      text-align: center;
      padding-top: 2em;
    }

    .text h1 {
      font-size: 1em;
    }

作者:LogicFlow
链接:https://juejin.cn/post/7410333135117975591
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。