HTML5 Canvas Speedometer

ネットワークには、速度計を作成するいくつかの同様の例がありますが、私はあなたと私のものを共有することにしました。



画像



最初に、DOMでキャンバスオブジェクトを作成する必要があります。



<canvas id="canvas" width="500" height="500"></canvas>
      
      





インラインスタイルの記述は罪ですが、キャンバスの幅と高さをcssで設定すると、多くの問題に直面します。さらに正確に言えば、うまくいきません。 次に、スクリプトに直接移動します。 最初に、2Dコンテキストを取得する必要があります。これを使用して作業を続けます。



 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d");
      
      





以下は、計算に必要な一連の設定です。 キャンバスの幅を基準にしてすべての寸法値を計算します。 したがって、キャンバスのサイズを変更しても、速度計の比率は変わりません



 // general settings var middleX = canvas.width / 2; var middleY = canvas.height / 2; var radius = canvas.width / 2 - canvas.width / 10; // beginning and ending of our arc. Sets by rad * pi var startAngleIndex = 0.7; var endAngleIndex = 2.3; // zones settings var zoneLineWidth = canvas.width / 30; var counterClockwise = false; // ticks settings var tickWidth = canvas.width / 100; var tickColor = "#746845"; var tickOffsetFromArc = canvas.width / 40; // Center circle settings var centerCircleRadius = canvas.width / 20; var centerCircleColor = "#efe5cf"; var centerCircleBorderWidth = canvas.width / 100; // Arrow settings var arrowValueIndex = 1.29; var arrowColor = "#464646"; var arrowWidth = canvas.width / 50; // Digits settings var digits = [0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240]; var digitsColor = "#746845"; var digitsFont = "bold 20px Tahoma"; var digitsOffsetFromArc = canvas.width / 12; var zonesCount = digits.length - 1; var step = (endAngleIndex - startAngleIndex) / zonesCount;
      
      





変数startAngleIndexおよびendAngleIndex について詳しく説明します。 そのような価値がどこから来たのかをよりよく理解するために、 www.html5canvastutorials.comから撮影した写真を示します。



画像



次に、キャンバスに速度計要素を描画するいくつかのメソッドを実装します。



 var DrawZones = function() { var greenZonesCount = Math.ceil(zonesCount / 2); var yellowZonesCount = Math.ceil((zonesCount - greenZonesCount) / 2); var redZonesCount = zonesCount - greenZonesCount - yellowZonesCount; var startAngle = (startAngleIndex - 0.02) * Math.PI; var endGreenAngle = (startAngleIndex + greenZonesCount * step) * Math.PI; var endYellowAngle = (startAngleIndex + (greenZonesCount + yellowZonesCount) * step) * Math.PI; var endRedAngle = (endAngleIndex + 0.02) * Math.PI; var sectionOptions = [ { startAngle: startAngle, endAngle: endGreenAngle, color: "#090" }, { startAngle: endGreenAngle, endAngle: endYellowAngle, color: "#cc0" }, { startAngle: endYellowAngle, endAngle: endRedAngle, color: "#900" } ]; this.DrawZone = function(options) { ctx.beginPath(); ctx.arc(middleX, middleY, radius, options.startAngle, options.endAngle, counterClockwise); ctx.lineWidth = zoneLineWidth; ctx.strokeStyle = options.color; ctx.lineCap = "butt"; ctx.stroke(); }; sectionOptions.forEach(function(options) { DrawZone(options); }); };
      
      





この方法では、 数字配列を解析し、緑、黄、赤のゾーンのを決定します。



画像

DrawTicksメソッドは、以前に計算されたステップで円弧にセリフを描画します



 var DrawTicks = function() { this.DrawTick = function(angle) { var fromX = middleX + (radius - tickOffsetFromArc) * Math.cos(angle); var fromY = middleY + (radius - tickOffsetFromArc) * Math.sin(angle); var toX = middleX + (radius + tickOffsetFromArc) * Math.cos(angle); var toY = middleY + (radius + tickOffsetFromArc) * Math.sin(angle); ctx.beginPath(); ctx.moveTo(fromX, fromY); ctx.lineTo(toX, toY); ctx.lineWidth = tickWidth; ctx.lineCap = "round"; ctx.strokeStyle = tickColor; ctx.stroke(); }; for (var i = startAngleIndex; i <= endAngleIndex; i += step) { var angle = i * Math.PI; this.DrawTick(angle); } };
      
      





画像

次の方法では、将来の速度計に数字を描画します。



 var DrawDigits = function() { var angleIndex = startAngleIndex; digits.forEach(function(digit) { var angle = angleIndex * Math.PI; angleIndex += step; var x = middleX + (radius - digitsOffsetFromArc) * Math.cos(angle); var y = middleY + (radius - digitsOffsetFromArc) * Math.sin(angle); ctx.font = digitsFont; ctx.fillStyle = digitsColor; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(digit, x, y); }); };
      
      





画像

最後の2つの方法は、中心円と実際には矢印を描くように設計されています。 必要に応じて、通常の値を受け入れ、矢印が表示される場所を決定するロジックを実装するようにDrawArrowメソッドを教えることができます。



 var DrawArrow = function() { var arrowAngle = arrowValueIndex * Math.PI; var toX = middleX + (radius) * Math.cos(arrowAngle); var toY = middleY + (radius) * Math.sin(arrowAngle); ctx.beginPath(); ctx.moveTo(middleX, middleY); ctx.lineTo(toX, toY); ctx.strokeStyle = arrowColor; ctx.lineWidth = arrowWidth; ctx.stroke(); }; var DrawCenterCircle = function() { ctx.beginPath(); ctx.arc(middleX, middleY, centerCircleRadius, 0, 2 * Math.PI, false); ctx.fillStyle = centerCircleColor; ctx.fill(); ctx.lineWidth = centerCircleBorderWidth; ctx.strokeStyle = arrowColor; ctx.stroke(); };
      
      





メソッドを正しい順序で呼び出すことは残っています



 DrawTicks(); DrawZones(); DrawDigits(); DrawArrow(); DrawCenterCircle();
      
      





もちろん、呼び出しの順序は重要です。たとえば、Photoshopのレイヤーの順序と同様です(逆の順序でのみ)

結果:

画像



ソース:






All Articles