从SVG星形图中移除白色背景

huangapple go评论86阅读模式
英文:

Remove White Background from SVG Stars

问题

这段代码用于显示星星评分,但您想知道如何移除星星上的白色背景矩形。您可以尝试将星星的背景颜色设置为透明,以移除白色背景矩形。在CSS中,将.rating progress.rating-bg::-webkit-progress-value.rating progress.rating-bg::-moz-progress-barbackground-color属性设置为transparent,这应该可以实现您想要的效果。

英文:

I have this code to show stars from a decimal.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

.rating {
  width: 120px;
  height: 24px;
  position: relative;
  background-color: gray;
}

.rating progress.rating-bg {
  -webkit-appearance: none;
  -moz-appearence: none;
  appearance: none;
  border: none;
  display: inline-block;
  height: 24px;
  width: 100%;
  color: orange;
}

.rating progress.rating-bg::-webkit-progress-value {
  background-color: orange;
}

.rating progress.rating-bg::-moz-progress-bar {
  background-color: orange;
}

.rating svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

<!-- language: lang-html -->

&lt;svg style=&quot;display:none;&quot;&gt;
  &lt;defs&gt;
    &lt;symbol id=&quot;fivestars&quot;&gt;
      &lt;path d=&quot;M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z M0 0 h24 v24 h-24 v-24&quot; fill=&quot;white&quot; fill-rule=&quot;evenodd&quot;/&gt;
      &lt;path d=&quot;M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z M0 0 h24 v24 h-24 v-24&quot; fill=&quot;white&quot; fill-rule=&quot;evenodd&quot; transform=&quot;translate(24)&quot;/&gt;
      &lt;path d=&quot;M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z M0 0 h24 v24 h-24 v-24&quot; fill=&quot;white&quot; fill-rule=&quot;evenodd&quot; transform=&quot;translate(48)&quot;/&gt;
      &lt;path d=&quot;M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z M0 0 h24 v24 h-24 v-24&quot; fill=&quot;white&quot; fill-rule=&quot;evenodd&quot; transform=&quot;translate(72)&quot;/&gt;
      &lt;path d=&quot;M12 .587l3.668 7.568 8.332 1.151-6.064 5.828 1.48 8.279-7.416-3.967-7.417 3.967 1.481-8.279-6.064-5.828 8.332-1.151z M0 0 h24 v24 h-24 v-24&quot; fill=&quot;white&quot; fill-rule=&quot;evenodd&quot;  transform=&quot;translate(96)&quot;/&gt;
    &lt;/symbol&gt;
  &lt;/defs&gt;
&lt;/svg&gt;
&lt;div class=&quot;rating&quot;&gt;
  &lt;progress class=&quot;rating-bg&quot; value=&quot;4.9&quot; max=&quot;5&quot;&gt;&lt;/progress&gt;
  &lt;svg&gt;&lt;use xlink:href=&quot;#fivestars&quot;/&gt;&lt;/svg&gt;
&lt;/div&gt;

<!-- end snippet -->

https://codepen.io/ppolp/pen/mdQyezW

It works but I'm trying to figure out how to remove the white rectange bg from the stars. Anyone able to point me in the right direction?

Thanks.

答案1

得分: 1

下面是您提供的代码部分的中文翻译:

你可以将所有内容包装在本地 JavaScript (JSWC) Web 组件中:

&lt;star-rating stars=5 rating=&quot;3.5&quot;
             bgcolor=&quot;green&quot; nocolor=&quot;grey&quot; color=&quot;gold&quot;&gt;&lt;/star-rating&gt;

如果您在所有现代浏览器中使用自定义元素 (Custom Element) 来创建所有 SVG,会更加容易:

  • 从星星图标中 仅复制 d-path
  • https://yqnn.github.io/svg-path-editor/ 中编辑 d-path 以适应 100x100 的 viewBox/grid
  • 通过在路径前添加 M0 0h100v100h-100v-100 来创建一个 反向 星星
  • 在一个 0 0 N 100 的 viewBox 中创建一个新的 SVG 文件,以适应所有星星... 请参见下文
  • 添加一个 背景矩形,设置为 金色
  • 使用反向星星,每个都有一个 x 偏移
  • 添加 覆盖 所有半星的 矩形
  • 在每个“半星”上设置内联事件 onclickonmouseover
&lt;!-- begin snippet: js hide: false console: true babel: false --&gt;

&lt;!-- language: lang-html --&gt;

    &lt;star-rating stars=5 rating=&quot;3.5&quot;
                 bgcolor=&quot;green&quot; nocolor=&quot;grey&quot; color=&quot;gold&quot;&gt;&lt;/star-rating&gt;
    &lt;star-rating stars=7 rating=&quot;50%&quot;
                 bgcolor=&quot;rebeccapurple&quot; nocolor=&quot;beige&quot; color=&quot;goldenrod&quot;&gt;&lt;/star-rating&gt;
    &lt;script&gt;
      document.addEventListener(&quot;click&quot;, (evt) =&gt; console.log(evt.target.getAttribute(&quot;n&quot;)))

      customElements.define(&quot;star-rating&quot;, class extends HTMLElement {
        set rating( rate ) {
          if (!String(rate).includes(&quot;%&quot;)) rate = Number(rate) / this.stars * 100 + &quot;%&quot;;
          this.querySelector(&quot;#rating&quot;).setAttribute(&quot;width&quot;, rate);
        }
        connectedCallback() {
          let { bgcolor, stars, nocolor, color, rating } = this.attributes;
          this.stars = ~~stars.value || 5;
          this.innerHTML = 
            `&lt;svg viewBox=&quot;0 0 ${this.stars*100} 100&quot; style=&quot;cursor:pointer;width:300px&quot;&gt;`
          + `&lt;rect width=&quot;100%&quot; height=&quot;100&quot; fill=&quot;${nocolor.value}&quot;/&gt;`
          + `&lt;rect id=&quot;rating&quot;  height=&quot;100&quot; fill=&quot;${color.value}&quot;  /&gt;`
            + Array(  this.stars     ).fill()
                   .map((i, n) =&gt; `&lt;path fill=&quot;${bgcolor.value}&quot; d=&quot;M${ n*100 } 0h102v100h-102v-100m91 42a6 6 90 00-4-10l-22-1a1 1 90 01-1 0l-8-21a6 6 90 00-11 0l-8 21a1 1 90 01-1 1l-22 1a6 6 90 00-4 10l18 14a1 1 90 010 1l-6 22a6 6 90 008 6l19-13a1 1 90 011 0l19 13a6 6 90 006 0a6 6 90 002-6l-6-22a1 1 90 010-1z&quot;/&gt;`)
                   .join(&quot;&quot;)
            + Array(  this.stars * 2 ).fill()
                   .map((i, n) =&gt; `&lt;rect x=&quot;${ n*50 }&quot; n=&quot;${n}&quot; opacity=&quot;0&quot; width=&quot;50&quot; height=&quot;100&quot;`
                      + ` onclick=&quot;dispatchEvent(new Event(&#39;click&#39;))&quot; `
                      + ` onmouseover=&quot;this.closest(&#39;star-rating&#39;).rating = ${(n+1)/2}&quot;/&gt;`)
                  .join(&quot;&quot;) 
          + &quot;&lt;/svg&gt;&quot;;

          this.rating = rating.value;
        }
      });
    &lt;/script&gt;

&lt;!-- end snippet --&gt;

希望这对您有所帮助。如果您需要进一步的翻译或解释,请随时告诉我。

英文:

FYI, you can wrap it all in a native JavaScript (JSWC) Web Component:

&lt;star-rating stars=5 rating=&quot;3.5&quot;
             bgcolor=&quot;green&quot; nocolor=&quot;grey&quot; color=&quot;gold&quot;&gt;&lt;/star-rating&gt;

It is way easier if you create all SVG client-side, using a Custom Element (supported in all modern Browsers):

  • copied only the d-path from a star icon
  • Edited the d-path in https://yqnn.github.io/svg-path-editor/ to a 100x100
    viewBox/grid
  • made it an inverse star by prepending M0 0h100v100h-100v-100 to the path
  • Created a new SVG file in a 0 0 N 100 viewBox to fit all stars.. see below
  • Added a background rectangle setting gold color rating
  • Used inverse stars, each at an x-offset
  • added rectangles covering all half-stars
  • set inline events onclick and onmouseover on every "half-star"

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;star-rating stars=5 rating=&quot;3.5&quot;
             bgcolor=&quot;green&quot; nocolor=&quot;grey&quot; color=&quot;gold&quot;&gt;&lt;/star-rating&gt;
&lt;star-rating stars=7 rating=&quot;50%&quot;
             bgcolor=&quot;rebeccapurple&quot; nocolor=&quot;beige&quot; color=&quot;goldenrod&quot;&gt;&lt;/star-rating&gt;
&lt;script&gt;
  document.addEventListener(&quot;click&quot;, (evt) =&gt; console.log(evt.target.getAttribute(&quot;n&quot;)))

  customElements.define(&quot;star-rating&quot;, class extends HTMLElement {
    set rating( rate ) {
      if (!String(rate).includes(&quot;%&quot;)) rate = Number(rate) / this.stars * 100 + &quot;%&quot;;
      this.querySelector(&quot;#rating&quot;).setAttribute(&quot;width&quot;, rate);
    }
    connectedCallback() {
      let { bgcolor, stars, nocolor, color, rating } = this.attributes;
      this.stars = ~~stars.value || 5;
      this.innerHTML = 
        `&lt;svg viewBox=&quot;0 0 ${this.stars*100} 100&quot; style=&quot;cursor:pointer;width:300px&quot;&gt;`
      + `&lt;rect width=&quot;100%&quot; height=&quot;100&quot; fill=&quot;${nocolor.value}&quot;/&gt;`
      + `&lt;rect id=&quot;rating&quot;  height=&quot;100&quot; fill=&quot;${color.value}&quot;  /&gt;`
        + Array(  this.stars     ).fill()
               .map((i, n) =&gt; `&lt;path fill=&quot;${bgcolor.value}&quot; d=&quot;M${ n*100 } 0h102v100h-102v-100m91 42a6 6 90 00-4-10l-22-1a1 1 90 01-1 0l-8-21a6 6 90 00-11 0l-8 21a1 1 90 01-1 1l-22 1a6 6 90 00-4 10l18 14a1 1 90 010 1l-6 22a6 6 90 008 6l19-13a1 1 90 011 0l19 13a6 6 90 006 0a6 6 90 002-6l-6-22a1 1 90 010-1z&quot;/&gt;`)
               .join(&quot;&quot;)
        + Array(  this.stars * 2 ).fill()
               .map((i, n) =&gt; `&lt;rect x=&quot;${ n*50 }&quot; n=&quot;${n}&quot; opacity=&quot;0&quot; width=&quot;50&quot; height=&quot;100&quot;`
                  + ` onclick=&quot;dispatchEvent(new Event(&#39;click&#39;))&quot; `
                  + ` onmouseover=&quot;this.closest(&#39;star-rating&#39;).rating = ${(n+1)/2}&quot;/&gt;`)
              .join(&quot;&quot;) 
      + &quot;&lt;/svg&gt;&quot;;

      this.rating = rating.value;
    }
  });
&lt;/script&gt;

<!-- end snippet -->

答案2

得分: 0

Sure, here is the translated content:

使用<progress>元素是个好主意。您可以使用SVG作为蒙版应用在进度条上,而不是将进度条和SVG叠加在一起。在这里,我定义了一个星形蒙版,它将成为一个星星的蒙版,然后又在另一个蒙版中遮罩了五个矩形。这个蒙版可以应用于进度条。

我自由地构建了星星,而不是使用路径。在像这个示例中使用蒙版时,这并不重要。

<!-- 开始片段:js 隐藏:false 控制台:true Babel:false -->

<!-- 语言:lang-js -->
document.forms.form01.range.addEventListener('change', e => {
  document.getElementById('rating').setAttribute('value', e.target.value);
});

<!-- 语言:lang-css -->
.rating progress.rating-bg {
  -webkit-appearance: none;
  -moz-appearence: none;
  appearance: none;
  border: none;
  display: inline-block;
  height: 24px;
  width: 120px;
  color: orange;
  background-color: #ddd;
  mask: url(#m1);
}

.rating progress.rating-bg::-webkit-progress-value {
  background-color: orange;
}

.rating progress.rating-bg::-moz-progress-bar {
  background-color: orange;
}

<!-- 语言:lang-html -->
<svg style="display: block;" width="0" height="0" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <mask id="star">
      <rect width="24" height="24" fill="white"/>
      <g transform="translate(12 12)">
        <rect id="r1" width="48" height="24" fill="black" transform="translate(0 7) rotate(24) skewX(-42)"/>
        <use href="#r1" transform="rotate(72)"/>
        <use href="#r1" transform="rotate(144)"/>
        <use href="#r1" transform="rotate(216)"/>
        <use href="#r1" transform="rotate(288)"/>
      </g>
    </mask>
    <mask id="m1">
      <rect id="r2" width="24" height="24" fill="white" mask="url(#star)"/>
      <use href="#r2" transform="translate(24 0)"/>
      <use href="#r2" transform="translate(48 0)"/>
      <use href="#r2" transform="translate(72 0)"/>
      <use href="#r2" transform="translate(96 0)"/>
    </mask>
  </defs>
</svg>
<div class="rating">
  <progress id="rating" class="rating-bg" value="2" max="5"></progress>
</div>
<form name="form01">
  <input type="range" name="range" step=".25" min="0" max="5" value="2">
</form>

<!-- 结束片段 -->

希望这对您有所帮助。

英文:

Good idea to use the &lt;progress&gt; element. Instead of laying the progress bar and the SVG on top of each other you can use an SVG as a mask on the progress bar. Here I defined a star mask that will be a mask for just one star and masked off five rectangles in another mask. This mask can then be applied to the progress bar.

I took the freedom to construct the star instead of using a path. When using masks like in this example it doesn't matter.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

document.forms.form01.range.addEventListener(&#39;change&#39;, e =&gt; {
document.getElementById(&#39;rating&#39;).setAttribute(&#39;value&#39;, e.target.value);
});

<!-- language: lang-css -->

.rating progress.rating-bg {
-webkit-appearance: none;
-moz-appearence: none;
appearance: none;
border: none;
display: inline-block;
height: 24px;
width: 120px;
color: orange;
background-color: #ddd;
mask: url(#m1);
}
.rating progress.rating-bg::-webkit-progress-value {
background-color: orange;
}
.rating progress.rating-bg::-moz-progress-bar {
background-color: orange;
}

<!-- language: lang-html -->

&lt;svg style=&quot;display: block;&quot; width=&quot;0&quot; height=&quot;0&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;defs&gt;
&lt;mask id=&quot;star&quot;&gt;
&lt;rect width=&quot;24&quot; height=&quot;24&quot; fill=&quot;white&quot;/&gt;
&lt;g transform=&quot;translate(12 12)&quot;&gt;
&lt;rect id=&quot;r1&quot; width=&quot;48&quot; height=&quot;24&quot; fill=&quot;black&quot; transform=&quot;translate(0 7) rotate(24) skewX(-42)&quot;/&gt;
&lt;use href=&quot;#r1&quot; transform=&quot;rotate(72)&quot;/&gt;
&lt;use href=&quot;#r1&quot; transform=&quot;rotate(144)&quot;/&gt;
&lt;use href=&quot;#r1&quot; transform=&quot;rotate(216)&quot;/&gt;
&lt;use href=&quot;#r1&quot; transform=&quot;rotate(288)&quot;/&gt;
&lt;/g&gt;
&lt;/mask&gt;
&lt;mask id=&quot;m1&quot;&gt;
&lt;rect id=&quot;r2&quot; width=&quot;24&quot; height=&quot;24&quot; fill=&quot;white&quot; mask=&quot;url(#star)&quot;/&gt;
&lt;use href=&quot;#r2&quot; transform=&quot;translate(24 0)&quot;/&gt;
&lt;use href=&quot;#r2&quot; transform=&quot;translate(48 0)&quot;/&gt;
&lt;use href=&quot;#r2&quot; transform=&quot;translate(72 0)&quot;/&gt;
&lt;use href=&quot;#r2&quot; transform=&quot;translate(96 0)&quot;/&gt;
&lt;/mask&gt;
&lt;/defs&gt;
&lt;/svg&gt;
&lt;div class=&quot;rating&quot;&gt;
&lt;progress id=&quot;rating&quot; class=&quot;rating-bg&quot; value=&quot;2&quot; max=&quot;5&quot;&gt;&lt;/progress&gt;
&lt;/div&gt;
&lt;form name=&quot;form01&quot;&gt;
&lt;input type=&quot;range&quot; name=&quot;range&quot; step=&quot;.25&quot; min=&quot;0&quot; max=&quot;5&quot; value=&quot;2&quot;&gt;
&lt;/form&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月8日 16:34:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定