Canvas imitation sesame credit meter dial

Time:2021-7-4

Hi, this is a canvas imitation Alipay sesame credit score, in fact, is an animation dashboard.

First of all, the original picture:

Canvas imitation sesame credit meter dial

This is a screenshot of the next Alipay. Then look at the effect of my canvas implementation:

<canvas id="canvas" width="400" height="700" data-score='724'></canvas>
<!--  Set data score, score range [400, 900] -- >

Canvas imitation sesame credit meter dial

Well, it doesn’t feel like it. This is a GIF diagram. It may be better to open it on the web page(Of course, that could be it)。 You can click on the bottom to preview the demo on codepen. There are two imperfections. One is that the scale on the sesame credit dial is actually uneven. I use the same scale for simple implementation; Second, the movement of the dial point is a fuzzy effect, has not been solved. Well, let’s talk about it next time.

Next, let’s talk about how to achieve it. The first step is to create a canvas according to international practice

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    cWidth = canvas.width,
    cHeight = canvas.height;

Then draw the dial. Although it’s not Virgo, try to be the same as in the original picture. That’s the angle of the ring opening? Please go to PS to test:

Canvas imitation sesame credit meter dial

Well, 136 °, This angle is really tricky. For the convenience of the next calculation, it is about 140 °。 Then the radian of a fraction segment is:

var deg1 = Math.PI * 11 / 45

First, draw the middle translucent scale layer

ctx.save(); // Middle scale layer
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 255, 255, .2)';
ctx.lineWidth = 10;
ctx.arc(0, 0, 135, 0, 11 * deg0, false);
ctx.stroke();
ctx.restore();

Then, draw six scale lines and use the for loop to achieve the following:

ctx.save(); //  Tick marks
for (var i = 0; i < 6; i++) {
  ctx.beginPath();
  ctx.lineWidth = 2;
  ctx.strokeStyle = 'rgba(255, 255, 255, .3)';
  ctx.moveTo(140, 0);
  ctx.lineTo(130, 0);
  ctx.stroke();
  ctx.rotate(deg1);
}
ctx.restore();

Similarly, the large scale is subdivided into five small scales

ctx.save(); //  Subdivision tick mark
for (i = 0; i < 25; i++) {
  if (i % 5 !== 0){
    ctx.beginPath();
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'rgba(255, 255, 255, .1)';
    ctx.moveTo(140, 0);
    ctx.lineTo(133, 0);
    ctx.stroke();
  }
  ctx.rotate(deg1 / 5);
}
ctx.restore();

The scale is OK here. You also need to mark the text and the credit rating of each score segment on the scale. Please refer to the code for details, because it is similar to the principle of scale implementation, so it’s not wordy. Now the most important thing is to realize the moving point on the dial. We can think that it is a circle with a very small radius, which is just a circle drawn on the outermost circular orbit, and the circle is in the middlecanvasThe implementation method of this method is as follows:

ctx.arc(x, y, radius, sAngle, eAngle, false);

As long as we control X and y, we can make it move and achieve the effect we want. So, create a moving point object:

function Dot() {
  this.x = 0;
  this.y = 0;
  this.draw = function (ctx) {
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = 'rgba(255, 255, 255, .7)';
    ctx.arc(this.x, this.y, 3, 0, Math.PI * 2, false);
    ctx.fill();
    ctx.restore();
  };
}
var dot = new Dot(),
    Dotspeed = 0.03, // control the speed of the moving point
    Angle = 0, // this is the key to get the coordinates x, y of the moving point
    credit = 400; // Minimum credit score

How to get the coordinates x, y of dot? Then we need to use the legendary trigonometric function.

Canvas imitation sesame credit meter dial

From the picture above, we can see that

x = r * cos(angle), y = r * sin(angle)

In JavaScript, the center coordinates of dot become:

dot.x = radius * Math.cos(angle); // Radius is the radius of the outermost orbit
dot.y = radius * Math.sin(angle);

Next we just need to get this angle. This can be obtained by the proportional relationship between radian and fraction

var aim = (score - 400) * deg1 / 100;
if (angle < aim) {
  angle += dotSpeed;
}
dot.draw(ctx);

Then let the credit score in the middle also change with the rotation of the moving point to create a credit scoretext()In order to keep the digital change consistent with the moving point, the digital change should be calculated according to the speed of the moving point

function text(process) {
  ctx.save();
  ctx.rotate(10 * deg0);
  ctx.fillStyle = '#000';
  ctx.font = '80px Microsoft yahei';
  ctx.textAlign = 'center';
  ctx.textBaseLine = 'top';
  ctx.fillText(process, 0 ,10);
  ctx.restore();
}
var textSpeed = Math.round(dotSpeed * 100 / deg1),
if (credit < score - textSpeed) {
  credit += textSpeed;
} else if (credit >= score - textSpeed && credit < score) {
  credit += 1; //  Here's to make sure that the credit score that stops at the end is the score we entered
}
text(credit);

In the end, it’s impossible to let window. Requestanimationframe () control the animation and CTX. Clearrect (0, 0, cwidth, cheight) clear the canvas.

Writing is not good, you will see, I believe you understand the ability of the code must be better than understanding me these I do not know what to say the text.

Well, that’s all.

Codepen demo address

GitHub address