最近需要搞一个仪表盘动态更新的功能,新改版风格的UI表盘都不适用只有自己画了。
先上效果图:
canvas坐标系:左上角的点为0.0 右下角的点为 width,height, 与之前我们学习的坐标系不同
cans.arc(x,y,r,0,Math.PI,1);
圆的中心的 x 坐标。
y 圆的中心的 y 坐标。
r 圆的半径。
sAngle 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。
eAngle 结束角,以弧度计。
counterclockwise 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。
ctx.fillText("textAlign=center",150,120); 实心字体
ctx.strokeText("Sample String", x0-text.width/2, y0-30) 空心字体
2.如何画一个半圆?
思路就是:其实角度为Math.PI ,结束角度为0,或者2Math.PI ,效果都是一样的,确定好了开始结束角度就能简单的画一个半圆
3.如何画一个指针的尖尖的三角?
思路就是先画一个宽一点的线段,根据线宽的一半来确定上下浮动的角度。
一个圆周是360.周长是2*Math.PI*R ,所以确定上下的浮动角度=2*Math.PI*R *360*线宽/2
再根据起始角度的不同算出来不同的坐标,先左下,在lineto到顶点,linto到第二点就可以实现
4.
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- </head>
-
- <body>
- <canvas id="mycanvas" class="mycanvas" width="338" height="168"></canvas>
- </body>
-
- <script>
- /**
- * 圆的中心的 x 坐标。
- y 圆的中心的 y 坐标。
- r 圆的半径。
- sAngle 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。
- eAngle 结束角,以弧度计。
- counterclockwise 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。
- ctx.lineTo(lineEndX,lineEndY);
- ctx.lineTo(angEndX,angEndY);
- ctx.fill();
- // 线条末端线帽的设置为圆形
- ctx.lineCap = 'round';
- let differ = 4.6/2/Math.PI/ange3*360
- ctx.fillText("textAlign=center",150,120); 实心字体
- ctx.strokeText("Sample String", x0-text.width/2, y0-30) 空心字体
- * @type {number}
- */
-
- var canvas = document.getElementById('mycanvas');
- const x0 = canvas.width/2; // 圆心坐标
- const y0 = canvas.height; // 圆心坐标
- const r1 = (x0 / 2 - 16) * 2 // 外圆半径
- const r2 = (x0 / 2 - 30) * 2 // 内圆半径
- const ange3 = (x0 / 2 - 20) * 2 // 线段终止的地方
- const startAng = 180; // 起始角度
- const curSpeedTex ="实时速率(Mbps)";
- let curSpeed = Math.floor(Math.random() *3500);
- const maxSpeed =3500;
- let targetAng = curSpeed/maxSpeed*180+startAng; // 起始角度
- function getPointX(r, ao) {
- return x0 + r * Math.cos(ao * Math.PI / 180)
- }
-
- function getPointY(r, ao) {
- return y0 + r * Math.sin(ao * Math.PI / 180)
- }
-
- var ctx = canvas.getContext("2d");
- ctx.beginPath();
- var img = new Image();//创建img元素
- img.onload = function(){
- // 参数 1:要绘制的 img 参数 2、3:绘制的 img 在 canvas 中的坐标 参数4,5是width,height
- console.log("img.width="+img.width+",img1.height="+img.height);
- ctx.drawImage(img,0,0,img.width,img.height);
- }
- img.src = 'yibiaopan.png';//设置图片源地址
- ctx.fillStyle="#FEB95A";
- // 获取大圆上的点 与 边界圆交点
- let lineStartX = this.getPointX(r2, targetAng);
- let lineStartY = this.getPointY(r2, targetAng);
- // 获取小圆上的点 与 边界圆交点
- let lineEndX = this.getPointX(r1, targetAng);
- let lineEndY = this.getPointY(r1, targetAng);
- let angX = this.getPointX(ange3, targetAng);
- let angY = this.getPointY(ange3, targetAng);
- ctx.beginPath();
- ctx.moveTo(lineStartX, lineStartY);
- ctx.lineWidth = 5;
- ctx.lineCap = 'round';
- ctx.strokeStyle = '#FEB95A';
- ctx.lineTo(angX,angY);
- ctx.stroke();
-
- // 根据线的宽度确定小三角的开始坐标的偏移角度
- let differ = 2.8/2/Math.PI/ange3*360
-
- // 确定左下的坐标
- let angStartX = this.getPointX(ange3, targetAng-differ);
- let angStartY = this.getPointY(ange3, targetAng-differ);;
-
- let angEndX = this.getPointX(ange3, targetAng+differ);
- let angEndY = this.getPointY(ange3, targetAng+differ) ;
- ctx.moveTo(angStartX, angStartY);
- ctx.lineWidth = 1;
- ctx.lineTo(lineEndX,lineEndY);
- ctx.lineTo(angEndX,angEndY);
- ctx.fill();
- ctx.stroke();
- ctx.strokeStyle = '#FEB95A';
- ctx.save();
- ctx.fillStyle="#00FFDC";
- // 写文字
- ctx.font = "28px Verdana"
-
- // 确定文字长度,文字一半的位置刚好可以居中
- var text = ctx.measureText(curSpeed)
- console.log("text="+text.width+",text.height"+text.height);
- ctx.fillText(curSpeed,x0-text.width/2, y0-45);
- ctx.restore();
- ctx.fillStyle="#FFF";
- ctx.font = "16px Verdana"
- // 实时速率的文字
- var curspeed_text = ctx.measureText(curSpeedTex);
- ctx.fillText(curSpeedTex,x0-curspeed_text.width/2, y0-14);
-
- ctx.closePath();
- </script>
-
- <style>
- .mycanvas{
-
- background-color:#232228;
- }
- </style>
-
- </html>