评价打分组件,SVG 半颗星的解决方案!

微信搜索 【大迁世界】, 我会第一时间和你分享前端行业趋势,学习途径等等。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

对于一个内容服务的网站来说评价打分也是很重要的一部分,它有利于分析用户对我们的内容的喜好程序。最近,我们团需要为一个项目实现一个星级评价的组件,需求如下:

  • 性能(不能用图片)
  • 可调整的大小
  • 可访问性
  • 小数位打分(如:3.53.2
  • 使用 css 就可以直接控制样式

要达到上面的要求,经常调研,最终选择了 SVG 方案。

任务

下图是我们最终想要的效果:

image.png

我们主要的工作就是让星星可以改变其颜色,描边,大小,还可以显示半颗星星。

实现

在实现之前,我们需要有一个基础 SVG 结构,如下所示:


    

添加 aria-label

添加 aria-label 可以使用读屏器用户能够访问这一信息。

aria-label属性用来给当前元素加上的标签描述,接受字符串作为参数。是用不可视的方式给元素加label(如果被描述元素存在真实的描述元素,可使用 aria-labelledby 属性作为来绑定描述元素和被描述元素来代替)。

如何重用SVG

我们可以把上面的SVG 标签复制五次,或者提取path数据并保存在某个地方,然后在不重复代码的情况下重新使用它。我们选择后者。

首先,我们需要创建一个宽度和高度为零的SVG,这样它就不会保留空间。


    

在该SVG中,我们需要在元素中包含path数据。根据MDN:

symbol 元素用于定义图形模板对象,可以通过元素来实例化。

里面的内容与图标的内容相同。另外,添加一个 id 也很重要,这样我们以后就可以引用这个 symbol


    
        
    

有了这个设置,我们现在可以用元素来重用这个symbol。做法就是使用id作为href属性的值。

星星的样式

有了上面的星星结构,我们现在来添加样式:

.c-icon {
    --star-active: #fece3c;
    --star-inactive: #6c6962;
    fill: var(--star-inactive);
}

.c-icon.active {
    fill: var(--star-active);
}

运行后的结果:

image.png

半颗星

使用 SVG后做半颗星就很容易,有两个很好的解决方案。第一个是使用,第二个是使用SVG 渐变。

使用

使用 masks 的目的是模拟擦除星星的一部分并将另一部分涂成半透明颜色的效果。

image.png

在上图中,有一个正方形和一个星星。它们的交集就是我们想要的结果。

做法如下:

  • 创建一个可重用的SVG模板
  • 添加一个 元素,位置为x=50%
  • 将 mask 应用到星星上


  
    
      
    
    
      
    
  



    

问题是,当一颗半透明的星星被遮住时,我们如何才能显示它呢? 好吧,多亏了 SVG,我们可以在 中包含多个元素。


  
  

mask 中,白色元素表示我们想要显示的内容,黑色元素表示我们想要隐藏的内容。结合在一起时,我们可以创建一个cut-out effect效果。

image.png

注意,白色矩形被定位在0,0点,而黑色矩形被定位在50%,0。下面是它的效果:

image.png

涂写的部分代表最终结果,半颗星。 现在,你的可能在想,如何添加另一个半透明的星星以使其更清晰?

通过使用比纯黑更浅的颜色,我们将得到一个半透明的效果。这意味着目前被隐藏的区域将有一个浅色的星形颜色。


  
  

image.png

到这,我们回顾一下完整的 SVG 标签。


   
      
         
         
      

      
         
      
   


这样,我们就有了一个部分填充的恒星。这个解决方案的绝妙之处在于,我们不需要提供两种色调, mask 会起作用的:

image.png

事例地址:https://codepen.io/shadeed/pe...

第一种方法到这就介绍完了,我们来看第二种方法。

带有SVG渐变的半星

mask类似,我们需要在元素中定义一个渐变。


    
        
            
            
        
    

注意,我们有两个色块,第一个代表前半部分,第二个代表浅色阴影。在这个解决方案中,我们需要手动提供两种颜色。

image.png

事例地址:https://codepen.io/shadeed/pe...

轮廓样式

接下来我们给星星做个轮廓,这样看起来会更立体点。

image.png

SVG Mask 解决轮廓样式的问题

要添加描边,我们只需要在SVG元素中添加stroke。这将很好地工作全星。然而,对于部分的,它将被切断,因为掩码。这对完整的星星来说是很好的。然而,对于半颗,由于mask的原因,它将被遮住。

image.png

为了解决这个问题,我们需要另一个星形轮廓。可以通过复制元素并删除它的 mask 来实现这一点。

注意,我们有两个元素。一个带mask的,一个只有 stroke 的。这就是使用SVG masks 实现轮廓样式的方法。

事例地址:https://codepen.io/shadeed/pe...

SVG 渐变实现轮廓样式

对于渐变解决方案,我们不需要复制图标,因为没有mask 。我们需要做的是添加一个stroke,它就完成了。


   
      
        
        
      
   


事业地址:https://codepen.io/shadeed/pe...

大小

通过使用CSS变量并确保SVG具有正确的viewBox属性,我们可以轻松地调整它们的大小。

.c-icon {
    width: var(--size, 24px)
    height: var(--size, 24px);
}

.c-icon--md {
    --size: 40px;
}

.c-icon--lg {
    --size: 64px;
}

~完,我是刷碗智,我要去 SPA 了,我们下期见~


原文:https://ishadeed.com/article/...

编辑中可能存在的bug没法实时知道,事后为了解决这些bug,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

交流

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

你可能感兴趣的:(评价打分组件,SVG 半颗星的解决方案!)