SVG, Canvas or CSS? I need to make a network of circles with images that interconnect

1

Well, that's it.

I thought of doing using SVG and bordered image but my concern is about responsiveness, on smaller devices it will get all messed up

I wanted a way for lines to automatically connect to images regardless of where they go

    
asked by anonymous 06.03.2018 / 02:58

2 answers

2

See an example using CSS and SVG. The lines were created using SVG and are connected from the center of the center circle to the center of each of the smaller circles.

Using jQuery, you can keep the rows connected in the same places when you resize the window.

See the example:

$(window).on("load resize", function(){

   var princ_x2 = $("#principal").width()/2,
       princ_y2 = $("#principal").height()/2;

   $("#c2 line").attr({
      "x1" : parseInt($("#principal .circ:eq(1)").css("left"))+34,
      "y1" : parseInt($("#principal .circ:eq(1)").css("top"))+34,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c3 line").attr({
      "x1" : parseInt($("#principal .circ:eq(2)").css("left"))+34,
      "y1" : parseInt($("#principal .circ:eq(2)").css("top"))+34,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c4 line").attr({
      "x1" : parseInt($("#principal .circ:eq(3)").css("left"))+34,
      "y1" : parseInt($("#principal .circ:eq(3)").css("top"))+34,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c5 line").attr({
      "x1" : parseInt($("#principal .circ:eq(4)").css("left"))+34,
      "y1" : parseInt($("#principal .circ:eq(4)").css("top"))+34,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c6 line").attr({
      "x1" : parseInt($("#principal .circ:eq(5)").css("left"))+34,
      "y1" : parseInt($("#principal .circ:eq(5)").css("top"))+34,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c7 line").attr({
      "x1" : parseInt($("#principal .circ:eq(6)").css("left"))+34,
      "y1" : parseInt($("#principal .circ:eq(6)").css("top"))+34,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c8 line").attr({
      "x1" : parseInt($("#principal .circ:eq(7)").css("left"))+44,
      "y1" : parseInt($("#principal .circ:eq(7)").css("top"))+44,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c9 line").attr({
      "x1" : parseInt($("#principal .circ:eq(8)").css("left"))+44,
      "y1" : parseInt($("#principal .circ:eq(8)").css("top"))+44,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c10 line").attr({
      "x1" : parseInt($("#principal .circ:eq(9)").css("left"))+44,
      "y1" : parseInt($("#principal .circ:eq(9)").css("top"))+44,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c11 line").attr({
      "x1" : parseInt($("#principal .circ:eq(10)").css("left"))+44,
      "y1" : parseInt($("#principal .circ:eq(10)").css("top"))+44,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c12 line").attr({
      "x1" : parseInt($("#principal .circ:eq(11)").css("left"))+44,
      "y1" : parseInt($("#principal .circ:eq(11)").css("top"))+44,
      "x2" : princ_x2,
      "y2" : princ_y2
   });

   $("#c13 line").attr({
      "x1" : parseInt($("#principal .circ:eq(12)").css("left"))+44,
      "y1" : parseInt($("#principal .circ:eq(12)").css("top"))+44,
      "x2" : princ_x2,
      "y2" : princ_y2
   });
});
#principal{
   height: 524px;
   max-width: 524px;
   left: 50%;
   transform: translate(-50%);
   position: relative;
   align-items: center;
   justify-content: center;
}

.circ{
   border: 8px solid #fff;
   border-radius: 100%;
   background-color: #fff;
   position: absolute;
   z-index: 9;

   /*essas duas linhas abaixo apenas para ilustração*/
   /*pode apagá-las*/
   text-align: center;
   line-height: 50px;
}

.circ::before{
   content: '';
   width: 100%;
   height: 100%;
   border: 4px solid #000;
   position: absolute;
   left: -4px;
   top: -4px;
   border-radius: 100%;
   z-index: -1;
}

.c60{
   width: 60px;
   height: 60px;
}

.c80{
   width: 80px;
   height: 80px;
}

.c100{
   width: 100px;
   height: 100px;
}

svg{
   width: 100%;
   height: 100%;
   stroke: #000;
   stroke-width: 4;
   position: absolute;
   top: 0;
   left: 0;
}

#principal span:nth-child(1){
   top: 50%;
   left: 50%;
   margin-top: -58px;
   margin-left: -58px;
   background-image: url(https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg);
   background-size: cover;
}

#principal span:nth-child(2){
   top: 100px;
   left: 45%;
}

#principal span:nth-child(3){
   top: 156px;
   right: 21%;
}

#principal span:nth-child(4){
   bottom: 136px;
   right: 20%;
}

#principal span:nth-child(5){
   bottom: 110px;
   left: 45%;
}

#principal span:nth-child(6){
   bottom: 156px;
   left: 21%;
}

#principal span:nth-child(7){
   top: 156px;
   left: 21%;
}

#principal span:nth-child(8){
   top: 56px;
   right: 20%;
}

#principal span:nth-child(9){
   top: 200px;
   right: 1%;
}

#principal span:nth-child(10){
   bottom: 36px;
   right: 21%;
}

#principal span:nth-child(11){
   bottom: 36px;
   left: 21%;
}

#principal span:nth-child(12){
   top: 200px;
   left: 1%;
}

#principal span:nth-child(13){
   top: 56px;
   left: 20%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divid="principal">
   <span class="circ c100"></span>

   <span class="circ c60">2</span>
   <span class="circ c60">3</span>
   <span class="circ c60">4</span>
   <span class="circ c60">5</span>
   <span class="circ c60">6</span>
   <span class="circ c60">7</span>

   <span class="circ c80">8</span>
   <span class="circ c80">9</span>
   <span class="circ c80">10</span>
   <span class="circ c80">11</span>
   <span class="circ c80">12</span>
   <span class="circ c80">13</span>

   <svg id="c2"><line /></svg>
   <svg id="c3"><line /></svg>
   <svg id="c4"><line /></svg>
   <svg id="c5"><line /></svg>
   <svg id="c6"><line /></svg>
   <svg id="c7"><line /></svg>

   <svg id="c8"><line /></svg>
   <svg id="c9"><line /></svg>
   <svg id="c10"><line /></svg>
   <svg id="c11"><line /></svg>
   <svg id="c12"><line /></svg>
   <svg id="c13"><line /></svg>
</div>
    
06.03.2018 / 17:03
2

I made this quick example with only CSS that I think will answer you!

It is responsive, always adjusted to the size of% w / o% only the balls at the end of the lines that you will have to make a .container to them, because with measures in% w /% they are stretched, of size is the line (which is wider than tall and the ball turns ellipse )

I made a simplified version, but you can do the rest of the lines and change the @media as I did in the example to have as many lines as you like.

* {
    box-sizing: border-box;
}
body {
    margin: 0;
}
.container {
    width: 300px;
    height: 300px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
}
.bola {
    width: 25%;
    height: 25%;
    border-radius: 50%;
    background-color: red;
    border: 5px solid black;
    box-shadow: 0 0 0 10px #fff;
    position: absolute;
    z-index: 100;
}
.linha {
    width: 100%;
    height: 2px;
    background-color: black;
    position: absolute;
}
.linha::before, .linha::after {
    content: "";
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background-color: red;
    border: 3px solid black;
    box-shadow: 0 0 0 6px #fff;
    position: absolute;
    z-index: 100;
    top: 50%;
    transform: translateY(-50%);
}
.linha::after {
    right: 0;
}

.linha:nth-child(2) {
    width: 60%;
    height: 2px;
    background-color: black;
    position: absolute;
    transform: rotate(90deg);
}
.linha:nth-child(3) {
    width: 90%;
    height: 2px;
    background-color: black;
    position: absolute;
    transform: rotate(45deg);
}
.linha:nth-child(3)::before, .linha:nth-child(3)::after  {
    width: 35px;
    height: 35px;
}
.linha:nth-child(4) {
    width: 90%;
    height: 2px;
    background-color: black;
    position: absolute;
    transform: rotate(-45deg);
}
.linha:nth-child(4)::before, .linha:nth-child(4)::after  {
    width: 35px;
    height: 35px;
}
<div class="container">
    <div class="bola"></div>
    <div class="linha"></div>
    <div class="linha"></div>
    <div class="linha"></div>
    <div class="linha"></div>
</div>

OBS1: Adjust the size of % to see that it does not fall out! :)

.container {
    width: 300px;
    height: 300px;
}

OBS2: The lines are always proportional to the size of transform: rotate(); ok, as I said, you only need to treat the size of the smaller balls.

    
06.03.2018 / 16:20