Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Radial shape in JS

I want to make this shape with javascript or jquery:

enter image description here

These dots will be dynamic and some anywhere in radial circle. And it needs to be responsive also.

Is there any plugins for this?

like image 990
Ganesh Yadav Avatar asked May 24 '16 08:05

Ganesh Yadav


People also ask

How do you make a radial gradient in CSS?

To create a radial gradient you must also define at least two color stops. background: radial-gradient (shape size at position, start-color, ..., last-color); By default, shape is ellipse, size is farthest-corner, and position is center.

What is the default radial gradient shape?

background: radial-gradient (shape size at position, start-color, ..., last-color); By default, shape is ellipse, size is farthest-corner, and position is center. Radial Gradient - Evenly Spaced Color Stops (this is default)

How do you render complex shapes on a web page?

In this article we’ll be looking at the HTML canvas element and the JavaScript canvas API to render complex shapes onto our web pages. All we need to start is an HTML page with a canvas tag and a JavaScript file to manipulate it with.

What is the radial scale used for?

The linear radial scale is used to chart numerical data. As the name suggests, linear interpolation is used to determine where a value lies in relation to the center of the axis. The following additional configuration options are provided by the radial linear scale. Angle line configuration. more...


1 Answers

enter image description here

You are drawing many circles

  • The circles showing orbits are stroked circles around a common center.
  • The circling bodies are filled circles rotated at angles around the circumference of the orbit that they are in.

Functions: an efficient way to write reusable code!

Instead of re-writing (repeating) code to draw your 2 types of circles, you can create reusable functions that take in variables specific to a circle and use those variables to draw your stroked or filled circles.

The function that strokes your orbits

The drawOrbit function takes in a radius and strokes a circle at that radius around the center point:

// 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();    
}

The function that draws your orbital bodies (circles)

The circleInOrbit function takes in a radius and strokes a circle at that radius around the center point:

  • x,y are computed with trigonometry.
  • cx,cy is the orbit centerpoint
  • orbits[circle.orbitIndex] fetches the orbit object from the orbits array. Then the orbit object tells the function how far away from the centerpoint the orbit is.
  • Math.cos(angle) & Math.sin(angle) tells the function where on the circumference of the orbit the orbiting circle is

The drawOrbitingCircle function looks like this:

// 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();
}

[Addition: show signed-center circle & prevent overlapping circles]

This function draws a blue filled circle containing your text-sign (plus):

  • Draw a blue-filled circle at the concentric point.
  • Use context.fillText('+',centerX,centerY) to draw a plus sign in the center of the blue circle.

Note that you can align text to be centered horizontally & vertically with context.textAlign = 'center' and 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);
}

This code creates orbiting circles that won't overlap.

It works by giving each orbiting circle a unique slice of its orbit. Since each slice is unique, any circle won't overlap with any other circle in the same orbit.

// 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});
    }
}

Example code and a Demo:

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');
  }

}
body{ background-color:white;padding:20px;}
#canvas{border:1px solid red; margin:0 auto; }
<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>
like image 157
markE Avatar answered Oct 16 '22 19:10

markE