乐趣区

关于javascript:评价打分组件SVG-半颗星的解决方案

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

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

  • 性能(不能用图片)
  • 可调整的大小
  • 可拜访性
  • 小数位打分(如:3.53.2
  • 应用 css 就能够间接管制款式

要达到下面的要求,常常调研,最终抉择了 SVG 计划。

工作

下图是咱们最终想要的成果:

咱们次要的工作就是让星星能够扭转其色彩,描边,大小,还能够显示半颗星星。

实现

在实现之前,咱们须要有一个根底 SVG 构造,如下所示:

<svg width="32" height="32" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
    <path d="..."/>
</svg>

增加 aria-label

增加 aria-label 能够应用读屏器用户可能拜访这一信息。

<p aria-label="Rating is 4.5 out of 5">
   <svg width="32" height="32" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
      <path d="..."/>
   </svg>
</p>

aria-label 属性用来给以后元素加上的标签形容,承受字符串作为参数。是用不可视的形式给元素加 label(如果被形容元素存在实在的形容元素,可应用 aria-labelledby 属性作为来绑定形容元素和被形容元素来代替)。

如何重用 SVG

咱们能够把下面的 SVG 标签复制五次,或者提取 path 数据并保留在某个中央,而后在不反复代码的状况下从新应用它。咱们抉择后者。

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

<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Content -->
</svg>

在该 SVG 中,咱们须要在 <symbol> 元素中蕴含 path 数据。依据 MDN:

symbol 元素用于定义图形模板对象,能够通过 <use> 元素来实例化。

<symbol>外面的内容与图标的内容雷同。另外,增加一个 id 也很重要,这样咱们当前就能够援用这个 symbol

<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
    <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" id="star">
        <path d="..."/>
    </symbol>
</svg>

有了这个设置,咱们当初能够用 <use> 元素来重用这个 symbol。做法就是应用id 作为 href 属性的值。

<p class="c-rate">
    <svg class="c-icon" width="32" height="32">
      <use href="#star"></use>
    </svg>
    <svg class="c-icon" width="32" height="32">
      <use href="#star"></use>
    </svg>
    <svg class="c-icon" width="32" height="32">
      <use href="#star"></use>
    </svg>
    <svg class="c-icon" width="32" height="32">
      <use href="#star"></use>
    </svg>
    <svg class="c-icon" width="32" height="32">
      <use href="#star"></use>
    </svg>
</p>

星星的款式

有了下面的星星构造,咱们当初来增加款式:

<p class="c-rate">
    <svg class="c-icon active" width="32" height="32">
      <use href="#star"></use>
    </svg>
    <svg class="c-icon active" width="32" height="32">
      <use href="#star"></use>
    </svg>
    <svg class="c-icon active" width="32" height="32">
      <use href="#star"></use>
    </svg>
    <svg class="c-icon active" width="32" height="32">
      <use href="#star"></use>
    </svg>
    <svg class="c-icon" width="32" height="32">
      <use href="#star"></use>
    </svg>
</p>
.c-icon {
    --star-active: #fece3c;
    --star-inactive: #6c6962;
    fill: var(--star-inactive);
}

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

运行后的后果:

半颗星

应用 SVG 后做半颗星就很容易,有两个很好的解决方案。第一个是应用<masks>,第二个是应用 SVG 突变。

应用<masks>

应用 masks 的目标是模仿擦除星星的一部分并将另一部分涂成半透明色彩的成果。

在上图中,有一个正方形和一个星星。它们的交加就是咱们想要的后果。

做法如下:

  • 创立一个可重用的 SVG 模板
  • 增加一个 <mask> 元素,地位为x=50%
  • 将 mask 利用到星星上
<!-- The reusable SVG template -->
<svg viewBox="0 0 32 32" id="star">
  <defs>
    <mask id="half">
      <rect x="50%" y="0" width="32" height="32" fill="white" />
    </mask>
    <symbol viewBox="0 0 32 32" id="star">
      <path d="..." />
    </symbol>
  </defs>
</svg>

<svg class="c-icon" width="32" height="32" viewBox="0 0 32 32">
    <use href="#star" mask="url(#half)" fill="green"></use>
</svg>

问题是,当一颗半透明的星星被遮住时,咱们如何能力显示它呢?好吧,多亏了 SVG,咱们能够在 <mask> 中蕴含多个元素。

<mask id="half">
  <rect x="0" y="0" width="32" height="32" fill="white" />
  <rect x="50%" y="0" width="32" height="32" fill="black" />
</mask>

mask 中,红色元素示意咱们想要显示的内容,彩色元素示意咱们想要暗藏的内容。联合在一起时,咱们能够创立一个 cut-out effect 成果。

留神,红色矩形被定位在 0,0 点,而彩色矩形被定位在50%,0。上面是它的成果:

涂写的局部代表最终后果,半颗星。当初,你的可能在想,如何增加另一个半透明的星星以使其更清晰?

通过应用比纯黑更浅的色彩,咱们将失去一个半透明的成果。这意味着目前被暗藏的区域将有一个浅色的星形色彩。

<mask id="half">
  <rect x="0" y="0" width="32" height="32" fill="white" />
  <rect x="50%" y="0" width="32" height="32" fill="grey" />
</mask>

到这,咱们回顾一下残缺的 SVG 标签。

<svg style="width: 0; height: 0;" viewBox="0 0 32 32">
   <defs>
      <mask id="half">
         <rect x="0" y="0" width="32" height="32" fill="white" />
         <rect x="50%" y="0" width="32" height="32" fill="grey" />
      </mask>

      <symbol viewBox="0 0 32 32" id="star">
         <path d="..." />
      </symbol>
   </defs>
</svg>

<p class="c-rate">
   <svg class="c-icon" width="32" height="32" viewBox="0 0 32 32">
      <use href="#star" mask="url(#half)" fill="green"></use>
   </svg>
   <!-- 4 more stars -->
</p>

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

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

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

带有 SVG 突变的半星

mask 相似,咱们须要在 <defs> 元素中定义一个突变。

<svg style="width: 0; height: 0;" viewBox="0 0 32 32">
    <defs>
        <linearGradient id="half" x1="0" x2="100%" y1="0" y2="0">
            <stop offset="50%" stop-color="#f7efc5"></stop>
            <stop offset="50%" stop-color="#fed94b"></stop>
        </linearGradient>
    </defs>
</svg>

留神,咱们有两个色块,第一个代表前半部分,第二个代表浅色暗影。在这个解决方案中,咱们须要手动提供两种色彩。

<p class="c-rate">
    <svg class="c-icon" width="32" height="32" viewBox="0 0 32 32">
        <use href="#star" fill="url(#half)"></use>
    </svg>
</p>

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

轮廓款式

接下来咱们给星星做个轮廓,这样看起来会更平面点。

SVG Mask 解决轮廓款式的问题

要增加描边,咱们只须要在 SVG 元素中增加 stroke。这将很好地工作全星。然而,对于局部的,它将被切断,因为掩码。这对残缺的星星来说是很好的。然而,对于半颗,因为mask 的起因,它将被遮住。

为了解决这个问题,咱们须要另一个星形轮廓。能够通过复制 <use> 元素并删除它的 mask 来实现这一点。

<p class="c-rate">
   <svg class="c-icon" width="32" height="32" viewBox="0 0 32 32">
      <use href="#star" mask="url(#half)" fill="green"></use>
      <use href="#star" fill="none" stroke="grey"></use>
   </svg>
</p>

留神,咱们有两个 <use> 元素。一个带 mask 的,一个只有 stroke 的。这就是应用 SVG masks 实现轮廓款式的办法。

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

SVG 突变实现轮廓款式

对于突变解决方案,咱们不须要复制图标,因为没有mask 。咱们须要做的是增加一个stroke,它就实现了。

<svg style="width: 0; height: 0;" viewBox="0 0 32 32">
   <defs>
      <linearGradient id="half" x1="0" x2="100%" y1="0" y2="0">
        <stop offset="50%" stop-color="#f7efc5"></stop>
        <stop offset="50%" stop-color="#fed94b"></stop>
      </linearGradient>
   </defs>
</svg>

<p class="c-rate">
   <svg class="c-icon" width="32" height="32" viewBox="0 0 32 32">
     <use href="#star" fill="url(#half)" stroke="grey"></use>
   </svg>
</p>

事业地址: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 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

退出移动版