基础圆环实现

css 实现圆环最简单的方法就是,将里面的圆盖在外面的圆上,让里面的圆颜色和外圆一样,看起来就像一个圆环了

优化圆环:使用 mask 进行切割

上面的做法是有一定的局限性的,对于单色背景还行,渐变色背景呢?甚至背景本身有动画效果呢?

最理想的方式是“真的”没有中间那一块

实现的方式是使用 mask 进行遮罩。这个遮罩类似于 ps 里的蒙版,把 svg/png 图片放在元素上,重合的地方保留,其他地方就直接切掉。

根据 svg/png 图片特有的属性,“透明”的部分就代表“没有”,一般黑色的部分就代表“有”

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100" height="100"><circle cx="50" cy="50" r="47" fill="none" stroke="#000000" stroke-width="6" />
</svg>

这是一个典型的圆环,把这个圆环放在一个 div 上就能将 div 切出圆环的形状

.ring {height: 200px;width: 200px;background-color: red;position: absolute;-webkit-mask-image: url(./assets/images/mysvg.svg);mask-image: url(./assets/images/mysvg.svg);-webkit-mask-size: 100%;mask-size: 100%;top: 50%;left: 50%;transform-origin: 0% 0%;
}

其中,生效的是(-webkit-)mask-image、(-webkit-)mask-size。分别指示了 svg 文件的路径和把 svg 遮盖在上面时 svg 图片的大小。注意 url 里内容不带引号。如果不幸 url 写错了,这个蒙版仍然会生效,但是会生效的有点厉害,整个都给遮盖了,让你以为是 svg 本身有问题改半天

css 的 mask 属性受支持但不完全受支持,在 chrome 里开发的时候就能发现,类似于 mask 开头的都被划掉了,但-webkit-mask 开头的就可以得到应用

个人猜测,可能有些平台适用加 webkit 的(比如说 chrome),有些不能加 webkit,所以每次写的时候两个都写上,如果只写一个会报 warning

关于 mask 及其相关属性:https://developer.mozilla.org/zh-CN/docs/Web/CSS/mask
mark-size 可以由被蒙的 div 的长宽的 x% 定义,也可以取 cover 和 contain 两个值,也可以同时用

指针运动实现

如何把指针“抠图”抠出来就不必赘述,依然使用 mask,指针运动就是小方块的 animation,但是 animation 的具体流程是需要讨论的

我想到的有两种方法,第一种方法是使用 transform: skew();,通过角度的伸缩来进行

但是这种方式被证明是不可行的。skew 进行倾斜的时候并非像我们想象中的,从左下角开始倾斜,而是从中间点开始倾斜

第二种方法是使用transform: rotate();这也更贴近真正钟表的旋转

有一些问题需要考虑:

  1. 各个方块做完需要 animation 后,何去何从?
  2. 最后 1/4 的时间段,方块不应保持原有的 90° 角,而是越来越小,如何实现?

第一个问题比较简单,animation 做完后,立即消失就好了

@keyframes rot3 {0% {transform: rotate(180deg);}25% {transform: rotate(90deg);opacity: 1;}25.1% {transform: rotate(90deg);opacity: 0;}100% {transform: rotate(90deg);opacity: 0;}
}

0% 到 25% 是 div 旋转,25% 到 25.1% 就是立即消失

第二个问题,最容易想到的是遮盖,用一个块把左半边挡住

注意各个块的上下关系,1、2 在最上层,挡板在中间,3、4 在最下层

这些用 z-index 调即可

加入光晕

光晕和阴影事实上是一种东西,看颜色黑还是白咯

在这里选择filter: drop-shadow();而非box-shadowdrop-shadow是真的牛,一张图说明一切(上面是 box-shadow,西下面是 drop-shadow)

具体区别见:
https://www.zhangxinxu.com/wordpress/2016/05/css3-filter-drop-shadow-vs-box-shadow/

#container {filter: drop-shadow(0 0 40px hsl(270, 73%, 53%));
}

顺带一提,hsl 跟 rgb 一样,是一种色彩表示方式。
HSL:hue(色彩),saturation(饱和度),lightness(明度)

完整代码:

<div id="container"><div id="round"><div id="plate"></div><div class="occlude_fan"></div><div class="occlude_fan"></div><div class="occlude_fan"></div><div class="occlude_fan"></div><div id="occlude_rect"></div></div>
</div>
#container {width: 500px;height: 500px;position: absolute;filter: drop-shadow(0 0 40px hsl(270, 73%, 53%));
}#round {height: 400px;width: 400px;position: absolute;top: 50px;left: 30px;border-radius: 50% 50% 50% 50%;-webkit-mask-image: url(./assets/images/mask1.svg);mask-image: url(./assets/images/mask1.svg);-webkit-mask-size: cover;mask-size: cover;overflow: clip;
}#plate {height: 100%;width: 100%;position: absolute;background-color: grey;
}#occlude_rect {height: 400px;width: 200px;background-color: grey;position: absolute;-webkit-mask-image: url(./mask1.svg);mask-image: url(./mask1.svg);-webkit-mask-size: cover;mask-size: cover;top: 0%;left: 0%;z-index: 3;
}.occlude_fan {height: 200px;width: 200px;background-color: hsl(270, 73%, 53%);position: absolute;-webkit-mask-image: url(./mask1-4.svg);mask-image: url(./mask1-4.svg);-webkit-mask-size: 100%;mask-size: 100%;top: 50%;left: 50%;transform-origin: 0% 0%;filter: drop-shadow(0 0 40px hsl(270, 73%, 53%));
}.occlude_fan:nth-of-type(2) {transform: rotate(90deg);animation: rot2 20s linear infinite;z-index: 4;
}.occlude_fan:nth-of-type(3) {transform: rotate(180deg);animation: rot3 20s linear infinite;z-index: 4;
}.occlude_fan:nth-of-type(4) {transform: rotate(-90deg);animation: rot4 20s linear infinite;z-index: 2;
}.occlude_fan:nth-of-type(5) {transform: rotate(0deg);animation: rot5 20s linear infinite;z-index: 2;
}@keyframes rot2 {0% {transform: rotate(90deg);}25% {transform: rotate(90deg);opacity: 1;}50% {transform: rotate(0deg);opacity: 1;}50.1% {transform: rotate(0deg);opacity: 0;}100% {transform: rotate(0deg);opacity: 0;}
}@keyframes rot3 {0% {transform: rotate(180deg);}25% {transform: rotate(90deg);opacity: 1;}25.1% {transform: rotate(90deg);opacity: 0;}100% {transform: rotate(90deg);opacity: 0;}
}@keyframes rot4 {0% {transform: rotate(-90deg);}75% {transform: rotate(-90deg);}100% {transform: rotate(-180deg);}
}@keyframes rot5 {0% {transform: rotate(0deg);}50% {transform: rotate(0deg);opacity: 1;}75% {transform: rotate(-90deg);opacity: 1;}75.1% {transform: rotate(-90deg);opacity: 0;}100% {transform: rotate(-90deg);opacity: 0;}
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="50" height="50"><circle cx="0" cy="0" r="47" fill="none" stroke="#000000" stroke-width="7" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100" height="100"><circle cx="50" cy="50" r="47" fill="none" stroke="#000000" stroke-width="6" />
</svg>

至此,效果如下:

好像还可以,但是有一个不能忍的问题:灰色条部分不应该发光却发光了。

这是因为左半边的灰色条,事实上是“挡板”裁出来的,是一个实体,所以自然也被镀上光了

我尝试过用一个 div 把 4 个块包起来,在该 container 上加 drop-shadow,结果给浏览器整不会了,摆烂,直接 shadow 一个都不显示——这也是很正常的,真实世界投影的时候,是不可能存在不透明的东西没有影子,放在它下面的东西却有影子的事情的。

这个问题不能解决,看起来我们上面所有的努力都白费了

新的思路——SVG

这种困境不是我一个人遇到,很多的前辈都遇到过:
https://www.cnblogs.com/coco1s/p/6225973.html

考虑在倒计时过程中的一帧,就是圆环一部分显示,一部分被切掉嘛

stroke-dasharray 这个属性刚好可以描绘这个,它的本意是将一个线变成变成虚线

下图就是 stroke-dasharray="5, 10, 20"的情况,5 实,10 空,20 实,5 空,10 实,20 空,形成了这样一个循环

当“实”和“空”的大小都足够大,就可以实现一条线里只有一循环

图片如何做出动画呢?仍然需要和 css 结合

所有 svg 显示属性都可以作为 css 属性来用

所以 css 动画放心使用 stroke-dasharray 就好了

@keyframes rot {0% {stroke-dasharray: 0 570;}100% {stroke-dasharray: 570 0;}
}

假设整个圆的周长是 570,动画开始时实线部分长 0,空的部分占 570,动画结束时实线部分长 570,空的部分是 0,视觉效果就是圆

对了,svg 可以直接插入 HTML 的,不一定要单独一个文件

<div id="clock-container"><svgwidth="240px"height="240px"version="1.1"xmlns="http://www.w3.org/2000/svg"><!-- 不动的灰色圆 --><circlecx="110"cy="110"r="90"stroke-width="10"stroke="gray"fill="none"></circle><!-- 动的紫色圆 --><circlecx="110"cy="110"r="90"stroke-width="10"stroke="hsl(270, 73%, 53%)"fill="none"class=" circle-load-svg"></circle></svg>
</div>

能转了

改变方向

虽然能转起来了,但是起始点是歪的,在右边

transform: rotate()对于 svg 也是适用的,不过不用加 deg 单位

<circle cx="110" cy="110" r="90" stroke-width="10" stroke="hsl(270, 73%, 53%)" fill="none"
transform="rotate(90)" class=" circle-load-svg">
</circle>

新的光晕

参考:https://juejin.cn/post/6844903492646092807

现在紫色圆环不再是多个东西拼凑的结果,而是一个可以选择的对象

所以可以顺利地使用 css 的filter:blur()

但是好像这样性能会有问题:每次变化的时候网页都会重绘

另一种方式是使用 svg 的阴影

svg 阴影的底层实现是高斯模糊,使用时首先 define 一个 blur

  <defs><filter id="f1"><feGaussianBlur in="SourceGraphic" stdDeviation="10" /></filter></defs>

这里 feGaussianBlur 就是高斯模糊的意思
in 是输入值,SourceGraphic 就是说对元素自己进行模糊,还有一些其他的取值,比如说 SourceAlpha 表示只取元素透明度
stdDeviation 是用来控制模糊程度的,越大越模糊
一般来说模糊的外延最多不超过 10%,要是想要更大的模糊范围参考上面的链接吧

之后像 css id 一样引用就好了

<circle ... filter="url(#f1)">
</circle>

效果还可以,但是变透明了。其实用 css filter:blur 也会变透明

那就再加一层真环好了

至此代码如下

<div id="ontainer"><svg width="1000px" height="1040px" version="1.1" xmlns="http://www.w3.org/2000/svg"><defs><filter id="f1"><feGaussianBlur in="SourceGraphic" stdDeviation="10" /></filter></defs><g transform="translate(0,300)rotate(-90)"><circle cx="110" cy="110" r="90" stroke-width="10" stroke="gray" fill="none"></circle><circle cx="110" cy="110" r="90" stroke-width="10" stroke="hsl(270, 73%, 53%)" fill="none"class=" circle-shadow" filter="url(#f1)"></circle><circle cx="110" cy="110" r="90" stroke-width="10" stroke="hsl(270, 73%, 53%)" fill="none"class=" circle-load-svg"></circle></g></svg>s
</div>
.circle-shadow .circle-load-svg {animation: rot 5s linear infinite;
}.circle-load-svg {}@keyframes rot {0% {stroke-dasharray: 570 0;}100% {stroke-dasharray: 0 570;}
}

样式优化

大体效果出来了,但是还是略丑了一些——线的边缘怎么这么方呢

svg 有一个stroke-linecap: round属性可以轻松解决

除此之外,stroke-linejoin: round也是很常用的,这个是指明线条拐角处的形状,用圆形
具体例子见:https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/stroke-linejoin

用CSS实现圆环倒计时相关推荐

  1. html 圆环实现多种颜色,SVG实现多彩圆环倒计时效果的示例代码

    圆环倒计时我们经常见到,实现的方法也有很多种.但是本文将介绍一种全新的实现方式,使用SVG来实现倒计时功能. 本文主要用到了SVG的stroke-dasharray和stroke-dashoffset ...

  2. svg 实现圆环倒计时效果

    一.先上效果图,项目中需要圆环根据中间的倒计时相应递减: 二.接下来看svg代码实现: (1)css 部分 #svgContainer {position: relative;display: fle ...

  3. svg实现圆环倒计时动画效果

    效果展示 1. 状态过渡:57s.20s.3s.0s 2.svg制作 由两圆环(一圆环作为灰色底色,一圆环倒计时60->0)一文本组成 <svg viewBox="0,0,100 ...

  4. css实现圆环效果,利用css实现圆环效果的方法

    利用css实现圆环效果的方法 发布时间:2020-08-24 10:16:31 来源:亿速云 阅读:135 作者:小新 这篇文章将为大家详细讲解有关利用css实现圆环效果的方法,小编觉得挺实用的,因此 ...

  5. CSS实现圆环进度条

    CSS实现圆环进度条 一.静态进度条 首先,我们先看一个静态进度条 第一步当然是先实现一个最外层的父级圆环. 其次是通过 clip-path画出两个半圆,并绝对定位覆盖在父级圆环. 小于50的时候,我 ...

  6. html 虚线圆形,css虚线圆环 和实线圆环

    css虚线圆环 和实线圆环 css虚线圆环 和实线圆环 虚线圆环 dashed为破折号 间隔 dotted为点 间隔 { border-radius:50px;width:100px;height:1 ...

  7. 倒计时动画 html,HTML+CSS动画实现倒计时

    最近想做一个倒计时的动画,来实现圆形时间动画倒计时特效 做之前自己的想法是,对像素点的位置用函数进行判断,然后将对应位置的颜色隐藏,但是这样很麻烦,而且自己不知道怎么用函数去实现圆环均匀消失这样的效果 ...

  8. android 圆环温度控件,android 圆环倒计时控件

    public classCountDownView extendsView { //圆环颜色private intmRingColor;//圆环宽度private floatmRingWidth;// ...

  9. css 实现圆环进度条

    先上图,最后的效果是这样 主要的思路是 使用锥形渐变给div一个背景,然后使用mask遮挡中间部分,这样就变成一个圆环了,最后用 before和after处理一下 圆环进度开始和结束位置. html ...

最新文章

  1. java 系统 类_JAVA系统类 System的简单整理
  2. 语言的进步与代码生成
  3. 手动写sonar plugin 一直File is not a plugin.
  4. spring roo_使用Spring Roo进行快速云开发–第1部分:Google App Engine(GAE)
  5. 小程序开发(1)-之目录结构和文件说明
  6. ERROR 程序出错,错误原因:'bytes' object has no attribute 'read'
  7. maven 阿里云的镜象
  8. linux内存脚本下载,linux tmpfs及消耗内存脚本
  9. 高中会考计算机免考条件,高中会考学生听力残疾可免考外语听力
  10. 如何快速获取CSDN积分
  11. 华为手机玩王者荣耀的时候微信消息通知不弹窗提示,打王者的时候微信不弹窗提示消息,(P30)【解决办法】
  12. java程序执行时间_java记录代码运行时间
  13. 无监督降维 效果评价 trustworthiness measure
  14. ICPC 昆明 单挑打铁记
  15. 抖音python广告用的什么音乐_被抖音捧火的几首纯音乐,都是你们要的原版,太震撼人心!...
  16. [AndroidStudio]Building Apps with Over 64K Methods
  17. workbench中施加预紧力进行模态分析
  18. 参加考试时不要使用计算机,2016年计算机等级考试上机操作应试技巧
  19. 搜狗拼音输入法输入数字和英文时总是有空格
  20. 【王阳明心学语录】-001

热门文章

  1. 寻迹小车逻辑电路模块
  2. RBF-UKF径向基神经网络结合无迹卡尔曼滤波估计锂离子电池SOC(附MATLAB代码)
  3. 65 - 请解释什么是线程锁,以及如何使用线程锁
  4. 推荐一个界面库:RingSDK
  5. sass-loader@13.2.0“ has unmet peer dependency “webpack@^5.0.0“
  6. [Pytorch图像分类全流程实战]Task06:可解释性分析
  7. Bowtie使用介绍
  8. 抽象工厂模式(三):抽象工厂模式概述
  9. 实现Vue移动端的PDF预览
  10. 2023大连海洋大学计算机考研信息汇总