JavaScript canvas绘制动态圆环进度条

现在我来详细讲解如何通过 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 String 的扩展方法集合

    下面是关于“javascript String 的扩展方法集合”的完整攻略。 标准的 String 方法 JavaScript 中的 String 拥有许多标准的方法,例如 charAt()、substr()、slice()、toUpperCase() 等等。这些方法可以在 MDN 上找到详细的文档说明和使用示例。 扩展的 String 方法 除了标准的方法…

    JavaScript 2023年5月27日
    00
  • JavaScript find()方法及返回数据实例

    下面是关于JavaScript中find()方法及返回数据的完整攻略,包括方法的介绍、语法、参数、返回值和示例说明。 find()方法介绍 JavaScript中的find()方法是ES6中新增加的数组方法之一,用于返回符合条件的第一个数组元素,如果没有符合条件的元素则返回undefined。 find()方法的语法 array.find(function(…

    JavaScript 2023年5月28日
    00
  • Js操作DOM元素及获取浏览器高宽的简单方法

    Js操作DOM元素及获取浏览器高宽的简单方法的攻略如下: 操作DOM元素 选择元素 在Javascript中,选择DOM元素是很重要的一步。有很多方法可以选择DOM元素,但是最常用的方法是使用document.querySelector和document.querySelectorAll这两个方法。 document.querySelector方法返回一个与…

    JavaScript 2023年6月10日
    00
  • 详解JS中的this、apply、call、bind(经典面试题)

    详解JS中的this、apply、call、bind(经典面试题) 在Javascript中,this、apply、call、bind都是常见的关键字。它们在面试过程中也往往是必问的问题,因为它们对于Javascript的理解非常关键,而且使用得好能够使代码更加简洁高效。本文将会详细讲解它们的含义和用法。 this this是Javascript中非常重要的…

    JavaScript 2023年6月10日
    00
  • JS获取并操作iframe中元素的方法

    JS获取并操作iframe中元素的方法可以分为以下几个步骤: 通过document.getElementById()获取iframe元素的引用。例如,若iframe元素的id为“myFrame”,则用下列代码获取它的引用: var myFrame = document.getElementById(‘myFrame’); 使用contentWindow属性获…

    JavaScript 2023年6月10日
    00
  • js截取字符串的两种方法及区别详解

    当我们需要在JavaScript中处理字符串时,常常需要对字符串进行截取。本篇攻略将会详细讲解js截取字符串的两种方法及其区别。 一、JavaScript中substring()方法 let str = "hello world"; let strNew = str.substring(3); console.log(strNew); 上…

    JavaScript 2023年5月28日
    00
  • javascript按钮禁用和启用的效果实例代码

    下面我将详细讲解“JavaScript按钮禁用和启用的效果实例代码”的完整攻略。 禁用按钮 原理:使用disabled属性禁用按钮。 示例代码 HTML代码: <button id="myBtn">提交</button> JavaScript代码: var myBtn = document.getElementBy…

    JavaScript 2023年6月10日
    00
  • JavaScript定义数组的三种方法(new Array(),new Array(‘x’,’y’)

    下面我来详细讲解JavaScript定义数组的三种方法。 一、使用数组字面量 使用数组字面量定义数组最简单,也是最常用的方法。语法如下: let arr = [item1, item2, …, itemN]; 其中,item1至itemN表示数组中的每个元素。这些元素可以是任意类型的,包括数字、字符串甚至还可以是其他数组。 示例: let arr = […

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