有趣的css知识又增长了之 conic-gradient + 饼图组件

本文由团队成员 BingLee1994 撰写,已受权涂鸦大前端独家使用,包括但不限于编辑、标注原创等权益。javascript

你是否是有这种感受:能用几行css画出来,不用四处找svg或者上传图片,就以为特别开心呢。那么渐变就能够作不少这样的事情,好比花纹,遮罩,常见图形等。css

咱们熟知的有线性渐变和锥形渐变,那么今天介绍另外一位伙伴 conic-gradient 锥形渐变。html

兼容性

主流现代浏览器均兼容。 581db541-7a14-4a20-9e89-f34392436bb9-image.png前端

全部好玩高效的css特性均不兼容IE11,不要让他成为阻碍进步的绊脚石。java

名词解释

若是你初次接触渐变呢,简单了解下:渐变由方向位置,和多个颜色驻点组成。git

颜色驻点

一个颜色驻点由颜色和位置组成,用空格隔开,如下图为例: 708ba743-df40-4cf3-a94b-1556739422cd-image.png 能够看到背景由绿→红→蓝,控制颜色的圈圈就是颜色驻点,那么本图中绿和蓝分别在头尾部,红色在25%的位置,那么这个红色驻点表示为:red 25%,处于头尾部可没必要写位置。github

方向与中心

上图咱们明显看到渐变朝右,那么咱们能够指定渐变的方向为任意角度,以下面这样 eda8cca0-8201-49ea-840e-9aba2491ef38-image.png 特殊的,锥形渐变和放射渐变还能够指定中心点,放射渐变还能够指定半径,原型椭圆形等。 95979704-00ea-4be5-a34d-424d7de16a2c-image.png浏览器

conic-gradient

好,进入正题,什么是conic-gradient(锥形渐变)?顾名思义,看下图 f33c7c4a-ca33-4d95-bed8-8b99f1a7b708-image.png 发现了吗?颜色绕着中心点旋转了一周,就像圆锥同样,这就是锥形渐变,颜色驻点位置以下图红线所示,恰好在半径线上: 4b26b7b2-4877-4d4a-99bd-247277b49b7f-image.pngmarkdown

语法

backgrouns-image: conic-gradient([ 角度 [at 位置] ], 颜色驻点1, 颜色驻点2, 颜色驻点...) 其中中括号表示非必要属性,默认角度为0,位置在元素正中心,大部分场景,默认的就知足需求。
颜色驻点位置除了可使用百分比,还可使用角度表示法。dom

试一试

语法看着有点长,别惧怕,让咱们写一个css试试效果吧:

div {
  width: 200px;
  height: 200px;
  background-image: conic-gradient(orange, blue 50%, purple)
}
复制代码

渲染以下:沿着中心转一圈,开始由橙色转到50%变为蓝色,而后由蓝色转到360°变成紫色,就是这么简单!

那么上述50%还可使用角度表示法: conic-gradient(orange, blue 180deg, purple), 特别地,能够指定两个角度,表示颜色覆盖的角度区域,好比 conic-gradient(orange, blue 180deg 240deg, purple).

c8f11dab-05bf-4165-985e-c86d675664ee-image.png

开始画饼图

光了解而不会实际应用怎么能够呢?本文咱们拿常见的饼图为实际应用案例,来更进一步体验锥形渐变。

以下图:橙色区域占30%. 4df6b5d9-e373-49f7-900c-9b1ae310c18a-image.png

差在哪里?

对比下咱们上述渐变和这个饼图差在哪里呢?
没错,你发现了吗?饼图背景和橙色扇形区域(下文咱们叫进度)之间的衔接处是硬的而不是渐变过渡的。 d6a59dfa-95bf-4942-9589-941a0339fc8d-image.png 怎么作呢?不要着急,让咱们先把渐变画出来:

div {
  width: 200px;
  height: 200px;
  background-image: conic-gradient(orange, purple 30%)
}
复制代码

e58cc51d-5e97-4509-b2bf-8c31e7c34592-image.png

让颜色衔接处变硬

唉~,咱们惊喜发现,在起始处0°和360°,是一条橙色直接到紫色的硬线,而不是渐变,由于0° = 360 °,同一个角度位置出现两种颜色,那么两个颜色距离是0,换句话说,留给橙色渐变到紫色的空间长度为0,那天然视觉上就是没有渐变,相连处变硬,颜色直接改变

知道了这个道理,咱们就能够轻松画出上述饼图,只须要将上述30%的位置添加两个颜色驻点,这样他们两个就会直接硬性过渡。

让咱们修改css代码以下:

div {
  width: 200px;
  height: 200px;
  background-image: conic-gradient(orange 30%, purple 30%);
  /* 30%的位置设置两个驻点橙色和紫色,那么在这个位置直接硬性过渡而无渐变 */
}
复制代码

d9c15801-eceb-4187-bc8a-84144e83be81-image.png 大功告成,最后不要忘了加个border-radius,so easy!

饼图动起来

这么有趣的东西咱们确定要封装成组件用才能用到真实的场景,上文咱们轻松画出了30%的饼图,相似地,经过更改百分比就可让饼图动起来了,那么咱们写个简单地demo控制饼图,咱们经过一个滑块控制!

你能够直接拷贝以下html代码作练习

<body>
  <style> body { height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; } #pie-chart { width: 200px; height: 200px; border-radius: 100px; background-image: conic-gradient(orange 0%, purple 0%); margin-bottom: 24px; } </style>

  <div id="pie-chart"></div>
  <input id="slider" type="range" value="0" max="100" min="0" step="10" />

  <script type="text/javascript"> // js代码写这里 </script>
</body>
复制代码

6ceb40ce-5ad5-46cf-ac8b-74f5acbbe2d8-image.png

添加滑块事件

本例中滑块取值为0 ~ 100,对应颜色驻点位置,经过添加滑块的input事件来控制饼图百分比:

<script type="text/javascript"> const elPieChart = document.getElementById('pie-chart') const elSlider = document.getElementById('slider') elSlider.oninput = function updateChart() { const { value } = elSlider //将滑块value转换为驻点位置 elPieChart.style.backgroundImage = `conic-gradient(orange ${value}%, purple ${value}%)` } </script>
复制代码

你看,就是这么短短几句代码,饼图就能动起来了😊! 230c6ade-b5fe-47dd-813d-10ce571a7991-屏幕录制2021-06-05 上午10.43.44.gif

组件可定制

上面紫色饼可能不合你口味,让咱们在js代码里换换颜色吧,咱们定义两个变量,一个背景色,一个进度颜色,最后修改css背景便可:

<script type="text/javascript"> // 自定义颜色 const chartColor = '#C6E9FF' const chartProgressColor = '#4589EF' const elPieChart = document.getElementById('pie-chart') const elSlider = document.getElementById('slider') // 首次渲染设置颜色 elPieChart.style.backgroundImage = `conic-gradient(${chartProgressColor} 0%, ${chartColor} 0%)` elSlider.oninput = function updateChart() { const { value } = elSlider //更改饼图进度 elPieChart.style.backgroundImage = `conic-gradient(${chartProgressColor} ${value}%, ${chartColor} ${value}%)` } </script>
复制代码

a1d95f3a-1076-468e-8eb8-f4d18f049dec-image.png

持续优化

你觉得写到这里就结束了吗?让咱们回过头看看代码,只是增长了个颜色需求,js代码开始变得很是丑陋,主要出如今 elPieChart.style.backgroundImage = `conic-gradient(${chartProgressColor} ${value * 100}%, ${chartColor} ${value * 100}%)

这一坨代码很是刺眼,由于:

  1. 这个css字符串很臭长。
  2. js拼接css字符串由于没有代码提示,因此很是容易写错,中间少个标点符号空格啥的,调试起来太恶心了。
  3. 今天我写的,我能看懂,过几天我再来看,我本身都看不懂了,无可维护性!

若是你在平常组件开发时遇到相似的烦恼,那么好消息是,这是一个典型的使用css变量的应用场景教程传送门

代码可维护性在整个项目中很是重要,不要为了赶进度或者偷懒而忽视。

使用css变量瘦身

如今,让咱们把全部样式有关的东西统统留在css代码里,本例中是两个颜色和一个饼图进度,那么相应的,咱们要暴露出对应的css变量让js来操做。是的,css代码就应该老老实实呆在css里面,不要出来凑热闹.

修改上面的css代码以下,定义须要暴露给js的变量并赋予初始值:

#pie-chart {
  /* 声明变量并初始化 */
  --chartColor: orange; /* 背景色 */
  --chartProgressColor: purple; /* 进度色 */
  --chartProgress: 0%; /* 进度 */

  width: 200px;
  height: 200px;
  border-radius: 100px;
  /* 使用变量,(有点模板的意思) */
  background-image: conic-gradient(
    var(--chartProgressColor) var(--chartProgress), 
    var(--chartColor) var(--chartProgress)
  );
  margin-bottom: 24px;
}
复制代码

而后在js里直接操做css变量便可,API传送门

<script type="text/javascript"> // 自定义颜色 const chartColor = '#C6E9FF' const chartProgressColor = '#4589EF' const elPieChart = document.getElementById('pie-chart') const { style } = elPieChart const elSlider = document.getElementById('slider') // 首次渲染设置颜色 style.setProperty('--chartColor', chartColor) style.setProperty('--chartProgressColor', chartProgressColor) elSlider.oninput = function updateChart() { const { value } = elSlider //更改饼图进度 style.setProperty('--chartColor', chartColor) style.setProperty('--chartProgressColor', chartProgressColor) style.setProperty('--chartProgress', `${value}%`) } </script>
复制代码

如今咱们用更优,可读性更高的变量代替传统css拼接字符串,通过优化后的js代码更加js.

你能够用喜欢的方式继续重构,那么上述操做css变量的部分其实能够再优化,能够写工具类,可是不管如何,终于摆脱了css.

试想,若是咱们的组件dom层级很深,还按照老的笨方法,层层查找节点,样式穿透,将会是噩梦,使用css变量,只需专一变量自身,而无需考虑dom层级,而且开发者能够更好维护,也方便了使用者经过css hack的手段去定制样式,但愿你能get到这个点。

更多场景

除了饼图,圆环进度条,Loading动画,遮罩等等也是锥形渐变的使用场景,大胆发挥你的想象力吧。

喜欢本文记得三连支持😙

相关文章
相关标签/搜索