Ángulos en canvas

facebook-svg gplus-svg twitter-svg

A diferencia de lo que podamos estar acostumbrados, en <canvas> los ángulos  empiezan a contarse "desde las 3 en punto" como en el siguiente ejemplo:

Utilizamos radianes

En el <canvas> para trabajar con ángulos, utilizamos radianes. Un circulo completo tiene 2π radianes, con lo cual podemos escribir: 360° = 2π rad; o en JavaScript: 2*Math.PI;

Para convertir grados sexagesimales a radianes utilizamos la siguiente fórmula:

var radianes =  grados *(Math.PI / 180);

También podemos convertir radianes a  grados sexagesimales utilizando esta otra fórmula:

var grados = radianes * (180/Math.PI);

Por lo tanto podemos escribir estas dos funciones que nos vendrán bien más tarde:

function deGrados_aRadianes (grados) {
    return grados * (Math.PI/180);
  }
function deRadianes_aGrados (radianes) {   return radianes * (180/Math.PI); }

Por favor arrastre el punto naranja.

0deg

Vea esta aplicación codepen.io.


Por favor arrastre el punto naranja.

0deg

.resultado article {
  font-size: 16px;
  font-family: serif;
  text-align: center;
  font-style: italic;
}
.g_panel.resultado:before {
    content: 'demo';
}
#c {
  background-color: white;
  display: block;
  margin: 0 auto;
  cursor: pointer;
}

#canvasContainer {
  margin: 0 auto;
  width: 300px;
  height: 300px;
  position: relative;
}

#canvasContainer #output {
  position: absolute;
  padding: .5em;
  top: 107px;
  left: 220px;
  background-color: rgba(255, 255, 255, .8);
  width: 3em;
  pointer-events: none;
  z-index:99;
}

#output::selection {
  background-color: rgba(255, 255, 255, .8);
  color:#333;
}

#output::-moz-selection {
  background-color: rgba(255, 255, 255, .8);
  color:#333;
}


var output = document.getElementById("output");

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

var cw = c.width = 300,
  cx = cw / 2;
var ch = c.height = 300,
  cy = ch / 2;
var rad = Math.PI / 180;
var R = 100,
  r = 5;

var handle = {
  x: cx + R,
  y: cy,
  r: 5
}
output.style.top = (handle.y - 50) + "px";
output.style.left = (handle.x - 30) + "px";

var isDragging = false;
ctx.strokeStyle = "#555";
ctx.fillStyle = "#e18728";


strokeCircle(cx, cy, R);
drawHandle(handle);
drawHub()

// Events ***************************

c.addEventListener("mousedown", function(evt) {
  isDragging = true;
  updateHandle(evt);

}, false);

// mousemove 
c.addEventListener("mousemove", function(evt) {
  if (isDragging) {

    updateHandle(evt);

  }
}, false);
// mouseup 
c.addEventListener("mouseup", function() {
  isDragging = false;
}, false);
// mouseout 
c.addEventListener("mouseout", function(evt) {
  isDragging = false;
}, false); /**/

// Helpers ***************************
function strokeCircle(x, y, r) {
  ctx.beginPath();
  ctx.arc(x, y, r, 0, 2 * Math.PI);
  ctx.stroke();
}

function fillCircle(x, y, r) {
  ctx.beginPath();
  ctx.arc(x, y, r, 0, 2 * Math.PI);

  ctx.save();
  ctx.strokeStyle = "#cc0000";
  ctx.lineWidth = 1;
  ctx.fill();
  ctx.stroke();
  ctx.restore()
}

function drawHub() {
  ctx.save()
  ctx.fillStyle = "black";
  ctx.beginPath();
  ctx.arc(cx, cy, 3, 0, 2 * Math.PI);
  ctx.fill();
  ctx.restore();
}

function oMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: Math.round(evt.clientX - rect.left),
    y: Math.round(evt.clientY - rect.top)
  };
}

function drawHandle(handle) {

  ctx.beginPath();
  ctx.moveTo(cx, cy);
  ctx.lineTo(handle.x, handle.y);
  ctx.stroke();

  fillCircle(handle.x, handle.y, handle.r);

}

function updateHandle(evt) {
  var m = oMousePos(c, evt);
  var deltaX = m.x - cx;
  var deltaY = m.y - cy;
  handle.a = Math.atan2(deltaY, deltaX);
  handle.x = cx + R * Math.cos(handle.a);
  handle.y = cy + R * Math.sin(handle.a);
  ctx.clearRect(0, 0, cw, ch);

  strokeCircle(cx, cy, R);
  drawHandle(handle);
  drawHub()

  output.innerHTML = parseInt(handle.a * (180 / Math.PI)) + "deg";
  output.style.top = (handle.y - 50) + "px";
  output.style.left = (handle.x - 30) + "px";
}