h5canvas实现圆形时间倒计时进度条(代码片段)

suwu150 suwu150     2022-12-02     169

关键词:

在项目中,我们会遇到需要显示进度条或者倒计时的功能,我们今天就来实现一下。

一、效果展示


实现效果要求:
1.环形倒计时
2.能够根据总时间和当前时间进行比例性的倒计时
3.进度条环形能够有颜色渐变效果
4.中间文字能够有颜色渐变效果

二、准备文件

在开发canvas程序时,我们通常需要准备静态html和需要引用的js文件即可,这次我们使用的静态html模板如下:
1.html页面

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" /> -->
    <title>圆形倒计时</title>
  </head>
  <body>
    <div class="clock-show" style="width: 800px;height: 700px">
        <canvas id="canvas" width="800" height="700"></canvas>
      </div>
  </body>

  <script src="./index.js"></script>
</html>

2.js文件-需要操作canvas标签的代码
我们先定义好需要去实现的方法,分别如下面代码

function CircleClock(canvas) 
  // 定义一个CircleClock构造函数,用于初始化 


CircleClock.prototype.setProgress = function (progress) 
    // 用于设置从外部设置进度
;

CircleClock.prototype.getProgress = function () 
    // 用于获取进度
;

CircleClock.prototype.drawBackgroundCircle = function () 
    // 画圆形的背景环形条
;

CircleClock.prototype.drawCurrentProgressCircle = function () 
  // 绘制倒计时环形进度条
;

CircleClock.prototype.createLinearGradientByTime = function () 
    // 按照进度,计算渐变色
;

CircleClock.prototype.drawTimeText = function () 
    // 绘制环中间文字倒计时
;

CircleClock.prototype.clear = function () 
    // 清理canvas
;

CircleClock.prototype.setTime = function (seconds) 
    // 设置初始时间,需要倒计时的时间
;

CircleClock.prototype.setCurrentTime = function (currentSeconds) 
    // 实时同步当前剩下的时间
;

CircleClock.prototype.run = function (seconds, endCallback) 
    // 开始运行项目,运行时传入初始时间和回调函数
;

CircleClock.prototype.update = function (unPass) 
  this.setCurrentTime(unPass);
  this.clear();
  this.drawBackgroundCircle();
  this.drawCurrentProgressCircle();
  this.drawTimeText();
;

const circleClock = new CircleClock("canvas");
circleClock.run(30, () => 
  console.log("倒计时执行完毕");
);

三、代码方法说明

1.构造函数
function CircleClock(canvas) 
  // 定义一个CircleClock构造函数,用于初始化 
  this.canvas = document.querySelector(canvas);
  this.context = this.canvas.getContext("2d");
  this.width = 800;
  this.height = 700;
  this.progress = 0;  // 用于记录当前的进度
  this.seconds = 0; // 需要倒计时的时间,秒
  this.currentSeconds = 0; // 当前倒计时到的位置

2.设置进度和获取进度方法
CircleClock.prototype.setProgress = function (progress) 
    // 用于设置从外部设置进度
  this.progress = progress;
;
CircleClock.prototype.getProgress = function () 
    // 用于获取进度
  return this.progress;
;
3.绘制圆形进度背景环
CircleClock.prototype.drawBackgroundCircle = function () 
    // 画圆形的背景环形条
  const x = this.width / 2;
  const y = this.height / 2;
  this.context.strokeStyle = "#40C4FF";
  this.context.lineWidth = 16;
  this.context.beginPath();
  // 绘制圆形背景。从弧度-(Math.PI / 2)到2 * Math.PI
  this.context.arc(x, y, this.width / 5, -(Math.PI / 2), 2 * Math.PI);
  this.context.stroke();
;
4.绘制当前进度环
CircleClock.prototype.drawCurrentProgressCircle = function () 
  const x = this.width / 2;
  const y = this.height / 2;
  // 绘制倒计时环形进度条
  const canvasGradient = this.context.createLinearGradient(
    0,
    0,
    0,
    this.height
  );
  // 在offset为0的位置(即起点位置)添加一个蓝色的渐变
  canvasGradient.addColorStop(0, "#00BCD4");
  // 在offset为0.4的位置(线段左起20%的位置)添加一个绿色的渐变
  canvasGradient.addColorStop(0.4, "#7C4DFF");
  // 在offset为0.8的位置(即终点位置)添加一个红色的渐变
  canvasGradient.addColorStop(0.8, "#DCE775");
  // 在offset为1的位置(即终点位置)添加一个红色的渐变
  canvasGradient.addColorStop(1, "#FF5722");
  // 将strokeStyle的属性值设为该CanvasGradient对象
  this.context.strokeStyle = canvasGradient;
  // 计算进度
  const progress = 1 - this.currentSeconds / this.seconds;
  this.setProgress(progress);
  // - (Math.PI/2),  (progress) *(3/2 *Math.PI)   [-0.5, 1.5]-[0, 1],
  this.context.lineWidth = 16;
  this.context.lineCap = "round";
  this.context.beginPath();
  // 绘制圆形进度环
  this.context.arc(
    x,
    y,
    this.width / 5,
    -(Math.PI / 2),
    (-0.5 + 2 * progress) * Math.PI
  );
  this.context.stroke();
;
5.根据时间或者进度创建渐变色
CircleClock.prototype.createLinearGradientByTime = function () 
    // 按照进度,计算渐变色
  const progress = this.getProgress();
  // 修改填充颜色
  const canvasGradient = this.context.createLinearGradient(
    this.width / 2 - 18,
    this.height / 2 - 18,
    this.width / 2,
    this.height / 2 + 50
  );
  canvasGradient.addColorStop(0, "#00BCD4");
  progress > 0 && progress < 0.4 && canvasGradient.addColorStop(0.3, "#7C4DFF");

  progress > 0.4 &&
    progress < 0.8 &&
    canvasGradient.addColorStop(0.6, "#DCE775");
  progress > 0.6 &&
    progress < 0.9 &&
    canvasGradient.addColorStop(0.8, "#EEFF41");
  canvasGradient.addColorStop(1, "#FF5722");
  return canvasGradient;
;
6.绘制中间的倒计时文本
CircleClock.prototype.drawTimeText = function () 
    // 绘制环中间文字倒计时
  this.context.fillStyle = this.createLinearGradientByTime();
  this.context.textAlign = "start";
  this.context.font = "36px bold";
  this.context.textBaseline = "alphabetic";
  let s = parseInt(this.currentSeconds);
  let ss = parseInt(s % 60);
  let mm = parseInt(s / 60);
  const text = `$mm.toString().padStart(2, 0): $ss
    .toString()
    .padStart(2, 0)`;
    // 计算文本长度,适配位置
  const textWidth = this.context.measureText(text).width;
  this.context.fillText(
    text,
    this.width / 2 - textWidth / 2,
    this.height / 2 + 18
  );
;

7.清理canvas
CircleClock.prototype.clear = function () 
    // 清理canvas
  this.context.clearRect(0, 0, this.width, this.height); //每改变一次动画就要对这个空间范围进行一次刷新,不然会重叠在一起
;
8.设置初始倒计时时间
CircleClock.prototype.setTime = function (seconds) 
    // 设置初始时间,需要倒计时的时间
  this.seconds = seconds;
;
9.设置当前已经倒计时的时间点
CircleClock.prototype.setCurrentTime = function (currentSeconds) 
    // 实时同步当前剩下的时间
  this.currentSeconds = currentSeconds;
;
10.开始运行项目

运行项目,传入初始时间和回调函数,这里会不停的反复运行,如果需要停止,可以通过打开clearInterval(intervalTime);代码进行关闭计时器

CircleClock.prototype.run = function (seconds, endCallback) 
    // 开始运行项目,运行时传入初始时间和回调函数
  let count = 0;
  const intervalTime = setInterval(() => 
    this.setTime(seconds);
    const allTime = this.seconds;
    const unPass = allTime - count;
    count = count + 1;
    console.log("unPass", unPass);
    if (unPass < 0) 
      //   clearInterval(intervalTime);
      this.setTime(30);
      count = 0;
      endCallback && endCallback();
     else 
      this.update(unPass);
    
  , 1000);
;
11.更新时间

用于更新当前已经倒计时倒计到的时间,相当于重新绘制整个界面

CircleClock.prototype.update = function (unPass) 
  this.setCurrentTime(unPass);
  this.clear();
  this.drawBackgroundCircle();
  this.drawCurrentProgressCircle();
  this.drawTimeText();
;
12.初始化,运行代码

const circleClock = new CircleClock("canvas");
circleClock.run(30, () => 
  console.log("倒计时执行完毕");
);

上面是所有代码的分布解析,下面给出完整代码

四、完整代码

1.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" /> -->
    <title>圆形倒计时</title>
  </head>
  <body>
    <div class="clock-show" style="width: 800px;height: 700px">
        <canvas id="canvas" width="800" height="700"></canvas>
      </div>
  </body>

  <script src="./index.js"></script>
</html>

2.js

function CircleClock(canvas) 
  // 定义一个CircleClock构造函数,用于初始化 
  this.canvas = document.querySelector(canvas);
  this.context = this.canvas.getContext("2d");
  this.width = 800;
  this.height = 700;
  this.progress = 0;  // 用于记录当前的进度
  this.seconds = 0; // 需要倒计时的时间,秒
  this.currentSeconds = 0; // 当前倒计时到的位置


CircleClock.prototype.setProgress = function (progress) 
    // 用于设置从外部设置进度
  this.progress = progress;
;

CircleClock.prototype.getProgress = function () 
    // 用于获取进度
  return this.progress;
;

CircleClock.prototype.drawBackgroundCircle  = function () 
    // 画圆形的背景环形条
  const x = this.width / 2;
  const y = this.height / 2;
  this.context.strokeStyle = "#40C4FF";
  this.context.lineWidth = 16;
  this.context.beginPath();
  // 绘制圆形背景。从弧度-(Math.PI / 2)到2 * Math.PI
  this.context.arc(x, y, this.width / 5, -(Math.PI / 2), 2 * Math.PI);
  this.context.str

圆形进度条 Android

...倒数计时器。(来源:jiaojianli.com)到目前为止,我能够实现类似于倒数计时器但没有段或块概念的圆形进度条。【问题讨论】:【 查看详情

h5canvas圆形进度条上上有圆点,进度70%圆点就在70%上(随着进度到哪就在哪),怎么做。

类似效果,这里有原理和源代码http://blog.csdn.net/tangdou5682/article/details/52778766参考技术Abymember`varchar(12)defaultNULL,`sex`varchar(2)defaultNULL,`count`int(4)defaultNULL)ENGINE=MyISAMDEFAULTCHARSET=gb2312;/*Dataforthetable`m_count_by`*/ 查看详情

wpf实现圆形进度条(代码片段)

 WPF实现圆形进度条控件名:CircularProgressBar作 者:WPFDevelopersOrg-驚鏵原文链接[1]:https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用.NET40;VisualStudio2019;CircularProgressBar继承ProgressB 查看详情

带有 Swift UI 的圆形进度条

...它的外观从未改变。我准备了2个文件。其中一个是关于倒计时程序的编码,另一个文件是关于UI的编码。我使用键@ObservableObject、@Public为过程代码和@Observed 查看详情

svg的圆形进度条(代码片段)

 目前发现svg实现一些动画效果是比较高效简单的。如圆形进度条,只要会stroke-dasharray与stroke-dashoffset属性基本就可以实现,而且美观。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Document</title 查看详情

delphi:圆形进度(环形进度)(代码片段)

...回DC5项目,资源下载美工提供圆形进度条,复习Delphi,为实现其颇觉有趣,遂研究其。最终效果图如下: 实现:制作TCircleProgress控件,实现方法参照系统之TGauge控件,CSDN上tp机器猫一个源码,结合GDI+绘制技术实现。设计控... 查看详情

javaswing圆形加载进度条(代码片段)

查看详情

ycprogress自定义百分比进度条(代码片段)

...设置内圆和外圆的颜色,设置圆环的边缘宽度。支持设置倒计时总时间,可以调用start开始倒计时,也可以调用stop暂停倒计时,也可以自定义设置进度仿杀毒类型百分比进度条支持设置多种类型,比如设 查看详情

html+css+js实现❤️canvas圆形水波进度条动画特效❤️(代码片段)

...留言📝  效果演示: 文末获取源码 主要代码实现:CSS样式 查看详情

html+css+js实现❤️canvas圆形水波进度条动画特效❤️(代码片段)

...留言📝  效果演示: 文末获取源码 主要代码实现:CSS样式 查看详情

酷炫进度条自定义seekbar(代码片段)

...当前进度值;4、并且圆形进度可滑动操作;最终实现效果:废话不多说上代码:水平的进度条ÿ 查看详情

微信小程序进度条详解progress自定圆形进度条(代码片段)

...ff0c;过好今天就好。在微信小程序开发中,progress用来实现水平进度条效果1基本使用<progresspercent="80"stroke-width="12"show-infocolor="pink"active/>效果就是如上图所示percent表示当前的进度stroke-width进度条... 查看详情

圆形百分比进度条效果(代码片段)

...前言前段时间我有个页面需要该效果,就在网上看了下,实现方式有好几种,我找了一种比较好实现的给大家一步步讲解。先放效果图:参考别人的链接:HTML+CSS实现环形比例图效果二、整体思路1.设置一个浅灰色的圆当背景,... 查看详情

composecanvas自定义圆形进度条(代码片段)

@ComposablefunCircleRing(boxWidthDp:Int,viewModel:TaskViewModel)Canvas(modifier=Modifier.size(boxWidthDp.dp),onDraw=valstrokWidth=30F//灰色背景drawArc(Color(0,0,0,15),startAngle=160f,s 查看详情

compose自定义条形进度条(代码片段)

...更方便简单,比如接下来本文要介绍的就是使用Compose实现View系统中常见的条形进度条。自定义进度条Composematerial包中提供了CircularProgressIndicator实现View系统中的圆形进度条,因为Compose没有现成的条形进度条,所以我... 查看详情

compose自定义条形进度条(代码片段)

...更方便简单,比如接下来本文要介绍的就是使用Compose实现View系统中常见的条形进度条。自定义进度条Composematerial包中提供了CircularProgressIndicator实现View系统中的圆形进度条,因为Compose没有现成的条形进度条,所以我... 查看详情

newuwpcommunitytoolkit-radialprogressbar(代码片段)

...rogressBar,本篇我们结合代码详细讲解 RadialProgressBar的实现。RadialProgressBar是一种圆形的进度条控件,进度值用圆形中的填充色的角度来表示,进度增长,填充色按照顺时针方向增加,直到占满整个圆形,则进度条达到最大值... 查看详情

android自定义控件篇圆形进度条(代码片段)

一、效果图二、代码逻辑/***funcation:圆形进度条控件*/publicclassCircleProgressViewextendsViewprivatePaintmBackPaint,mProgPaint;//绘制画笔privateRectFmRectF;//绘制区域privateint[]mColorArray;//圆环渐变色privateintmProgress;//圆环进度(0-100)publicCircleProgressView(Co... 查看详情