计算在HTML5画布径向进度条中单击的百分比

时间:2014-10-01 22:24:11

标签: javascript jquery html5 canvas

我创建了一个像这样的循环进度条

enter image description here

我可以通过使用java-script发送它来加载一定的百分比,但我无法弄清楚如何计算用户点击圆圈的黑色/绿色部分时点击的百分比。

如何计算百分比?

请解释你的答案。

2 个答案:

答案 0 :(得分:4)

以下是将点击角度转换为百分比的一种方法:

  • 使用Math.atan2计算鼠标与中心点的角度。

  • 将该角度标准化为0-PI * 2弧度:(angle+PI*2)%(PI*2)

  • 计算该角度占整圆的百分比:normalizedAngle/(PI*2)

  • 这是你的百分比!

插图:请注意,0%位于圆圈的3点位置

enter image description here enter image description here

示例代码和演示:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();

var isDown = false;
var startX;
var startY;

var cx = 150;
var cy = 150;
var radius = 75;
var PI = Math.PI;
var PI2 = PI * 2;

ctx.lineWidth = 15;
ctx.font = '24px verdana';

draw(50, 50);

function draw(x, y) {

  var dx = x - cx;
  var dy = y - cy;
  var endAngle = (Math.atan2(dy, dx) + PI2) % PI2;
  var pct = parseInt(endAngle / PI2 * 100);

  ctx.clearRect(0, 0, cw, ch);

  ctx.beginPath();
  ctx.arc(cx, cy, radius, 0, PI2);
  ctx.closePath();
  ctx.strokeStyle = 'black';
  ctx.stroke();

  ctx.beginPath();
  ctx.arc(cx, cy, radius, 0, endAngle);
  ctx.strokeStyle = 'forestgreen';
  ctx.stroke();

  ctx.fillText(pct + '%', cx - 15, cy + 8);

}



function handleMouseDown(e) {
  e.preventDefault();
  e.stopPropagation();

  mX = parseInt(e.clientX - offsetX);
  mY = parseInt(e.clientY - offsetY);

  draw(mX, mY);

}

$("#canvas").mousedown(function(e) {
  handleMouseDown(e);
});
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Click on the canvas to set a percentage.</h4>
<canvas id="canvas" width=300 height=300></canvas>

答案 1 :(得分:2)

我喜欢使用trig这样做,因为我觉得它很容易记住和使用。您只需要能够找到圆的顶部坐标和中心坐标并知道它的半径。而且你必须能够确定点击这两者的距离。因此可能必须使用偏移量。您可以修改此代码以满足您的特定需求。

如果您有点击的坐标,圆的中心和圆的顶部,您可以找到所有三个点之间的距离。拥有三角形每边的长度足以找到所有角度。

你唯一担心的角度是中心的角度。你可以使用那一个,相比之下你点击是否通过了中间的那个,找到圆圈的百分比。

以下是一些消息来源:

https://gamedev.stackexchange.com/questions/33709/get-angle-in-radians-given-a-point-on-a-circle http://snipplr.com/view/47207/distance-between-two-points/ http://www.mathsisfun.com/algebra/trig-solving-triangles.html MATH很有趣!

以下是一个工作示例:http://jsbin.com/hopak/1/edit

$('#circle').click(function (e) { //Relative ( to its parent) mouse position 
    var posX = $(this).position().left,
        posY = $(this).position().top,
     radius = 50,
     x = e.pageX - posX, /* Offset not sure if cross-browser compatibile? */
     y = e.pageY - posY,
     coords = {
        x:x,
        y:y
     };

     function findDist( start, end ){
       var dx = end.x;
       var dy = end.y;

       dx -= start.x;
       dx *= dx;

       dy -= start.y;
       dy *= dy;

       return Math.sqrt( dx + dy );
     }

     sideA = findDist(coords,{x:radius,y:0}); /* Click to Top Circle */
     sideB = findDist(coords,{x:radius,y:radius}); /* Click to Center */
     sideC = radius; /* Center to Middle */

     function findAngleUsingSides(a, b, c) {  
        var radians = ((a * a) + (b * b) - (c * c)) / (2 * (a * b));
        return (Math.acos(radians))/ Math.PI * 180;
     }

     A = findAngleUsingSides(sideB, sideC, sideA);

     if(x < radius){
        /* 
        You clicked before halfway across
        */
        A = 360 - A;
     }

     percentClicked =  A / 360;

     console.log(percentClicked);

});