Ángulos en canvas
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.
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";
}