Hallo, das ist eine Leinwand, die den Sesame Credit Score von Alipay imitiert. Es ist eigentlich ein animiertes Dashboard.
Zuerst das Originalbild oben:
Dies ist ein Screenshot auf Alipay. Der niedrige Punktestand bringt Sie zum Lachen. Dann schauen Sie sich die Renderings an, die ich mit Canvas erreicht habe:
<canvas id="canvas" width="400" height="700" data-score='724'></canvas> <!-- 设置data-score,分数区间[400, 900] -->
Oh, es fühlt sich nicht so an. Dies ist ein GIF-Bild, und der Effekt ist möglicherweise besser, wenn es auf einer Webseite geöffnet wird (das kann natürlich der Fall sein). Sie können unten klicken, um eine Vorschau der Demo auf Codepen anzuzeigen. Es gibt zwei Unvollkommenheiten: Zum einen ist die Skala auf dem Sesame Credit-Zifferblatt tatsächlich ungleichmäßig, zum anderen haben die beweglichen Punkte auf dem Zifferblatt einen unscharfen Effekt. Oh, lass uns das nächste Mal darüber reden.
Lassen Sie uns als Nächstes darüber sprechen, wie Sie dies erreichen können. Der erste Schritt, internationale Praxis, besteht darin, eine Leinwand zu erstellen:
var canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d'), cWidth = canvas.width, cHeight = canvas.height;
Dann zeichnen Sie das Zifferblatt. Obwohl es sich nicht um eine Jungfrau handelt, sollte es so gut wie möglich mit dem Originalbild übereinstimmen Wie groß ist der Winkel der ringförmigen Öffnung? Bitte gehen Sie zu PS, um ihn zu messen:
Nun, 136°, dieser Winkel ist wirklich knifflig. Um die spätere Berechnung zu erleichtern, entspricht er ungefähr 140°. Dann ist der Bogen eines Bruchsegments:
var deg1 = Math.PI * 11 / 45
Zeichnen Sie zuerst die halbtransparente Skalenebene in der Mitte:
ctx.save(); //中间刻度层 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();
Zeichnen Sie dann 6 Skalenlinien und verwenden Sie eine for-Schleife um dies zu erreichen. :
ctx.save(); // 刻度线 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();
Unterteilen Sie den großen Maßstab ebenfalls in 5 kleine Maßstäbe:
ctx.save(); // 细分刻度线 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();
Der Maßstab ist auch hier in Ordnung. Sie müssen den Maßstab auch mit Text markieren Einzelheiten zum Kreditniveau jedes Teilsegments finden Sie im Code. Da es dem Prinzip der Skalenimplementierung ähnelt, werde ich nicht näher darauf eingehen. Das Wichtigste ist jetzt, den beweglichen Punkt auf dem Zifferblatt zu erkennen (ich weiß nicht, wie ich ihn nennen soll, deshalb nenne ich ihn unten den beweglichen Punkt. Wir können es uns so vorstellen, es ist ein Kreis mit a). Sehr kleiner Radius, der nur ein Kreis ist, der auf der äußersten Ringschiene gezeichnet wird, und die Methode zum Realisieren des Kreises auf der Leinwand ist:
ctx.arc(x, y, radius, sAngle, eAngle, false);
Wir müssen nur x und y steuern, um ihn zu bewegen und den gewünschten Effekt erzielen. Erstellen Sie also ein bewegliches Punktobjekt:
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, //控制动点的速度 angle = 0, //这个很关键,用来得到动点的坐标x, y credit = 400; //信用最低分数
Wie erhalte ich die Koordinaten x, y des Punktes? Dann müssen wir die legendären trigonometrischen Funktionen verwenden.
Durch das obige Bild können wir
x = r * cos(angle), y = r * sin(angle)
In JavaScript werden die Mittelpunktskoordinaten des Punkts zu:
dot.x = radius * Math.cos(angle); //radius为最外层轨道的半径值 dot.y = radius * Math.sin(angle);
Als nächstes müssen wir nur noch diesen Winkel ermitteln. Dies kann durch die proportionale Beziehung zwischen Bogenmaß und Punktzahl erhalten werden:
var aim = (score - 400) * deg1 / 100; if (angle < aim) { angle += dotSpeed; } dot.draw(ctx);
Lassen Sie dann die mittlere Kreditpunktzahl mit der Drehung des beweglichen Punktes ändern, erstellen Sie einen Text(), um die numerischen Änderungen vorzunehmen konsistent mit dem sich bewegenden Punkt Die Punkte müssen konsistent sein und die numerischen Änderungen müssen basierend auf der Geschwindigkeit der sich bewegenden Punkte berechnet werden:
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; // 这里确保信用分数最后停下来是我们输入的分数 } text(credit);
Letztendlich kann all dies nicht durch Zulassen von Fenstern umgangen werden. requestAnimationFrame() steuert die Zeichenanimation und ctx.clearRect(0, 0, cWidth, cHeight) löscht die Leinwand.
Wenn der Text nicht gut ist, muss jeder ihn sich ansehen. Ich glaube, dass die Fähigkeit jedes Einzelnen, den Code zu verstehen, besser sein muss, als meine Worte zu verstehen, wenn ich nicht einmal weiß, was ich sagen soll.