用H5 Canvas绘制一个仪表盘笔记
前端有许多做数据可视化的图表插件,但有时候UI设计的图可能用现成的js插件无法定制或者比较麻烦(还不如自己造轮子来的快)。
下面记录下用H5 canvas设计一个仪表盘代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Document</title>
<script src="tween.umd.min.js"></script>
<style>
.container {
position: absolute;
top: 40px;
left: 100px;
width: 138px;
height: 138px;
display: flex;
align-items: center;
justify-content: center;
} #bg, #ring {
position: absolute;
width: 138px;
height: 138px;
} #bg {
background-color: #fff;
} </style>
</head>
<body style="background-color: #ccc">
<div class="container">
<div id="percent" style="z-index: 100; color: #fff;">0%</div>
<canvas id="bg" width="138" height="138"></canvas>
<canvas id="ring" width="138" height="138"></canvas>
</div>
</body>
<script>
const bgCanvas = document.querySelector('#bg');
const ringCanvas = document.querySelector('#ring');
const bgCtx = bgCanvas.getContext('2d');
const ctx = ringCanvas.getContext('2d');
const percentEl = document.querySelector('#percent'); const pixelRatio = window.devicePixelRatio;
const BG_RING_WIDTH = 6;
const POINTER_BALL_RADIUS = 6;
const CANVAS_WIDTH = 138;
const CANVAS_HEIGHT = 138;
const INNER_CIRCLE_RADIUS = 45; if(pixelRatio > 1) {
bgCanvas.width = CANVAS_WIDTH * 2;
bgCanvas.height = CANVAS_HEIGHT * 2;
ringCanvas.width = CANVAS_WIDTH * 2;
ringCanvas.height = CANVAS_HEIGHT * 2;
bgCanvas.style.width = CANVAS_WIDTH;
bgCanvas.style.height = CANVAS_HEIGHT;
ringCanvas.style.width = CANVAS_WIDTH;
ringCanvas.style.height = CANVAS_HEIGHT;
} function createBgCircle() {
bgCtx.save();
bgCtx.beginPath();
bgCtx.arc(CANVAS_WIDTH / 2, CANVAS_HEIGHT / 2, INNER_CIRCLE_RADIUS, 0, 2 * Math.PI);
let gradient = bgCtx.createLinearGradient(INNER_CIRCLE_RADIUS * 2, 0, 0, INNER_CIRCLE_RADIUS * 2);
gradient.addColorStop(0, '#E69908');
gradient.addColorStop(1, '#FDF27B');
bgCtx.fillStyle = gradient;
bgCtx.fill();
bgCtx.restore();
} function createBgRing() {
bgCtx.save();
bgCtx.beginPath();
const x = CANVAS_WIDTH / 2;
const y = r = x;
bgCtx.arc(x, y, r, 0, 2 * Math.PI, true);
bgCtx.arc(x, y, x - BG_RING_WIDTH, 0, 2 * Math.PI, false);
bgCtx.fillStyle = '#EEF5F5';
bgCtx.fill();
bgCtx.restore();
} let imageLoaded = false;
let img = null; async function createProcessRing(radian) {
const x = CANVAS_WIDTH / 2;
const y = r = x;
//裁剪扇形区域
ctx.save();
ctx.beginPath();
ctx.moveTo(x, y);
ctx.arc(x, y, r, -Math.PI/2, -Math.PI/2 + radian);
ctx.clip(); if(imageLoaded) {
ctx.drawImage(img, 0, 0, img.width, img.height);
ctx.restore();
return;
} return new Promise(resolve => {
const imgUrl = "ring.png";
img = new Image();
img.src = imgUrl;
img.onload = function() {
imageLoaded = true;
ctx.drawImage(img, 0, 0, img.width, img.height);
ctx.restore();
resolve();
}
})
} function createBallPointer(x, y) {
const cx = CANVAS_WIDTH / 2;
const cy = cx;
ctx.save();
ctx.translate(cx, cy);
ctx.beginPath();
ctx.arc(x, y, POINTER_BALL_RADIUS, 0, 2 * Math.PI);
let gradient = ctx.createLinearGradient(0, POINTER_BALL_RADIUS * 2, POINTER_BALL_RADIUS * 2, 0);
gradient.addColorStop(0, '#FF8B00');
gradient.addColorStop(1, '#F2C008');
ctx.fillStyle = gradient;
ctx.fill();
ctx.restore();
} function createAnimation(startAngle = 0, endAngle = 360, callback) {
function animate(time) {
requestAnimationFrame(animate)
TWEEN.update(time)
}
requestAnimationFrame(animate) const p = {angle: startAngle}
const tween = new TWEEN.Tween(p)
.to({angle: endAngle}, 600)
.easing(TWEEN.Easing.Quadratic.Out)
.onUpdate(() => {
let radian = Math.PI / 180 * p.angle;
let x = (CANVAS_WIDTH / 2 - BG_RING_WIDTH) * Math.cos(Math.PI/2 - radian);
let y = -(CANVAS_HEIGHT / 2 - BG_RING_WIDTH) * Math.sin(Math.PI/2 - radian);
ctx.clearRect(0, 0, ringCanvas.width, ringCanvas.height);
createProcessRing(radian);
createBallPointer(x, y);
percentEl.innerText = Math.round(p.angle / 360 * 100) + '%';
})
.start();
} async function setup() {
createBgCircle();
createBgRing();
await createProcessRing();
createBallPointer(0, -(CANVAS_WIDTH / 2 - BG_RING_WIDTH/2));
createAnimation(0, 360);
} setup(); </script>
</html>
效果:
用H5 Canvas绘制一个仪表盘笔记的更多相关文章
- H5 canvas绘制出现模糊的问题
在之前做移动端小游戏幸运转盘.九宫格转盘,使用到了 canvas ,也是第一次在项目中使用 canvas 来实现. 近期测试人员反应 canvas 绘制的内容太模糊,心想着用 canvas 绘制出来的 ...
- 使用canvas绘制一个时钟
周末学习canvas的一些基础功能,顺带写了一个基础的时钟.现在加工一下,做的更好看一点,先放上效果图: 谈一些自己的理解: (1).要绘制一个新的样式(不想被其他样式影响,或者影响到其他样式),那么 ...
- HTML5 在canvas绘制一个矩形
笔者:本笃庆军 原文地址:http://blog.csdn.net/qingdujun/article/details/32930501 一.绘制矩形 canvas使用原点(0,0)在左上角的坐标系统 ...
- Canvas绘制一个大鱼喂小鱼的游戏
Canvas是HTML5中的一部分,强大的API足以让我们绘制我们任意想绘制的东西.利用Canvas的基础学习以及JavaScript面向对象的思想绘制一个小游戏,下面是源码地址https://git ...
- 用canvas绘制一个简易时钟
在见识了html5中canvas的强大,笔者准备制作一个简易时钟. 下面就是成果啦,制作之前我们先分析一下,绘制一个时钟需要做哪些准备. 一 . 1.首先这个时钟分为表盘,指针(时针,分针,秒针)和数 ...
- 用canvas绘制一个时钟
实现一个时钟的绘制和时间的显示 一,首先是页面的搭建html部分以及一点点的css代码,因为css这块用的比较少,所以就没有单独出来: <!DOCTYPE html> <html l ...
- 使用H5 canvas画一个坦克
具体步骤如下: 1. 首先做出绘图区,作为坦克的战场 <canvas id="floor" width="800px" height=&quo ...
- Canvas 绘制一个像素风电子时钟
想法是在 Canvas 上绘制由小方块组成的数字. 第一步是实现绘制小方块的方法,先画出一个边长为 5 的 10x10 个方块,使用两个 for 循环很简单就能完成. for (let i = 0; ...
- 没事用html5 canvas画一个仪表盘自用,自适应的哦
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Canvas绘制图形
1.Canvas绘制一个蓝色的矩形 <!DOCTYPE html> <html> <head lang="en"> <meta chars ...
随机推荐
- JZOJ.4724 斐波那契
\(\text{Problem}\) \(\text{Solution}\) \(\text{Fibonacci}\) 数列有一个性质:若 \(H_1=a,H_2=b,H_n=H_{n-2}+H_{n ...
- Hbase学习三:Hbase常用命令总结
转载请注明出处: 1.Hbase连接 1.1.进入hbase命令行 hbase shell # 或 bin/hbase shell 1.2.查看帮助 help 1.3.查看所有表 list 2.表操作 ...
- SpringBoot2.6.x及以上版本整合swagger文档
SpringBoot的版本更新中引入了一些新的特性,并且Swagger的版本更新也同样引入了很多新的东西,这样就造成了许多配置无法实现一一对应的情况,因此高版本的SpringBoot集成Swagger ...
- observObservableCollection改变model属性UI不更新
使模型类实现INotifyPropertyChanged即可 public class ResDepartmentData : INotifyPropertyChanged { //需要更新UI的属性 ...
- 若依-更换数据库-sqlite
基础 我是在ruoyi-vue已经安装了mybatis-plus的基础上进行的修改 关于SQLite SQLite 是一个软件库,实现了自给自足的.无服务器的.零配置的.事务性的 SQL 数据库引擎. ...
- 【PyCharm】配置 Git
一.前提条件 本地先安装好:PyCharm 和 Git 二.操作步骤 1.打开 File -> Settings -> Version Control -> Git,在 Path t ...
- css 网页置灰
body *{ -webkit-filter: grayscale(100%); /* webkit */ -moz-filter: grayscale(100%); /*firefox*/ -ms- ...
- (app笔记)Appium如何开启、配置、启用
1.安装adb 2.打开手机调试 3.连接手机 4.appium运行前,手机需要io.appium.uiautomator2.server 和 Appium Settings. 5.appium操作: ...
- ubuntu安装cuda、cudnn和nvidia-docker
目录 安装前的工作 要安装的cuda和cudnn版本说明 安装cuda 检查cuda的安装情况 安装cudnn 安装nvidia-docker 在红米book14上的实践 本文参考自Ubuntu18. ...
- Linux系统Shell脚本第五章:shell数组、正则表达式及文件三剑客之AWK
目录 一.shell数组 1.数组分类 2.定义数组方法 二.正则表达式 1.元字符 2.表示次数 3.位置锚定 4.分组 5.扩展正则表达式 三.文本三剑客之AWK 1.awk 2.使用格式 3.处 ...