CSS | Trigonometry Circle
Tags: html, css, webdev, tutorial
Published: 2023-09-19 12:43:09

Hello Frondend developers, today i will show you how to create a circular element layout with css trigonometry functions sin and cos. We will be using SASS for this just for the easy implemention.

Credit -  @kevinpowell 

## Full Code with Example
{% codepen https://codepen.io/shubhamtiwari909/pen/OJrxLMG %}

## Real example with images
{% codepen https://codepen.io/shubhamtiwari909/pen/qBLVRQG %}

Let's get started...

## HTML - 
```html
 <div class="parent">
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
  <div class="circle"></div>
</div>
```
* We have created a parent container and inside it we have 12 elements as its children

## CSS
### Basic stylings
```css
html {
  color-scheme: dark light;
}
body {
  min-height: 100vh;
  display: grid;
  place-items: center;
}
```
* The html rule specifies a color scheme for the HTML document, which could be either "dark" or "light."

* The body rule sets the minimum height of the body to 100% of the viewport height (100vh) and centers its content both vertically and horizontally using CSS Grid.

### Parent container
```css
.parent {
  width: 50px;
  aspect-ratio: 1;
  background: lightblue;
  border-radius: 50%;
  position: relative;
}
```
* It's a circular container with a light blue background.
* The aspect-ratio property ensures that the container maintains a 1:1 aspect ratio (i.e., it remains a perfect circle).
* border-radius makes the container circular.
* position: relative positions the container relative to its normal position in the document flow.

### Child elements styles
```css
.circle {
  --size: 25px;
  --offset: 100px;
  --transformX: calc(cos(var(--degrees)) * var(--offset));
  --transformY: calc(sin(var(--degrees)) * var(--offset));
  width: var(--size);
  aspect-ratio: 1;
  border-radius: 50%;
  background-color: orangered;
  position: absolute;
  left: calc(var(--size) / 2);
  top: calc(var(--size) / 2);
  transform: translate(var(--transformX), var(--transformY));
}
```
* size variable is used to set the width of the childrens, --offset will be used to push the elements away from the center about 100px.
* transformX and transformY, these two will adjust the positioning of the childrens at a particular angle away from the center by offset value. We have passed these to the transform translate property.

### Smaller viewport - 
```css
@media screen and (max-width: 580px) {
  --size: 18px;
  --offset: 72px;
}
```
* We are justing reducing the size and offset for smaller viewports.

### Childrens positioning
```scss
$colors: (
  #ff5733,
  #ffbd33,
  #33ff57,
  #33a1ff,
  #b933ff,
  #ff33a1,
  #33ffbd,
  #338aff,
  #ff3333,
  #33ffa1,
  #a1ff33,
  #ff33bd
);
$total: 12;
@for $i from 1 through length($colors) {
  .circle:nth-of-type(#{$i}) {
    --degrees: calc(#{$i} * (360deg / #{$total}));
    background-color: nth($colors, $i);
    border: 1px solid rgb(0, 0, 0, 0.2);
    animation: blink ease-in-out infinite alternate;
    animation-delay: #{$i * .1}s;
    animation-duration: 2s;
    transform-origin: center;
  }
}
```
* This block uses SCSS (Sass) syntax to create an array of colors ($colors) and then iterates through the colors to create individual circle styles.
* degree variable calculates the angle for each circle individually.(Example - 1 * 360/12 = 30, 2 * 360/12 = 60, ....)It will always divide the 360 into total number of childrens and position them at the angle using transform translate property.
* Each circle is assigned a background color from the $colors array.They have a border, and a CSS animation called "blink" is applied to each circle. The animation alternates between two states, creating a blinking effect.
* animation-delay and animation-duration are adjusted based on the loop index ($i) to control the timing of the animations.
* transform-origin: center ensures that each circle will remain around its center.

### Animation
```css
@keyframes blink {
  0%{
    scale: 1;
  }
  100%{
    scale:1.2;
  }
}
```
* Its a simple animation effect by scaling up and down the circles.


Feel free to give suggestions in comments to improve the component and make it more reusable and efficient.
THANK YOU FOR CHECKING THIS POST
You can contact me on -
Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com

^^You can help me with some donation at the link below Thank you👇👇 ^^
☕ --> https://www.buymeacoffee.com/waaduheck <--

Also check these posts as well
https://dev.to/shubhamtiwari909/website-components-you-should-know-25nm

https://dev.to/shubhamtiwari909/smooth-scrolling-with-js-n56

https://dev.to/shubhamtiwari909/swiperjs-3802

https://dev.to/shubhamtiwari909/custom-tabs-with-sass-and-javascript-4dej