Good day to all! There is such an interesting task - to draw a circle using html and js. In essence, the task is to create a div on the markup of a certain width / height. I can offer the method itself because there is a way to draw such a rhombus

var obj = document.getElementById('container'); var tmp, k = 0, m = 200; for (var i = 0; i <= m; i++) { if (i > m / 2) k--; else k++; tmp = document.createElement('div'); //tmp.style.border = '1px solid #111fff' tmp.style.width = k + 'px'; tmp.style.height = '1px'; obj.appendChild(tmp); } 
 #container { width: 100%; display: block; padding: 10px; } #container div { background-color: lightblue; margin: 0 auto; } 
 <div id="container"></div> 

But I would like to ask for help in drawing a circle in this way. How to create an algorithm that draws a circle line by line with divs? I tried to do it with the formula c = 2R * sin (angle / 2), where c is the distance between points on the circle, and angle is the angle in radians. But it turns out a drop, not a circle. Code "drops":

 var obj = document.getElementById('container1'); var tmp, k = 0, m = 300, angl = 0; for (var i = 0; i <= m; i++) { if (angl > 360) angl = 360; tmp = document.createElement('div'); var sinus = Math.sin((Math.PI * angl / 180) / 2); tmp.style.width = m * sinus + 'px'; tmp.style.height = '1px'; obj.appendChild(tmp); var nexAngle = 360 / m; angl += nexAngle; } 
 #container, #container1 { width: 100%; display: block; padding: 10px; } #container1 div { background-color: lightgreen; margin: 0 auto; } 
 <div id="container1"></div> 

PS code is very ugly. done "in the forehead")

UPD: @pavel and @Gleb Kemarsky both answered the question posed, just in slightly different ways (although in the end it all comes down to the same formula). Thanks for the implementation on jQuery @Elena Semenchenko! @sitev_ru thanks too! Therefore, I advise those interested to pay attention to all the answers to this question. Thank !

  • And why html4 and div, but not html5 and canvas? - andreymal
  • one
    @andreymal Because it's so interesting! The task to think a little. With kanvas everything is solved without problems. I just didn’t have enough brains to think of this, so I decided to create a question - alexoander
  • By the way, why Math.sin ((Math.PI * angl / 180) / 2), if, like, 180 / pi * angl, - HamSter
  • @ElenaSemenchenko, sort of like there was a formula for converting an angle to radians. Something like this Ar = Ad * пи / 180 Where Ad is the angle in degrees, Ar is the angle in radians. - alexoander

4 answers 4

I think it's better not through a corner, but through segments.

Set the radius. Pass the circle vertically and draw the chords. Half of the chord length is the square root of the difference between the square of the radius and the square of the “height” of the chord.

 var obj = document.getElementById('container1'); var tmp, radius = 200; for (var i = 0; i <= 2 * radius; i++) { var height = Math.abs(radius - i); var chord = 2 * Math.sqrt(radius * radius - height * height); tmp = document.createElement('div'); tmp.style.height = '1px'; tmp.style.width = chord + 'px'; obj.appendChild(tmp); } 
 #container1 div { background-color: lightgreen; margin: 0 auto; } 
 <div id="container1"></div> 

  • one
    Thanks for the answer! That's just a question - I essentially tried to do the same, but through the corners. Maybe you noticed my error in the code? - alexoander
  • I'm trying to do the same on jQuery, but it turns out to be a quarter) - HamSter
  • @ElenaSemenchenko will be grateful if you share the code in Jquery) Now I will try to do it too. At the same time, we ’ll also learn how to draw this puzzle on jquery =) - alexoander
  • one
    @alexoander 1) The Pythagorean theorem helps to solve a problem with simpler calculations, and thus saves you from wasting time searching for errors. 2) It seems to me that it is impossible to do a cycle in all 360 degrees, because far from all angles are involved in the construction of a circle. I think we should go all along the same vertical diameter and calculate its angle for each successive block. And then for this angle, calculate the length of the block. My hypothesis: a drop turned out precisely because of the passage through all the corners in a row. - Gleb Kemarsky
  • one
    @alexoander You can try to calculate the height of the block for each angle. Now they are all at 1px , and in theory the height of the block at the horizontal diameter should be greater than the height of the block at the top or bottom of the crown of the circle. But the blocks at the tops of the circle will be very low. Therefore, I am afraid that the error of rounding the result will intervene on this path, and the circle will again turn out to be distorted. - Gleb Kemarsky

Well, something like that, I think it is easier to pick up the exact constant instead of 5 manually.

The idea of ​​the formula: we have a triangle (equilateral, height - (50 - k) pixels, sides of 50 pixels (radius of the circle)). Hence, from the Pythagorean theorem, its width = 2 * Sqrt (50 * 50 - (50-k) * (50-k)). But if you do this, it will be severely squeezed (from abroad is possible), so you need to multiply by a factor.

 var obj = document.getElementById('container'); var tmp, k = 0, m = 100; for (var i = 0; i <= m; i++) { if (i > m / 2) k--; else k++; tmp = document.createElement('div'); tmp.style.border = '1px solid #111fff' tmp.style.width = 5*Math.sqrt(50*50 - (50-k)*(50-k)) + 'px'; tmp.style.height = '1px'; obj.appendChild(tmp); } 
 #container { width: 100%; display: block; padding: 10px; } #container div { margin: 0 auto; } 
 <div id="container"></div> 

  • If it doesn't make it difficult, can you describe a formula (of type C = 2 * pi * R ^ 2)? It's just that even somehow I am sad not to know the geometry - alexoander
  • @alexoander updated the answer, if it is still not clear, write. - pavel
  • Thank! Very clear and understandable (although I had to draw a little to realize how this formula works). - alexoander
  • True, the question appeared - why did you "interpret" actions on a circle on an equilateral triangle? I try to understand the train of thought to learn to think in this direction - alexoander
  • one
    @alexoander joxi.ru/nAy936niXo35bA something like that - pavel

On jQuery, according to the formula of a circle, it turned out like this:

 function arc(r){ $('<div>',{ class: 'box' }).appendTo('body'); for(var i = 0; i <= 2*r; i++ ){ var y = Math.abs(r - i); var x = 2*Math.sqrt( Math.pow(r,2) - Math.pow(y,2) ); $('<i>',{ class: 'i' }) .css({ 'display': 'block', 'width': x + 'px', 'height': '1px', 'background-color':'lightgreen', 'margin-left': 'auto', 'margin-right': 'auto' }) .appendTo('.box'); } } arc(100); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 

enter image description here

  • Well, the formula is still the same - although it pushes away from the coordinate grid. I, too, got something similar - the truth is not as nice and compact as yours. Thanks for the research) - alexoander

something like this:

 r = 100; //radius for (var i = 0; i <= 360; i++) { x = r * cos(i); y = r * sin(i); } 

on coordinates x, y you draw a circle ...

But in the task you need to draw divas, remade your method ... Here’s what happened:

 var obj = document.getElementById('container1'); var tmp, radius = 200, ys = 0; for (var i = 0; i < 180; i++) { var x = Math.sin(Math.PI * i / 180) * radius * 2; var y = radius - Math.cos(Math.PI * i / 180) * radius; var h = y; if (i != 0) h = y - ys; ys = y; tmp = document.createElement('div'); tmp.style.height = h + 'px'; tmp.style.width = x + 'px'; obj.appendChild(tmp); } 
 #container1 div { background-color: red; margin: 0 auto; } 
 <div id="container1"></div> 

  • Such a formula is good, but there are a few "other" rules because I need to draw a circle "line by line" drawing each div. and the coordinates are each point - a slightly different way. - alexoander
  • redid ... maybe it will come down) - sitev_ru
  • The main thing works) Can you explain why such a strange restriction in the cycle? The radius is 200, and the limit is 180? Also the line with if (i! = 0) is a bit confusing (the condition does not work only 1 time). For the rest I agree, thanks! - alexoander