有没有一种方法既可以通过 URL 加载 SVG 图像,又可以用 CSS 颜色变量填充它?

问题描述 投票:0回答:2

我正在构建一个编辑器,用户可以在其中从我们的 CDN 选择 SVG,并选择其填充颜色。在前端,我希望能够以用户选择的颜色渲染这些 SVG,但这似乎不可能。有人知道我应该尝试什么方法吗?

我从服务器获取的数据如下:

  • cdnURL:应从中加载 SVG 的 URL

  • fillColor:与我们前端中的 SCSS 变量相对应的文本。我为所有颜色制作了实用程序类来实现填充属性:

    color__fill--black { fill: black; }
    

我在这个网站上找到了建议更改 SVG 文件的 fill-property 的答案,但这是不可能的,因为我在 CDN 上只有它的源 URL。我也看到人们建议使用 CSS 过滤器,但这并不能解决我的问题,因为颜色变化很大,从黑色到蓝色到黄色到白色。

css svg sass
2个回答
1
投票

很简单,创建一个 (JSWC) 原生 javascript

<load-svg>
Web 组件。

  • 加载外部 SVG 文件
  • 将其分配给shadowDOM insideHTML
  • 追加所有
    <style>
    元素

<load-svg src="//svg-cdn.github.io/heart.svg">
  <style>
    svg { height: 180px  } path:nth-child(2n+2) { fill: red }
  </style>
</load-svg>

<load-svg src="//svg-cdn.github.io/heart.svg">
  <style>
    svg { height: 180px } path:nth-child(3n+2) { fill: yellow }
  </style>
</load-svg>

<load-svg src="//svg-cdn.github.io/heart.svg">
  <style>
    svg { height: 180px } path:nth-child(3n+1) { fill: blue }
  </style>
</load-svg>

<script>
  customElements.define('load-svg', class extends HTMLElement {
    async connectedCallback() {
      this.attachShadow({mode:"open"})
          .innerHTML = await (await fetch(this.getAttribute("src"))).text();
      this.shadowRoot.append(...this.childNodes);
    }
  });
</script>


0
投票

我建议您加载选定的 SVG 并将其内联插入到 HTML 元素中。这里我只使用 fetch 函数。基本上,我在数组中的数据 URL 可以替换为普通 URL,并且代码仍然可以工作(从同一域的 Web 服务器运行)。

对于颜色可能有多种不同的方法。在这里我更改了样式元素的内容。 SVG 中的任何元素都会获得指定的颜色。

const urls = [ 'data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAgMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTSA1IDAgTCAwIDUgTCA1IDEwIEwgMTAgNSBaIiAvPgo8L3N2Zz4=',
'data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAgMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGNpcmNsZSBjeD0iNSIgY3k9IjUiIHI9IjUiIC8+Cjwvc3ZnPg=='
];

const container = document.getElementById('container');
const style = document.getElementById('style01');

document.forms.form01.img.addEventListener('change', e => {
  if(e.target.value){
    fetch(urls[e.target.value]).then(res => res.text()).then(text => {
      container.innerHTML = text;
    });
  }
});

document.forms.form01.color.addEventListener('change', e => {
  style.textContent = `#container * {fill: ${e.target.value};}`;
});
#container {
  width: 200px;
}
<style id="style01">#container * {fill: #1a5fb4;}</style>
<form name="form01">
  <select name="img">
    <option>Select an SVG</option>
    <option value="0">SVG 1</option>
    <option value="1">SVG 2</option>
  </select>
  <input name="color" type="color" value="#1a5fb4" />
</form>
<div id="container"></div>

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.