Search code examples
htmlcsscss-shapes

How to calculate translateX in a hexagon made of arrows


I created a hexagon made by six arrows using html and css, I want to stick the arrows together without gaps.

The 37% in translate(37%, -25%) is derived using the exhaustive method, and its not precise.

How can I actually calculate the translateX number correctly?

I am happy to accept answer that require the use of JavaScript or any helpful hints.

body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

.container {
  position: relative;
  width: 350px;
  aspect-ratio: 1;
}

.arrow {
  top: 50%;
  left: 50%;
  opacity: 0.3;
  background-color: navy;
  width: 55%;
  height: 48%;
  position: absolute;
  translate: -50% -100%;
  transform: rotate(calc(360deg / 6 * var(--i))) translate(37%, -25%);
  transform-origin: 50% 100%;
  clip-path: polygon(0 0, 75% 0, 100% 50%, 75% 100%, 0 100%, 25% 50%);
}
<div class="container">
  <div class="arrow" style="--i: 0"></div>
  <div class="arrow" style="--i: 1"></div>
  <div class="arrow" style="--i: 2"></div>
  <div class="arrow" style="--i: 3"></div>
  <div class="arrow" style="--i: 4"></div>
  <div class="arrow" style="--i: 5"></div>
</div>


Solution

  • Here is a slightly different way to code it using accurate values and math. All you have to do is to update one value.

    body {
      display: grid;
      place-content: center;
      min-height: 100vh;
      margin: 0;
    }
    
    .container {
      height: 350px; /* you only have to adjust this */
      aspect-ratio: 1/cos(30deg);
      display: grid;
      place-items: center;
      outline: 1px solid red;
    }
    
    .arrow {
      grid-area: 1/1;
      background-color: hsl(calc(60deg*var(--i)) 30% 60%);
      height: 40%;
      aspect-ratio: 1;
      --_d:(1 - 2*cos(30deg))/sin(30deg);
      transform: 
        rotate(calc(60deg*var(--i))) 
        translate(calc(50%*cos(30deg)), calc(25%*(var(--_d) - 1)));
      clip-path: 
        polygon(0 0,
         calc(100% - 50%*tan(30deg)) 0,100% 50%, 
         calc(100% - 50%*tan(30deg)) 100%,0 100%, 
         calc(       50%*tan(30deg)) 50%);
    }
    <div class="container">
      <div class="arrow" style="--i: 0"></div>
      <div class="arrow" style="--i: 1"></div>
      <div class="arrow" style="--i: 2"></div>
      <div class="arrow" style="--i: 3"></div>
      <div class="arrow" style="--i: 4"></div>
      <div class="arrow" style="--i: 5"></div>
    </div>