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

cpjpxq1n  于 2023-01-22  发布在  其他
关注(0)|答案(2)|浏览(188)

我正在构建一个编辑器,用户可以从CDN中选择一个SVG,并选择它的填充颜色。在前端,我希望能够以用户选择的颜色呈现这些SVG,但这似乎是不可能的。有人知道我应该尝试什么方法吗?
我从服务器获得的数据如下:

  • cdnURL:加载SVG的URL
  • fillColor:与前端中的SCSS变量相对应的文本。我为所有颜色创建了实用程序类来实现fill-property:
color__fill--black { fill: black; }

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

wfveoks0

wfveoks01#

我建议你加载选定的SVG并将其内嵌到HTML元素中。这里我只使用fetch function。基本上,数组中的数据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>
pdkcd3nj

pdkcd3nj2#

很简单,创建一个本地javascript <load-svg> Web组件。

  • 加载外部SVG文件
  • 将其分配给shadowDOM innerHTML
  • 附加所有的<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>

相关问题