WEB/재밌어서 만드는 것

[css] clip-path polygon으로 원형 wheel 만들기 1탄

자바칩 프라푸치노 2023. 3. 21. 17:44

코드펜에서 이런 작업물을 발견했습니다.

https://codepen.io/wheatup/pen/GbgyLY

 

Interactive Wheel Menu

Using javascript and css(non-svg) to make an hold-and-drag wheel menu....

codepen.io

 

마우스 클릭을 하면 동그란 휠이 나와서 마우스가 움직일 때 마다 위치에 있는 버튼이 튀어나오는 인터렉션입니다.

 

 

 

 

그런데 무엇보다 이 원형 모양을 css로 어떻게 만들었는지 궁금해서 css를 분석해보았습니다.

전체 코드는 링크에서 확인 바랍니다.

 

 

1. 테두리있는 조각난 원링 모양 만들기

각각의 버튼에 기본적으로 이러한 css가 있었습니다.

예상컨대 이것이 핵심인 것 같았습니다.

background-image: 
radial-gradient(circle at 0% 100%, 
transparent, 
transparent 29.5%, 
var(--color-border) 30%, 
var(--color-border) 30.5%, 
var(--color) 31%, 
var(--color) 50%, 
var(--color-border) 50.25%,
var(--color-border) 51.5%,
transparent 51.75%,
transparent);

 

 

무슨 뜻인지 모르니까 다른 색깔로 바꾸어서 확인해보겠습니다.

 

 

<div class="hi"/>
.hi{
  width:500px;
  height : 500px; 
  transform: translate(50%, 50%);
  background-image: radial-gradient(circle at 0% 100%, orange, gray 29.5%, pink 30%, blue 30.5%, yellow 31%, red 50%, purple 50.25%, green 51.5%, skyblue 51.75%, #DDF10B);
}

 

div를 하나 만들고 background image에 색깔을 다르게 설정해보았습니다.

gray 29.5는 gray가 100퍼센트가 되면  아래와 같이 div를 끝까지 채우게 되는데,

29.5퍼센트까지만 그려서 반원형을 만든 것이었습니다.

 

 

 

 

마찬가지로 pink 30, blue 30.5 .. 등등 도 반원형을 만드는 코드입니다.

0.5씩 늘려서 테두리를 만들고 있습니다.

 

 

그래서 다시 원래 코드에 transparent가 있는 부분에 transparent를 넣는다면 아래와 같이 됩니다.

 

원래 작업물을 보면 테두리는 색이 1개인데 왜 2가지로 나누어졌는지가 의문이 들었습니다. 

그래서 두가지로 나누지 않고 테두리 부분을 1가지 색으로 바꿔보겠습니다.

 

 

  background-image: radial-gradient(circle at 0% 100%, 
  transparent, transparent 29.5%, 
  pink 30.5%, 
  red 50%,
  green 51.5%, 
  transparent 51.75%, transparent);

 

테두리 부분을 0.5씩 나누지 않고 그냥 1 차이를 두고 한가지 색상으로 설정을 해두었는데요,

뭔가 기준이 흐리멍텅하고 테두리 같지가 않습니다.

 

그렇다면 같은 색상으로 0.5씩 나누어서 줘보겠습니다 (원본 작업물과 같음)

 

오 이제 테두리 같습니다.

하지만 어딘가 좀 흐릿해보입니다.

 

 

 

 

그리하여 다음 색상과의 텀이 없도록 숫자를 조정하였습니다.

    background-image: radial-gradient(circle at 0% 100%, 
    transparent, transparent 29.5%, 
    pink 29.5%, pink 30.5%, 
    red 30.5%, red 50%, 
    green 50%, green 51.5%, 
    transparent 5.5%, transparent);

그랬더니 이제 진한 테두리가 되었습니다.


 

2. 원링을 8개 만들기

하지만 이제 보니 이 비율이라면 다른색상 휠 4개밖에 못만들겠군요. (4분의 1 원이기 때문에)

어떻게 8개로 원을 만들었는지 다시 코드를 확인해보았습니다.

clip-path: polygon(0 0, 0 99%, 99% 0);

clip-path polygon이라는 코드가 있었네요. 이건 처음봅니다..!

https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path

 

clip-path - CSS: Cascading Style Sheets | MDN

The clip-path CSS property creates a clipping region that sets what part of an element should be shown. Parts that are inside the region are shown, while those outside are hidden.

developer.mozilla.org

 

폴리곤은 다각형을 만드는 코드입니다.

polygon(시계방향 꼭지점)
clip-path: polygon(좌측 상단, 우측 상단, 우측 하단, 좌측 하단);

 

 

 

이렇게 값을 주는 건데 

위 코드는 예상하기로는 아래와 같이 삼각형대로 잘라서 삼각형 안에 있는 모습만 보여주도록 하는 코드인 것 같습니다.

알고 쓰려면 엄청난 연마가 필요할듯..

 

 

 

3. 결과

자 결론은..!

div 8개를 만들고

각각의 div에 동일한 clip-path를 주고

각자 rotate를 시켜주면 8개의 wheel을 만들 수 있습니다.

(8개이므로 360 나누기 8 을 해서 45도씩 회전시킵니다.)

 

 

 

<완성>

<코드>

html

<div class="wheel">
	<div class="child"></div>
	<div class="child"></div>
	<div class="child"></div>
	<div class="child"></div>
	<div class="child"></div>
	<div class="child"></div>
	<div class="child"></div>
	<div class="child"></div>
</div>

 

 

css

.wheel{
  width:500px;
  height : 500px; 
  transform: translate(50%, 50%);
  
}
.wheel .child {
  position: absolute;
  top: 0;
  right: 0;
  width: 50%;
  height: 50%;
  opacity: 0.8;
  transform-origin: 0% 100%;
  clip-path: polygon(0 0, 0 99%, 99% 0);
}

.wheel .child:nth-child(1) {
  transform: rotate(-22.5deg);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, pink 30%, pink 30.5%, red 31%, red 50%, green 50.25%, green 51.5%, transparent 51.75%, transparent);

}
.wheel .child:nth-child(2) {
  transform: rotate(22.5deg);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, yellow 30%, yellow 30.5%, blue 31%, blue 50%, purple 50.25%, purple 51.5%, transparent 51.75%, transparent);

}
.wheel .child:nth-child(3) {
  transform: rotate(67.5deg);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, pink 30%, pink 30.5%, red 31%, red 50%, green 50.25%, green 51.5%, transparent 51.75%, transparent);
}
.wheel .child:nth-child(4) {
  transform: rotate(112.5deg);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, yellow 30%, yellow 30.5%, blue 31%, blue 50%, purple 50.25%, purple 51.5%, transparent 51.75%, transparent);
}
.wheel .child:nth-child(5) {
  transform: rotate(157.5deg);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, pink 30%, pink 30.5%, red 31%, red 50%, green 50.25%, green 51.5%, transparent 51.75%, transparent);
}

.wheel .child:nth-child(6) {
  transform: rotate(202.5deg);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, yellow 30%, yellow 30.5%, blue 31%, blue 50%, purple 50.25%, purple 51.5%, transparent 51.75%, transparent);
}

.wheel .child:nth-child(7) {
  transform: rotate(247.5deg);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, pink 30%, pink 30.5%, red 31%, red 50%, green 50.25%, green 51.5%, transparent 51.75%, transparent);
}

.wheel .child:nth-child(8) {
  transform: rotate(292.5deg);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, yellow 30%, yellow 30.5%, blue 31%, blue 50%, purple 50.25%, purple 51.5%, transparent 51.75%, transparent);
}

 

다음 포스팅에서는 react 컴포넌트로 만들어서 변수로 rotate를 하고 background image를 설정 해보겠습니다 ~!

그리고 돌아가는 휠도 만들어보겠습니다.

 

 

 

 

 

 

728x90