JavaScript canvas绘制动态圆环进度条

yizhihongxing

现在我来详细讲解如何通过 JavaScript canvas 绘制动态圆环进度条的完整攻略。

概述

原理:利用 <canvas> 标签绘制一个圆环,再通过控制圆环的起始弧度和结束弧度来实现进度条的动态效果。

需要掌握的知识:

  • HTML5 <canvas> 标签的使用
  • ctx.beginPath()、ctx.closePath()、ctx.arc() 方法的使用
  • setInterval() 方法的使用

步骤

第一步:创建HTML页面

在HTML页面中,我们需要构建一个 canvas元素,通过该元素完成我们的绘图任务:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>JavaScript canvas绘制动态圆环进度条</title>
    <style>
        canvas {
            display: block;
            margin: auto;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="200" height="200"></canvas>
</body>
</html>

代码解析:

  • <canvas> 标签是作为绘图容器出现的,除了 width 和 height 属性外,其他所有属性均为布尔型属性,都被默认为false。
  • 使用 CSS 样式将 canvas 元素居中。

第二步:绘制静态圆环

// 获取canvas元素
let canvas = document.getElementById('myCanvas');

// 获取绘图上下文
let ctx = canvas.getContext('2d');

// 根据canvas的大小计算圆的半径
let r = canvas.width / 2;

// 绘制背景圆
ctx.beginPath();
ctx.arc(r, r, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.strokeStyle = '#e1e1e1';
ctx.lineWidth = 10;
ctx.stroke();

// 绘制进度圆
ctx.beginPath();
ctx.arc(r, r, r, 0, 2 * Math.PI);
ctx.closePath();
ctx.strokeStyle = '#f00';
ctx.lineWidth = 10;
ctx.stroke();

代码解析:

  • getContext('2d') 方法返回一个绘图上下文对象,该对象拥有丰富的绘制方法。
  • 通过绘制两个重叠的圆形来实现圆环进度条的效果,第一个圆为背景色,第二个圆为进度条。
  • 圆环的宽度,可以通过 lineWidth 属性来控制。

第三步:绘制动态圆环

接下来,我们需要通过 JavaScript 控制圆环的起始弧度和结束弧度,从而实现动态的进度条效果。

// 设定初始弧度和结束弧度
let startAngle = -Math.PI /2;
let endAngle = -Math.PI /2;

// 设定绘制间隔(60帧每秒)
let speed = 60;

// 设定动画帧数
let frame = 0;

// 设定需要绘制的弧度
let arcs = Math.PI * 2 * 0.8;

// 执行动画
setInterval(function() {
    // 让弧度按速度增长
    endAngle = endAngle + Math.PI / (speed / 3);

    // 每帧动画弧度增加的大小
    let unitArc = arcs / (speed / 3);

    // 绘制
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 绘制背景圆
    ctx.beginPath();
    ctx.arc(r, r, r, 0, 2 * Math.PI);
    ctx.closePath();
    ctx.strokeStyle = '#e1e1e1';
    ctx.lineWidth = 10;
    ctx.stroke();

    // 绘制进度圆
    ctx.beginPath();
    ctx.arc(r, r, r, startAngle, endAngle);
    ctx.closePath();
    ctx.strokeStyle = '#f00';
    ctx.lineWidth = 10;
    ctx.stroke();

    // 更新起始弧度和结束弧度
    startAngle = startAngle + unitArc;
    frame++;
}, 1000 / speed);

代码解析:

  • 通过 setInterval 方法设定固定帧速度,使得每隔 1000/60 秒会执行一次绘制圆环的函数。
  • 动画的关键在于每帧增加的弧度,通过简单的计算得到一个逐渐递增的数量,从而实现动态展示的效果。
  • 在每一次动画之前,首先使用 clearRect 方法清空画布,避免出现残留的进度条。
  • 在绘制进度条的时候,起始弧度的值需要与结束弧度的值保持一致,这意味着,每次绘制都是在上一次的基础之上增加的,从而实现动态的效果。

示例

下面给出两个绘制动态圆环进度条的示例,可以帮助更好的理解动态圆环的实现方法。

示例1

本例在动态圆环进度条外围绘制了一个文字,该文字能够随进度条的进度进行变动。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>示例1 - JavaScript canvas绘制动态圆环进度条</title>
    <style>
        canvas {
            display: block;
            margin: auto;
        }

        #percent {
            font-size: 30px;
            font-weight: bold;
            text-align: center;
            margin-top: -75px;
            color: #000;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="300" height="300"></canvas>
    <div id="percent">0%</div>
    <script>
        // 获取canvas元素
        let canvas = document.getElementById('myCanvas');

        // 获取绘图上下文
        let ctx = canvas.getContext('2d');

        // 根据canvas的大小计算圆的半径
        let r = canvas.width / 2;

        // 设定初始弧度和结束弧度
        let startAngle = -Math.PI /2;
        let endAngle = -Math.PI /2;

        // 设定绘制间隔(60帧每秒)
        let speed = 60;

        // 设定动画帧数
        let frame = 0;

        // 设定需要绘制的弧度
        let arcs = Math.PI * 2 * 0.8;

        // 执行动画
        setInterval(function() {
            // 让弧度按速度增长
            endAngle = endAngle + Math.PI / (speed / 3);

            // 每帧动画弧度增加的大小
            let unitArc = arcs / (speed / 3);

            // 更新百分比显示
            let percent = Math.round((endAngle + Math.PI / 2) / (Math.PI * 2) * 100) + '%';
            document.getElementById('percent').innerHTML = percent;

            // 绘制
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // 绘制背景圆
            ctx.beginPath();
            ctx.arc(r, r, r, 0, 2 * Math.PI);
            ctx.closePath();
            ctx.strokeStyle = '#e1e1e1';
            ctx.lineWidth = 10;
            ctx.stroke();

            // 绘制进度圆
            ctx.beginPath();
            ctx.arc(r, r, r, startAngle, endAngle);
            ctx.closePath();
            ctx.strokeStyle = '#f00';
            ctx.lineWidth = 10;
            ctx.stroke();

            // 更新起始弧度和结束弧度
            startAngle = startAngle + unitArc;
            frame++;
        }, 1000 / speed);
    </script>
</body>
</html>

代码解析:

  • 相对于基本版示例,本例唯一的区别在于增加了一个 div 元素,用于显示当前进度条的进度,元素样式方便修改。
  • 在每次绘制的时候,动态地更新 div 元素中的文字,向用户展示当前进度条的具体进度。

示例2

本例在动态圆环进度条外围绘制了一个带有动画的箭头,该箭头能够随进度条的进度进行旋转,并且指向进度条的当前位置。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>示例2 - JavaScript canvas绘制动态圆环进度条</title>
    <style>
        canvas {
            display: block;
            margin: auto;
        }

        #arrow {
            position: relative;
            width: 100%;
            height: 100%;
        }

        #arrow img {
            position: absolute;
            left: 50%;
            top: 50%;
            transform-origin: left center;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="300" height="300"></canvas>
    <div id="arrow">
        <img src="arrow.png" alt="">
    </div>
    <script>
        // 获取canvas元素
        let canvas = document.getElementById('myCanvas');

        // 获取绘图上下文
        let ctx = canvas.getContext('2d');

        // 根据canvas的大小计算圆的半径
        let r = canvas.width / 2;

        // 设定初始弧度和结束弧度
        let startAngle = -Math.PI /2;
        let endAngle = -Math.PI /2;

        // 设定绘制间隔(60帧每秒)
        let speed = 60;

        // 设定动画帧数
        let frame = 0;

        // 设定需要绘制的弧度
        let arcs = Math.PI * 2 * 0.8;

        // 获取箭头
        let arrow = document.getElementById('arrow').getElementsByTagName('img')[0];

        // 执行动画
        setInterval(function() {
            // 让弧度按速度增长
            endAngle = endAngle + Math.PI / (speed / 3);

            // 每帧动画弧度增加的大小
            let unitArc = arcs / (speed / 3);

            // 更新百分比显示
            let percent = Math.round((endAngle + Math.PI / 2) / (Math.PI * 2) * 100);

            // 绘制
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // 绘制背景圆
            ctx.beginPath();
            ctx.arc(r, r, r, 0, 2 * Math.PI);
            ctx.closePath();
            ctx.strokeStyle = '#e1e1e1';
            ctx.lineWidth = 10;
            ctx.stroke();

            // 绘制进度圆
            ctx.beginPath();
            ctx.arc(r, r, r, startAngle, endAngle);
            ctx.closePath();
            ctx.strokeStyle = '#f00';
            ctx.lineWidth = 10;
            ctx.stroke();

            // 绘制箭头
            arrow.style.transform = `rotate(${percent / 100 * 360 + 90}deg)`;

            // 更新起始弧度和结束弧度
            startAngle = startAngle + unitArc;
            frame++;
        }, 1000 / speed);
    </script>
</body>
</html>

代码解析:

  • 相对于基本版示例,本例唯一的区别在于增加了一个 div 元素,并在该元素内部绘制了一个带有动画的箭头。
  • 箭头的动态旋转效果是通过设置 transform 属性中的 rotate 值来实现的,在每次更新进度条的时候,调整 rotate 的值,即可实现箭头的动态旋转效果。
  • 注意,需要设置 transform-origin 属性,将旋转点设置为箭头的左端中点。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript canvas绘制动态圆环进度条 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • Javascript Date toString() 方法

    以下是关于JavaScript Date对象的toString()方法的完整攻略,包括两个示例说明。 JavaScript Date对象的toString()方法 JavaScript的toString()方法返回一个表示日期时间部分的字符串,该字符串格式根据国际标准时间(UTC)而定。该方法不接受任何参数。 下面是使用对象的toString()方法的示例:…

    JavaScript 2023年5月11日
    00
  • javascript 函数调用的对象和方法

    JavaScript 函数调用的对象和方法是 JavaScript 中一个非常重要的概念,理解这个概念对于编写高质量的 JavaScript 代码非常有帮助。下面,我将为您详细讲解 JavaScript 函数调用的对象和方法。 函数调用的对象 JavaScript 函数可以作为另一个对象的属性值使用,这时候函数称为该对象的一个方法。在调用该方法时,方法内的关…

    JavaScript 2023年5月27日
    00
  • Bootstrap中表单控件状态(验证状态)

    Bootstrap是一款流行的前端框架,它提供了丰富的表单控件状态(验证状态)来帮助开发者快速构建现代化的Web表单。本篇攻略将详细讲解Bootstrap中表单控件状态的使用方法。 表单控件状态分类 在Bootstrap中,表单控件的状态共分为以下四种: 默认状态 成功状态 警告状态 错误状态 使用方法 默认状态 表单控件默认状态不需要特殊设置,只需要按照B…

    JavaScript 2023年6月10日
    00
  • 正则基础之 捕获组(capture group)

    正则基础之 捕获组(capture group) 介绍 在正则表达式中,捕获组是一个由括号包围的子表达式。在使用正则表达式匹配字符串时,可以通过捕获组从匹配到的字符串中提取想要的部分。 捕获组可以使用圆括号中的数字引用到,如果有多个捕获组,可以通过捕获组的序号来区分哪一个捕获组是被引用的。除了序号之外,也可以给捕获组设置名字,用于更清晰、方便的引用。 示例 …

    JavaScript 2023年6月10日
    00
  • JavaScript定时器setTimeout、setInterval使用详解

    JavaScript定时器setTimeout、setInterval使用详解 在 JavaScript 中,定时器是一种非常有用的功能,它可以让你在一定时间后执行一些操作。其中,setTimeout 和 setInterval 是两种最常用的定时器,本文将详细解释它们的使用方法。 setTimeout setTimeout 函数可以让你在指定的时间后执行一…

    JavaScript 2023年6月11日
    00
  • 弱类型语言javascript开发中的一些坑实例小结【变量、函数、数组、对象、作用域等】

    弱类型语言JavaScript开发中的一些坑实例小结 JavaScript作为一门弱类型语言,存在着许多在开发过程中容易出现的坑。在本篇攻略中,我们将重点介绍在JavaScript开发中常见的一些坑,并且提供一些实例来帮助你更好地理解这些坑及其解决方法。本攻略的主要内容包括:变量、函数、数组、对象、作用域等。 变量 在JavaScript中,变量的声明、赋值…

    JavaScript 2023年5月18日
    00
  • 获取HTML DOM节点元素的方法的总结

    获取HTML DOM节点元素的方法有很多,常见的有通过ID、class、标签名称、属性等方式来获取节点。下面,我们来总结一下。 通过ID获取节点 通过ID获取节点是最常见的一种方式,我们可以使用getElementById()方法,该方法接收一个参数——需要获取的节点的ID,返回值为对应的节点对象,如果获取不到则返回null。示例代码如下: <!– …

    JavaScript 2023年6月10日
    00
  • Javascript和Ajax中文乱码吐血版解决方案

    以下是“Javascript和Ajax中文乱码吐血版解决方案”的完整攻略。 问题背景 在使用Javascript和Ajax编写中文网站时,可能会出现中文乱码的问题,导致网站无法正常显示中文内容。这是因为Javascript和Ajax默认使用的是UTF-8编码,而服务器返回的数据可能是其他编码方式,例如GB2312编码。如果两种编码方式不一致,就会出现中文乱码…

    JavaScript 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部