JS中的径向形状

时间:2016-05-24 08:47:40

标签: javascript jquery html canvas

我想用javascript或jquery制作这个形状:

enter image description here

这些点将是动态的,并且在径向圆圈中的任何位置。 它也需要响应。

这有插件吗?

1 个答案:

答案 0 :(得分:7)

enter image description here

您正在绘制多个圈子

  • 显示轨道的圆圈是围绕公共中心的描边圆圈。
  • 圆圈体是围绕它们所在的轨道圆周以角度旋转的实心圆圈。

功能:编写可重用代码的有效方法!

您可以创建可重复使用的函数,而不是重写(重复)代码来绘制您的2种类型的圆圈,这些函数可以获取特定于圆圈的变量,并使用这些变量来绘制您的描边或实心圆圈。

描绘您的轨道的功能

drawOrbit函数接受半径并在中心点周围的半径处描边圆圈:

// cx,cy is the concentric centerpoint of your orbits -- cx,cy don't change
// radius is how far your orbit is from the centerpoint -- radius does change
function drawOrbit(radius){
    ctx.beginPath();
    ctx.arc(cx,cy,radius,0,Math.PI*2);
    ctx.stroke();    
}

绘制轨道体(圆圈)的功能

circleInOrbit函数接受半径并在中心点周围的半径处描边圆圈:

  • x,y使用三角函数计算。
  • cx,cy是轨道中心点
  • orbits[circle.orbitIndex]从轨道阵列中获取轨道对象。然后轨道对象告诉函数离轨道中心点有多远。
  • Math.cos(angle) & Math.sin(angle)告诉函数在轨道圆周上的轨道圆是

drawOrbitingCircle函数如下所示:

// Takes in a circle object that holds the circle's orbit & rotation angle
// It draws the orbiting circle on the specified orbit at the specified angle
function drawOrbitingCircle(circle){
    var x=cx+orbits[circle.orbitIndex]*Math.cos(circle.angle);
    var y=cy+orbits[circle.orbitIndex]*Math.sin(circle.angle);
    ctx.beginPath();
    ctx.arc(x,y,circleRadius,0,Math.PI*2);
    ctx.fillStyle='lightgray';
    ctx.fill();
    ctx.strokeStyle='white';
    ctx.stroke();
}

[添加:显示签名中心圈&防止重叠圆圈]

此功能绘制一个包含文字符号(加号)的蓝色圆圈:

  • 在同心点绘制一个蓝色圆圈。
  • 使用context.fillText(' +',centerX,centerY)在蓝色圆圈的中心绘制一个加号。

请注意,您可以将文字对齐为水平居中&垂直与context.textAlign = 'center'context.textBaseline = 'middle'

function drawSignedCenterCircle(signCharacter){
    ctx.beginPath();
    ctx.arc(cx,cy, 18, 0, 2 * Math.PI);
    ctx.fillStyle='blue';
    ctx.fill();
    ctx.fillStyle='white';
    ctx.font='24px verdana';
    ctx.textAlign='center';
    ctx.textBaseline='middle';
    ctx.fillText(signCharacter,cx,cy);
}

此代码会创建不会重叠的轨道圆。

它的工作原理是为每个轨道圆提供一个独特的轨道切片。由于每个切片都是唯一的,因此任何圆圈都不会与同一轨道上的任何其他圆重叠。

// calculate non-overlapping placements of orbiting bodies
for(var o=0;o<orbits.length;o++){
    var count=circleCountByOrbit[o];
    var sweep=Math.PI*2/count;
    for(var c=0;c<count;c++){
        var midAngle=(sweep*c)+sweep/2;
        var randomOffset=Math.random()*0.50-1;
        var angle=midAngle+sweep*randomOffset;
        circles.push({orbitIndex:o, angle:angle});
    }
}

示例代码和演示:

&#13;
&#13;
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

$("#canvas").mousedown(function(e){handleMouseDown(e);});

var cx=cw/2;
var cy=ch/2;
var circleRadius=10;
var blueRadius=18;
var orbits=[40,80,120];
var circleCountByOrbit=[3,5,7];
var circles=[];

// calculate non-overlapping placements of orbiting bodies
for(var o=0;o<orbits.length;o++){
  var count=circleCountByOrbit[o];
  var sweep=Math.PI*2/count;
  for(var c=0;c<count;c++){
    var midAngle=(sweep*c)+sweep/2;
    var randomOffset=Math.random()*0.50-1;
    var angle=midAngle+sweep*randomOffset;
    var x=cx+orbits[o]*Math.cos(angle);
    var y=cy+orbits[o]*Math.sin(angle);
    circles.push({
      cx:x, cy:y, 
      radius:circleRadius,
      orbitIndex:o, 
      angle:angle
    });
  }
}

// draw the stroked orbits
for(var i=0;i<orbits.length;i++){
  drawOrbit(orbits[i]);
}

// draw the orbiting bodies
for(var i=0;i<circles.length;i++){
  drawOrbitingCircle(circles[i]);
}

// draw the signedCenterCircle
drawSignedCenterCircle('+');

function drawOrbit(radius){
  ctx.beginPath();
  ctx.arc(cx,cy,radius,0,Math.PI*2);
  ctx.stroke();    
}

function drawOrbitingCircle(circle){
  x=circle.cx;
  y=circle.cy;
  ctx.beginPath();
  ctx.arc(x,y,circleRadius,0,Math.PI*2);
  ctx.fillStyle='lightgray';
  ctx.fill();
  ctx.strokeStyle='white';
  ctx.stroke();
}

function drawSignedCenterCircle(signCharacter){
  ctx.beginPath();
  ctx.arc(cx,cy, blueRadius, 0, 2 * Math.PI);
  ctx.fillStyle='blue';
  ctx.fill();
  ctx.fillStyle='white';
  ctx.font='24px verdana';
  ctx.textAlign='center';
  ctx.textBaseline='middle';
  ctx.fillText(signCharacter,cx,cy);
}

function handleMouseDown(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  // Check if mouse is inside any orbiting circle
  for(var i=0;i<circles.length;i++){
    var c=circles[i];
    var dx=mouseX-c.cx;
    var dy=mouseY-c.cy;
    if(dx*dx+dy*dy<c.radius*c.radius){
      drawOrbitingCircle(circles[i]);
      ctx.fillStyle='red';
      ctx.fill();
    }
  }
  // Check if mouse is inside any orbiting circle
  var dx=mouseX-cx;
  var dy=mouseY-cy;
  if(dx*dx+dy*dy<blueRadius*blueRadius){
    alert('You clicked in blue circle');
  }

}
&#13;
body{ background-color:white;padding:20px;}
#canvas{border:1px solid red; margin:0 auto; }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Click in a circle.</h4>
<canvas id="canvas" width=300 height=300></canvas>
&#13;
&#13;
&#13;