英文:
Remove White Background from SVG Stars
问题
这段代码用于显示星星评分,但您想知道如何移除星星上的白色背景矩形。您可以尝试将星星的背景颜色设置为透明,以移除白色背景矩形。在CSS中,将.rating progress.rating-bg::-webkit-progress-value
和.rating progress.rating-bg::-moz-progress-bar
的background-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 -->
<svg style="display:none;">
<defs>
<symbol id="fivestars">
<path d="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" fill="white" fill-rule="evenodd"/>
<path d="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" fill="white" fill-rule="evenodd" transform="translate(24)"/>
<path d="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" fill="white" fill-rule="evenodd" transform="translate(48)"/>
<path d="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" fill="white" fill-rule="evenodd" transform="translate(72)"/>
<path d="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" fill="white" fill-rule="evenodd" transform="translate(96)"/>
</symbol>
</defs>
</svg>
<div class="rating">
<progress class="rating-bg" value="4.9" max="5"></progress>
<svg><use xlink:href="#fivestars"/></svg>
</div>
<!-- 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 组件中:
<star-rating stars=5 rating="3.5"
bgcolor="green" nocolor="grey" color="gold"></star-rating>
如果您在所有现代浏览器中使用自定义元素 (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 偏移
- 添加 覆盖 所有半星的 矩形
- 在每个“半星”上设置内联事件
onclick
和onmouseover
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<star-rating stars=5 rating="3.5"
bgcolor="green" nocolor="grey" color="gold"></star-rating>
<star-rating stars=7 rating="50%"
bgcolor="rebeccapurple" nocolor="beige" color="goldenrod"></star-rating>
<script>
document.addEventListener("click", (evt) => console.log(evt.target.getAttribute("n")))
customElements.define("star-rating", class extends HTMLElement {
set rating( rate ) {
if (!String(rate).includes("%")) rate = Number(rate) / this.stars * 100 + "%";
this.querySelector("#rating").setAttribute("width", rate);
}
connectedCallback() {
let { bgcolor, stars, nocolor, color, rating } = this.attributes;
this.stars = ~~stars.value || 5;
this.innerHTML =
`<svg viewBox="0 0 ${this.stars*100} 100" style="cursor:pointer;width:300px">`
+ `<rect width="100%" height="100" fill="${nocolor.value}"/>`
+ `<rect id="rating" height="100" fill="${color.value}" />`
+ Array( this.stars ).fill()
.map((i, n) => `<path fill="${bgcolor.value}" d="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"/>`)
.join("")
+ Array( this.stars * 2 ).fill()
.map((i, n) => `<rect x="${ n*50 }" n="${n}" opacity="0" width="50" height="100"`
+ ` onclick="dispatchEvent(new Event('click'))" `
+ ` onmouseover="this.closest('star-rating').rating = ${(n+1)/2}"/>`)
.join("")
+ "</svg>";
this.rating = rating.value;
}
});
</script>
<!-- end snippet -->
希望这对您有所帮助。如果您需要进一步的翻译或解释,请随时告诉我。
英文:
FYI, you can wrap it all in a native JavaScript (JSWC) Web Component:
<star-rating stars=5 rating="3.5"
bgcolor="green" nocolor="grey" color="gold"></star-rating>
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
andonmouseover
on every "half-star"
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
<star-rating stars=5 rating="3.5"
bgcolor="green" nocolor="grey" color="gold"></star-rating>
<star-rating stars=7 rating="50%"
bgcolor="rebeccapurple" nocolor="beige" color="goldenrod"></star-rating>
<script>
document.addEventListener("click", (evt) => console.log(evt.target.getAttribute("n")))
customElements.define("star-rating", class extends HTMLElement {
set rating( rate ) {
if (!String(rate).includes("%")) rate = Number(rate) / this.stars * 100 + "%";
this.querySelector("#rating").setAttribute("width", rate);
}
connectedCallback() {
let { bgcolor, stars, nocolor, color, rating } = this.attributes;
this.stars = ~~stars.value || 5;
this.innerHTML =
`<svg viewBox="0 0 ${this.stars*100} 100" style="cursor:pointer;width:300px">`
+ `<rect width="100%" height="100" fill="${nocolor.value}"/>`
+ `<rect id="rating" height="100" fill="${color.value}" />`
+ Array( this.stars ).fill()
.map((i, n) => `<path fill="${bgcolor.value}" d="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"/>`)
.join("")
+ Array( this.stars * 2 ).fill()
.map((i, n) => `<rect x="${ n*50 }" n="${n}" opacity="0" width="50" height="100"`
+ ` onclick="dispatchEvent(new Event('click'))" `
+ ` onmouseover="this.closest('star-rating').rating = ${(n+1)/2}"/>`)
.join("")
+ "</svg>";
this.rating = rating.value;
}
});
</script>
<!-- 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 <progress>
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('change', e => {
document.getElementById('rating').setAttribute('value', 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 -->
<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>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论