Javascript 是否可以只显示SVG图标的一半?

Javascript 是否可以只显示SVG图标的一半?,javascript,css,reactjs,svg,react-icons,Javascript,Css,Reactjs,Svg,React Icons,我目前有一个评级系统,可以产生5颗星,可以显示一半的价值。我通过使用FontAwesome的半星来实现这一点,并使用CSS技巧使它们看起来像一颗星星。但是我想通过想出一种只显示SVG图标一半的方法来增加我的React和CSS知识。因此,我可以使用用户想要的任何图标,而不是半星,它只会显示50%的图标,例如,如果你想给3.5分 问:你能不能只显示图标的一半,并且知道用户是在点击一侧还是另一侧 下面是我目前使用的代码,它使用半星作为一点参考 import React, { useState } fr

我目前有一个评级系统,可以产生5颗星,可以显示一半的价值。我通过使用FontAwesome的半星来实现这一点,并使用CSS技巧使它们看起来像一颗星星。但是我想通过想出一种只显示SVG图标一半的方法来增加我的React和CSS知识。因此,我可以使用用户想要的任何图标,而不是半星,它只会显示50%的图标,例如,如果你想给3.5分

问:你能不能只显示图标的一半,并且知道用户是在点击一侧还是另一侧

下面是我目前使用的代码,它使用半星作为一点参考

import React, { useState } from 'react'
import { FaRegStarHalf, FaStarHalf } from 'react-icons/fa'

import './styles/Rater.css'

const Rater = ({ iconCount }) => {
    const [rating, setRating] = useState(null)
    const [hover, setHover] = useState(null)
    // check if user has set a rating by clicking a star and use rating to determine icons
    const Star = rating ? FaStarHalf : FaRegStarHalf

    return (
        <div>
            {[...Array(iconCount), ...Array(iconCount)].map((icon, i) => {
                const value = (i + 1) / 2

                return (
                    <label>
                        <input
                            type='radio'
                            name='rating'
                            value={value}
                            onClick={() => {
                                console.log(`value => `, value)
                                return setRating(value)
                            }}
                        />
                        <div className='star-container'>
                            <div>
                                <Star
                                    className={i % 2 ? 'star-left' : 'star'}
                                    color={value <= (hover || rating) ? '#ffc107' : '#e4e5e9'}
                                    onMouseEnter={() => setHover(value)}
                                    onMouseLeave={() => setHover(null)}
                                />
                            </div>
                        </div>
                    </label>
                )
            })}
        </div>
    )
}

export default Rater


import React,{useState}来自“React”
从'react icons/fa'导入{FaRegStarHalf,FaStarHalf}
导入“./styles/Rater.css”
常数率=({iconCount})=>{
常数[rating,setRating]=useState(null)
const[hover,setHover]=useState(null)
//通过单击星号检查用户是否设置了分级,并使用分级确定图标
常数星=额定值?快速半小时:票价半小时
返回(
{[…数组(iconCount),…数组(iconCount)].map((图标,i)=>{
常量值=(i+1)/2
返回(
{
log(`value=>`,value)
返回设定值(值)
}}
/>
setHover(null)}
/>
)
})}
)
}
出口违约率

我已经写了一段代码让你明白这个想法;如果单击星星的右侧,它的颜色将变为蓝色,如果单击左侧,它的颜色将变为金色。另外,最好不要使用
stopPropagation
并检查事件的
e.target

const starIcon=document.getElementById(“star”);
const icon=document.getElementById(“图标”);
starIcon.onclick=e=>{
starIcon.style.color=“蓝色”;
e、 停止传播();
};
icon.onclick=e=>{
starIcon.style.color=“金色”;
}
i{
剪辑路径:插入(0.50%);
颜色:金色;
}

文件

这里有一个使用3D变换的不同想法:

i{
颜色:金色;
}
.集装箱{
背景:#fff;
变换样式:保留-3d;
}
.一半{
变换:旋转(1deg);
}
i、 足球明星:悬停{
颜色:红色;
}

您可以在一个SVG中完成

  • 我扔掉了字体图标
  • 在上的7000多个图标中搜索“星”(第一次加载需要一分钟)
  • 选择带有最佳d路径的星形图标(清晰图标集:
    cl社交星形实体
  • 仅复制了d路径
  • 将d路径编辑为a100x100 视口/栅格
  • 通过将
    M0 0h100v100h-100v-100
    预先添加到路径,使其成为反向
  • 0 300 100
    viewBox中创建了一个新的SVG文件,以适合3星。。见下文
  • 添加了一个背景矩形设置金色颜色等级,带有
    width=“50%”
  • 使用3颗逆星,每颗都有x偏移
  • 添加了6个矩形覆盖所有半星
  • 在每个“半星”上设置内联事件
    (此SO代码段中的单击有效,但SO会增加较长的延迟)
概念证明
我能想到的最简单的解决方案是拥有一行svg图标,然后使用
溢出:隐藏
剪裁用户的选择

然后使用图标的一半宽度,它可以以一半的增量移动

$(文档).ready(函数()
{
$(document).on(“mousemove”,“.star container.unvoted”,函数(e)
{
让width=$(this.find(“.star”).width()/2;
e、 clientX=Math.ceil(e.clientX/=(宽度))*宽度;
$(this.find(“.inner”).css(“width”,e.clientX+“px”);
});
$(“.star container.unvoted”)。单击(函数(e)
{
$(此).removeClass(“未引导”);
}); 
});
.star container.inner{
溢出:隐藏;
宽度:100%;
身高:100%;
}
.星形容器.内部.星形{
显示:内联块;
宽度:20px;
高度:20px;
背景图像:url('https://www.flaticon.com/svg/static/icons/svg/1828/1828884.svg');
背景尺寸:包含;
}
.星形容器.内部.内部-2{
宽度:10000px;
}


如果您希望能够显示半颗星,并检测单击了哪一半,最简单的方法是将(半)颗星显示为
标记的背景图像。这意味着您还必须设置标记的宽度,以便仅显示SVG的一半,因此您可能必须将标记的
display
属性更改为
inline block
。这个答案可能会有所帮助:您可以使用CSS遮住星形,然后检查单击处理程序中单击的坐标是否位于图标的前半部分或后半部分。