Creating interconnected circles with lines utilizing canvas

I am currently utilizing the canvas tag to generate circles on a world map image. My objective is to link these multiple circles with lines using the Canvas tag. Although I have successfully drawn the circles, I am facing difficulty in drawing the connecting lines.

HTML

<img src="http://educypedia.karadimov.info/library/worldoutlinemap.gif" width="500"/>
<canvas id="myCanvas1" width="200" height="200"></canvas>
<canvas id="myCanvas2" width="200" height="200"></canvas>
<canvas id="myCanvas3" width="200" height="200"></canvas>
<canvas id="myCanvas4" width="200" height="200"></canvas>

CSS

#myCanvas1
{
  position: absolute;
    top: 20px;
    left: 245px;
    z-index: 3;
}
#myCanvas2
{
  position: absolute;
    top: 20px;
    left: 25px;
    z-index: 3;
}

#myCanvas3
{
  position: absolute;
    top: 200px;
    left: 60px;
    z-index: 3;
}

#myCanvas4
{
  position: absolute;
    top: 150px;
    left: 200px;
    z-index: 3;
}

Javascript

/* circle1 */
    var canvas = document.getElementById('myCanvas1');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 10;
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'grey';
    context.fill();
    context.stroke();
    /* circle1 */  

    /* circle2 */
    var canvas = document.getElementById('myCanvas2');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 10;
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'grey';
    context.fill();
    context.stroke();
    /* circle2 */

  /* circle3 */
    var canvas = document.getElementById('myCanvas3');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 10;
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'grey';
    context.fill();
    context.stroke();
    /* circle3 */

  /* circle4 */
    var canvas = document.getElementById('myCanvas4');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 10;
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'grey';
    context.fill();
    context.stroke();
    /* circle4 */

Fiddle

Answer №1

Here is a unique implementation created for a previous query. This code specifically connects the outlines of two circles by drawing lines using vector principles and unit vectors to ensure the lines do not cross the circle boundaries.

The process involves calculating the vector between the centers of both circles, moving a certain distance towards the line from each circle, determining the intersection point between the circle and the line, and finally drawing a line connecting the modified end points.

Running the code multiple times will result in overlapping circles with only the outlines drawn. If filling the circles is necessary, the code may be considered excessive as the portion inside the circle will be automatically covered anyway. :)

function byId(e){return document.getElementById(e)}
window.addEventListener('load', onDocLoaded, false);

var shapeList = [];

function onDocLoaded()
{
var i, n=3;
var canvas = byId('myCanvas');

for (i=0; i<n; i++)
{
shapeList[i] = new circle_t(Math.random()*578, Math.random()*400, Math.random()*30 + 20);
shapeList[i].draw(canvas);
}

for (i=0; i<n-1; i++)
draw_line2(shapeList[i].origX, shapeList[i].origY, shapeList[i].radius, shapeList[i+1].origX, shapeList[i+1].origY, shapeList[i+1].radius);
}

var shape_t = function(x,y)
{
this.origX = (x==undefined ? 0 : x);
this.origY = (y==undefined ? 0 : y);
}
shape_t.prototype =
{
origX:0, origY:0, typeString:'shape',
setPos: function(x,y){this.x=x;this.y=y;},
setType: function(typeString){this.typeString = typeString;},
toString: function(){return this.typeString + " - " + this.origX + "," + this.origY;},
draw: function(canElem){},
};

function circle_t(x,y,radius)
{
this.origX = (x==undefined ? 0 : x);
this.origY = (y==undefined ? 0 : y);
this.radius = (radius==undefined ? 10 : radius);
this.setType("circle");
}
circle_t.prototype = new shape_t();
circle_t.prototype.constructor = circle_t;
circle_t.prototype.draw = function(canElem, color)
{
var ctx = canElem.getContext('2d');
var col = 'black';
if (color != undefined)
col = color;
drawCircle(this.origX, this.origY, this.radius, ctx, col);
}

circle_t.prototype.setRadius = function(radius)
{
if (radius != undefined)
this.radius = radius;
}

function drawCircle(x, y, radius, ctx, col)
{
ctx.save();
if (col == undefined)
col = 'black';
ctx.strokeStyle = col;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(x,y,radius,(Math.PI/180)*0, (Math.PI/180)*360, false);
ctx.stroke();
ctx.closePath();
ctx.restore();
}

// define a vec2 class to make vector maths easier (simpler to read)
function vec2(x,y)
{
this.length = function()
{
return Math.sqrt((this.x * this.x) + (this.y*this.y));
}
this.normalize = function()
{
var scale = this.length();
this.x /= scale;
this.y /= scale;
}
this.x = x;
this.y = y;
}

function draw_line2(center1_x, center1_y, radius1, center2_x, center2_y, radius2)
{
var betweenVec = new vec2(center2_x - center1_x, center2_y - center1_y);
betweenVec.normalize();

var p1x = center1_x + (radius1 * betweenVec.x);
var p1y = center1_y + (radius1 * betweenVec.y);

var p2x = center2_x - (radius2 * betweenVec.x);
var p2y = center2_y - (radius2 * betweenVec.y);

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(p1x,p1y);
context.lineTo(p2x,p2y);
context.stroke();
}
<canvas id="myCanvas" width="578" height="400"></canvas>

Answer №2

Take a look at this functional code snippet:

HTML

<img src="http://educypedia.karadimov.info/library/worldoutlinemap.gif" width="500"/>
<canvas id="line" width="500" height="200"></canvas>
<canvas id="myCanvas1" width="200" height="200"></canvas>
<canvas id="myCanvas2" width="200" height="200"></canvas>
<canvas id="myCanvas3" width="200" height="200"></canvas>
<canvas id="myCanvas4" width="200" height="200"></canvas>

JS

/*line1*/
    var canvas = document.getElementById('line');
  var ctx = canvas.getContext('2d');
  ctx.beginPath();
  ctx.moveTo(130, 0);
  ctx.lineTo(300, 150);
  ctx.stroke();

/* circle1 */
    var canvas = document.getElementById('myCanvas1');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 10;
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'grey';
    context.fill();
    context.stroke();
    /* circle1 */  

    /* circle2 */
    var canvas = document.getElementById('myCanvas2');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 10;
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'grey';
    context.fill();
    context.stroke();
    /* circle2 */

  /* circle3 */
    var canvas = document.getElementById('myCanvas3');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 10;
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'grey';
    context.fill();
    context.stroke();
    /* circle3 */

  /* circle4 */
    var canvas = document.getElementById('myCanvas4');
    var context = canvas.getContext('2d');
    var centerX = canvas.width / 2;
    var centerY = canvas.height / 2;
    var radius = 10;
    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'grey';
    context.fill();
    context.stroke();
    /* circle4 */

CSS

#line
{
  position: absolute;
    top: 110px;
    left: 0px;
    z-index: 3;
}

#myCanvas1
{
  position: absolute;
    top: 20px;
    left: 245px;
    z-index: 3;
}
#myCanvas2
{
  position: absolute;
    top: 20px;
    left: 25px;
    z-index: 3;
}

#myCanvas3
{
  position: absolute;
    top: 200px;
    left: 60px;
    z-index: 3;
}

#myCanvas4
{
  position: absolute;
    top: 150px;
    left: 200px;
    z-index: 3;
}

You can also view this on Fiddle.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can parameters be passed to a JavaScript or jQuery function?

I am currently utilizing a JS/JQ function to convert values into currency by adding commas. Although the function is running smoothly, I am encountering an issue when attempting to pass parameters to it. Kindly provide assistance on how to successfully pas ...

Is it possible to utilize Babel for transpiling, importing, and exporting in the client, all without relying on Web

Is it possible to compile JSX and export variables through the global namespace using Babel? I'm not interested in setting up a Webpack server. I'm currently familiarizing myself with ES6, JSX, Babel, and React, and I find adding another librar ...

Toggle classes on button click

<div class='fixed_button homes hidden'> <a class='btn btn-primary homes'>Continue &rarr;</a> </div> Using jQuery Library $(".homes").on('click', function(){ $("choose_style").addClass(&apo ...

How to Create Django Templates without Including head, body, and Doctype?

Is it considered the correct or recommended practice to omit the Doctype, head, and body tags? This is a question that arises when looking at examples like tutorial 3 in the Django documentation which can be found here, specifically in the polls/template ...

Global variable appears undefined in Angular 2 view, yet it is still displaying

I'm running into issues with my Angular 2 code. Inside my ts file, I have the following: import { Test } from '../../../../models/test'; import { TestService } from '../../../../services/test.service'; import { Job} fr ...

Adjust the dimensions of the react-dropdown-tree-select element to better fit your needs

Hey there, I'm a beginner web developer currently working on a tree-based dropdown menu. Check out the documentation here To see it live in action, visit the example here I'm trying to adjust the height and width of the "Search/DropDown bar" in ...

Initial React render fails to retrieve API data

I've encountered an issue during development where the page loads before the API data is sent. I attempted to use asynchronous functions, but it didn't resolve the problem as expected. I suspect that my approach may be incorrect. Here's a sn ...

How can you modify the color of a card in React by mapping through an array and evaluating its value?

I'm attempting to modify the color of a card depending on the current slot value, which is an object in an array. While I am iterating through each card, I want to adjust the background color of the card based on this value. However, my current method ...

I am facing an issue in JavaScript where one of my two timers is malfunctioning

While working on my tank game, similar to Awesome Tanks, I encountered an issue with the AI tank shooting mechanic. I set up a separate timer for the AI tank to shoot a bullet, but when I attempt to run it, I receive an error stating that AItimer is not de ...

Is there a way to show text as symbols in Primeng components?

Check out this helpful example that demonstrates what I am attempting to achieve. I have implemented p-menu from primeng. Is there a method to convert text into symbols like &trade to ™ and &#8482 to ®? ...

Stop image resizing on bootstrap Card

Looking for a Card design featuring a non-resized image against a grey background that is larger than the image itself. Although I have managed to set up the background and insert my chosen image, I am struggling to stop the image from resizing. <div c ...

How can I implement a search box on my HTML website without relying on Google Custom Search?

Greetings to all! I am currently managing a website filled with HTML content. I am looking to incorporate a search box into the site. After researching on Google, most of the results point towards using Google Custom Search. However, I require a search box ...

Ways to ensure that a div, header, container, and other elements completely cover the viewport

Currently, I am attempting to create a header that spans the entire viewport regardless of screen size. This header will be split horizontally into 3 equal sections, each occupying one third of the header space. I experimented with setting the header hei ...

What is the best way to continuously monitor MongoDB for updates and sync them with my user interface?

Looking to continuously monitor a user's notifications in MongoDB, updating them on specific actions and displaying updates on my React frontend without reloading every time the user logs in. I am currently utilizing Node and Mongoose models for datab ...

Steps to forward a restricted user to a specific webpage

I am currently utilizing NextJs and am in the process of creating a redirecting function for users who have been banned or blocked from accessing the DB/session. My attempt at this involved: redirect.js, where I created a custom redirect function. impo ...

What is the best way to center text in a div with a distinct background color?

Could really use some assistance with this. Here are the images for reference: https://i.stack.imgur.com/JNZkT.jpg Currently getting this result: https://i.stack.imgur.com/nW17o.jpg <style> .Nav_bar_links div{ margin: 0% 1 ...

The div element displays a vertical scrollbar exclusively

Can you explain why the div is only displaying a vertical scrollbar? Although the canvas is larger than the div in both dimensions: div { padding-top: 2px; height: 709px; width: 889px; overflow: auto; } <div> <canvas width="1405" sty ...

What is the reason behind the inconsistent behavior of Javascript's Date.getDate() and .setDate() methods?

As a hobbyist coder, I'm facing a challenging problem with building a dynamic HTML/CSS calendar. My goal is to have cells filled in based on today's date. However, when I attempt to add days to fill in another 13 days by looping through HTML elem ...

Problem with Internet Explorer version 9 and above and the Flip Card feature

I have a cool feature for one of my clients where clicking on one div causes another div to flip in its place, like a card flipping over. It's kind of like those portfolio image flippers, but instead of images, it flips divs with content inside. How ...

Tips for creating a linear movement effect for a collection of objects

I am working on animating a linear gripping motion for picking and placing objects. Here is a codesandbox link where you can see the issue I am facing: https://i.sstatic.net/dUdPv.png The gripper is created, moves down to reach the LEGO brick, and then s ...