css - 如何在 HTML5 Canvas 上使用外部 CSS 绘制 SVG

标签 css svg canvas html5-canvas

我需要在 Canvas 上使用外部 CSS 文件绘制 SVG。

在下面的示例代码中,第一个多边形(三 Angular 形)使用 SVG,第二个使用从 SVG 绘制的 Canvas ,第三个使用从 Canvas 转换的图像。 <polygon> SVG 标签使用来自外部 common.css 文件的 ploygon CSS

svgtest.html:

<!DOCTYPE html>
<html>
   <head>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <title></title>
        <link href="common.css" type="text/css" rel="stylesheet" 
              xmlns="http://www.w3.org/1999/xhtml"/>
   </head>
   <body>
      <div id="svg-container">
         <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="500" height="210">
         <defs>
         </defs>
            <g>
               <rect x="78" y="78" width="694" height="284" style="stroke-width: 0px; fill: #ffffff; fill-opacity: 1;"></rect>
            <svg width="500" height="210" >
              <polygon class="ploygon" points="200,10 250,190 160,210" />
            </svg>
            </g>
         </svg>
      </div>
      <div>
      </div>
      <canvas id="canvas" width="500" height="210"></canvas>
      <div id="png-container"></div>
      <script>
         var svgElement = document.querySelector('svg');
         svgElement.onload = function() {
             var svgString = new XMLSerializer().serializeToString(svgElement);
             var svg = new Blob([svgString], { type: "image/svg+xml;charset=utf-8" });

             var canvas = document.getElementById("canvas");
             var ctx = canvas.getContext("2d");
             var DOMURL = self.URL || self.webkitURL || self;
             var img = new Image();
             var url = DOMURL.createObjectURL(svg);
             img.src = url;
             img.onload = function () {
                 ctx.drawImage(img, 0, 0);
                 var png = canvas.toDataURL("image/png");
                 document.querySelector('#png-container').innerHTML = '<img src="' + png + '"/>';
                 DOMURL.revokeObjectURL(png);
             };
         }
         var canvas1 = document.getElementById("canvas");

      </script>
   </body>
</html>

common.css:

 .ploygon {
    fill:lime;
 }

当我把 CSS <link><head>如上图,第一个 SVG 三 Angular 形可以使用 .ploygon CSS 并填充青柠色,第二个和第三个三 Angular 形用黑色填充。

enter image description here

我读到 CSS 链接标记可以放在 SVG 中。当我执行以下操作时:

     <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="850" height="440">
         <defs>
            <link href="common.css" type="text/css" rel="stylesheet" 
                  xmlns="http://www.w3.org/1999/xhtml"/>   
         </defs>
        <g>
           <rect x="78" y="78" width="694" height="284" style="stroke-width: 0px; fill: #ffffff; fill-opacity: 1;"></rect>
        <svg height="210" width="500">
          <polygon class="ploygon" points="200,10 250,190 160,210" />
        </svg>
        </g>
     </svg>

所有 3 个三 Angular 形都没有使用 CSS 并用黑色填充:

enter image description here

如果我更改为在 <svg> 中使用内联样式像这样

     <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="500" height="210">
         <defs>
            <style>
                 .ploygon {
                    fill:lime;
                 }
            </style>
         </defs>
        <g>
           <rect x="78" y="78" width="694" height="284" style="stroke-width: 0px; fill: #ffffff; fill-opacity: 1;"></rect>
        <svg width="500" height="210" >
          <polygon class="ploygon" points="200,10 250,190 160,210" />
        </svg>
        </g>
     </svg>

然后所有 3 个三 Angular 形都充满石灰:

enter image description here

我尝试在 <defs> 中使用 import the common.css , 但它不使用 css 文件。我不想将 CSS 样式内联。有什么好的解决办法吗?

最佳答案

一种解决方案是读取 CSS 文件内容并将其作为样式节点插入到您的 SVG 中:

// Create style element and insert the rules in it
let style = document.createElementNS("http://www.w3.org/2000/svg", "style");
style.textContent = getCssStringFromFile('common.css');
svgElement.insertBefore(style, svgElement.firstChild);

这里是 getCssStringFromFile 函数:

/**
 * Returns css rules as string from linked css file 
 * @param {string} fileName - The css file name.
 */
function getCssStringFromFile(fileName){
  let cssStyles = "";

  for(let i=0; i < document.styleSheets.length; i++) {
        let styleSheet = document.styleSheets[i];

        if (!styleSheet.href || styleSheet.href.indexOf(fileName) == -1)
           continue;

        let style = null;

        if (styleSheet) {
           if (typeof styleSheet.cssRules !== "undefined")
              style = styleSheet.cssRules;
           else if (typeof styleSheet.rules !== "undefined")
              style = styleSheet.rules;
        }
        for(let item in style) {
           if(typeof style[item].cssText !== "undefined")
              cssStyles += (style[item].cssText);
        }

        break;
  }

  return cssStyles;
}

请看演示here

关于css - 如何在 HTML5 Canvas 上使用外部 CSS 绘制 SVG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57330425/

相关文章:

javascript - 带有 requestanimationframe 的 Canvas 鼠标事件

android - Unity3D Canvas 。我怎样才能得到相机?

php - 如何为谷歌字体指定缓存验证器

CSS:如何控制页脚中SVG的大小

svg - 使现有的SVG旋转(正在加载图标)

javascript - 减少两个 Canvas html 之间的空间

html - 添加自定义字体 ttf 不起作用

css - 缩放未知大小的 SVG

html - 导航菜单 : css vertical centering

html - 如何从图像中剪切圆形部分?