问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

通过CSS动画实现圆形进度条

创作时间:
2025-03-11 11:00:16
作者:
@小白创作中心

通过CSS动画实现圆形进度条

引用
CSDN
1.
https://m.blog.csdn.net/qq_45914628/article/details/144118965

1. WXML结构部分

<view class="circleProgress_wrapper" bind:longpress="startCountDown" bind:touchend="endCountDown">
  <view class="wrapper right">
    <view class="circleProgress rightcircle {{ animation ? 'animation' : '' }}"></view>
  </view>
  <view class="wrapper left">
    <view class="circleProgress leftcircle {{ animation ? 'animation' : '' }}"></view>
  </view>
  <view class="inner">
    <view class="block"></view>
    <view class="text">结束</view>
  </view>
</view>
  
  • **
    bind:longpress="startCountDown"

    bind:touchend="endCountDown"
    **:分别绑定了长按和触摸结束事件,用于启动和停止倒计时动画。
  • rightcircle

    leftcircle
    这两个视图分别负责右半部分和左半部分进度条的显示,并在动画激活时添加
    animation
    类。

2. CSS样式部分

这段代码实现了一个圆形进度条的效果,采用了 CSS 和动画来创建动态效果。下面是详细的解析:

**外部结构
.circleProgress_wrapper
**

.circleProgress_wrapper {
  width: 200rpx;
  height: 200rpx;
  margin: 50rpx auto;
  position: relative;
}
  
  • **
    width: 200rpx; height: 200rpx;
    **:设置了圆形进度条的外部容器的宽高为200rpx。
  • **
    margin: 50rpx auto;
    **:将该容器水平居中,并且上下有50rpx的间隔。
  • **
    position: relative;
    **:设置
    position: relative
    ,使得其内部子元素可以通过
    position: absolute
    定位。

**进度条容器
.wrapper
**

.wrapper {
  width: 100rpx;
  height: 200rpx;
  position: absolute;
  top: 0;
  overflow: hidden;
}
  
  • **
    width: 100rpx; height: 200rpx;
    **:设置容器宽度为100rpx,内部高度仍然是200rpx。
  • **
    position: absolute;
    **:让
    .wrapper
    定位到父容器
    .circleProgress_wrapper
    的顶部。
  • **
    overflow: hidden;
    **:使得容器的内容溢出部分不可见。

**左右部分
.right

.left
**

.right {
  right: 0;
}
.left {
  left: 0;
}
  
  • **
    .right

    .left
    **通过
    position: absolute;
    定位,用于在圆形进度条的左右两侧放置旋转的进度条动画。

**圆形进度条
.circleProgress
**

.circleProgress {
  width: 190rpx;
  height: 190rpx;
  border: 5rpx solid #E5E5E5;
  border-radius: 50%;
  position: absolute;
  top: 0;
}
  
  • **
    width: 190rpx; height: 190rpx;
    **:设置了一个 190rpx 的正方形,宽高一致,形状为圆形。
  • **
    border: 5rpx solid #E5E5E5;
    **:圆形外边框宽度为5rpx,颜色为淡灰色,表示未完成的进度部分。
  • **
    border-radius: 50%;
    **:设置为圆形。
  • **
    position: absolute; top: 0;
    **:将其定位在父容器的顶部。

**内部圆形和文字
.inner
**

.inner {
  width: 180rpx;
  height: 180rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  position: absolute;
  top: 9.5rpx;
  left: 11.5rpx;
  background: #FE9D45;
  color: #FFFFFF;
  font-size: 26rpx;
}
  
  • **
    width: 180rpx; height: 180rpx;
    **:设置比外圆形小的内圆形,形成边框。
  • **
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    **:使用 Flexbox 来居中内容,确保里面的文本或块元素都处于中央。
  • **
    border-radius: 50%;
    **:内圆形设置为圆形。
  • **
    background: #FE9D45; color: #FFFFFF;
    **:内圆背景颜色为橙色,文本颜色为白色。
  • **
    font-size: 26rpx;
    **:设置字体大小为26rpx。

**进度条内小块
.block
**

.block {
  width: 30rpx;
  height: 30rpx;
  border-radius: 5rpx;
  background: #FFFFFF;
  margin-bottom: 12rpx;
}
  
  • **
    width: 30rpx; height: 30rpx;
    **:小块的尺寸为30rpx,形成圆角矩形。
  • **
    border-radius: 5rpx;
    **:边角圆滑。
  • **
    background: #FFFFFF; margin-bottom: 12rpx;
    **:背景为白色,并设置下边距为12rpx,用来分隔其他内容。

**左右进度条
.rightcircle

.leftcircle
**

.rightcircle {
  right: 0;
}
.leftcircle {
  left: 0;
}
  
  • **
    .rightcircle

    .leftcircle
    **定位于圆形的左右两侧,作为进度条的动态部分。

**动画效果
circleProgressLoad_right

circleProgressLoad_left
**

.rightcircle.animation {
  border-top: 5rpx solid #FE9D45;
  border-right: 5rpx solid #FE9D45;
  animation: circleProgressLoad_right 2s linear infinite;
}
.leftcircle.animation {
  border-bottom: 5rpx solid #FE9D45;
  border-left: 5rpx solid #FE9D45;
  animation: circleProgressLoad_left 2s linear infinite;
}
  
  • **
    .rightcircle.animation

    .leftcircle.animation
    **:这两个类分别表示右半部分和左半部分的进度条,动画的核心是在这些类中实现的。
  • **
    animation: circleProgressLoad_right 2s linear infinite;
    **:为右半部分进度条添加了一个 2秒循环的动画,动画名称为
    circleProgressLoad_right
  • **
    animation: circleProgressLoad_left 2s linear infinite;
    **:左半部分的进度条同样添加了动画
    circleProgressLoad_left

**关键帧动画
@keyframes
**

**右半部分动画
circleProgressLoad_right
**

@keyframes circleProgressLoad_right {
  0% {
    border-top: 5rpx solid #FE9D45;
    border-right: 5rpx solid #FE9D45;
    -webkit-transform: rotate(45deg);
  }
  50% {
    border-top: 5rpx solid #FE9D45;
    border-right: 5rpx solid #FE9D45;
    border-left: 5rpx solid #E5E5E5;
    border-bottom: 5rpx solid #E5E5E5;
    -webkit-transform: rotate(225deg);
  }
  100% {
    border-left: 5rpx solid #E5E5E5;
    border-bottom: 5rpx solid #E5E5E5;
    -webkit-transform: rotate(225deg);
  }
}
  
  • 0%:设置右半部分的边框颜色为橙色,旋转45度。
  • 50%:过渡阶段,左侧和下方边框颜色变为灰色,旋转225度。
  • 100%:完成时,左侧和下方完全是灰色,表示进度已完成的一部分。

**左半部分动画
circleProgressLoad_left
**

@keyframes circleProgressLoad_left {
  0% {
    border-bottom: 5rpx solid #FE9D45;
    border-left: 5rpx solid #FE9D45;
    -webkit-transform: rotate(45deg);
  }
  50% {
    border-bottom: 5rpx solid #FE9D45;
    border-left: 5rpx solid #FE9D45;
    border-top: 5rpx solid #E5E5E5;
    border-right: 5rpx solid #E5E5E5;
    -webkit-transform: rotate(45deg);
  }
  100% {
    border-top: 5rpx solid #E5E5E5;
    border-right: 5rpx solid #E5E5E5;
    -webkit-transform: rotate(225deg);
  }
}
  
  • 0%:设置左半部分的边框颜色为橙色,旋转45度。
  • 50%:过渡阶段,右侧和上方边框颜色变为灰色,旋转45度。
  • 100%:完成时,右侧和上方完全是灰色,表示进度已完成。

3. JavaScript部分

Component({
  /**
   * 组件的初始数据
   */
  data: {
    animation: false,
    timer: null as any
  },
  /**
   * 组件的方法列表
   */
  methods: {
    startCountDown() {
      const that = this
      this.setData({
        animation: true,
        timer: setTimeout(() => {
          that.triggerEvent('end')
          that.setData({
            animation: false
          })
        }, 2000)
      })
    },
    endCountDown() {
      clearTimeout(this.data.timer)
      this.setData({
        animation: false,
        timer: null
      })
    }
  }
})
  

**
startCountDown()
**

  • startCountDown()
    是长按事件的处理函数。调用时会启动倒计时动画并设置一个 2 秒钟的延时:
  • this.setData({ animation: true })
    :开启动画,添加
    animation
    类。
  • this.setData({ timer: setTimeout(...) })
    :设置一个定时器,2 秒后执行结束逻辑,并触发
    end
    事件。

**
endCountDown()
**

  • endCountDown()
    是触摸结束事件的处理函数,用于清除定时器并停止动画:
  • clearTimeout(this.data.timer)
    :清除之前的定时器。
  • this.setData({ animation: false, timer: null })
    :停止动画并重置定时器。

4. 总结

  • 这段代码通过使用
    @keyframes
    定义了两个旋转动画,分别给右半圆和左半圆应用不同的颜色变化,模拟进度条的加载效果。
  • 通过
    position

    flexbox
    布局,整体进度条是一个嵌套的结构,外部有一个容器
    .circleProgress_wrapper
    ,内部是由多个部分组成的圆形进度条。
  • 最终的效果是一个不断旋转的进度条,右半部分和左半部分交替显示红色和灰色,模拟加载进度。
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号