WEB/재밌어서 만드는 것

[React] clip-path polygon으로 원형 wheel 만들기 2탄

자바칩 프라푸치노 2023. 4. 4. 18:19

1탄은 아래 게시물

https://sso-feeling.tistory.com/850

 

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

코드펜에서 이런 작업물을 발견했습니다. 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 마우스 클릭을 하면 동그란 휠이 나와서

sso-feeling.tistory.com

 

 

2탄은 리액트로 코드를 옮기고 hover 할때마다 약간 바운스되면서 커지는 효과를 넣어보겠습니다.

 

css는 styled-components를 사용하겠습니다.

1. styled-components로 Wheel 스타일 만들기

1탄의 코드를 보면 wheel의 스타일은 아래와 같습니다.

.wheel{
  width:500px;
  height : 500px; 
  transform: translate(50%, 50%);
  
}

 

이것을 styled-component로 만들어줍니다.

const Wheel = styled.div`
  width:500px;
  height : 500px; 
  transform: translate(50%, 50%);
`;

 

2. styled-components로 Child 스타일 만들기

1탄의 child css 는 아래와 같습니다.

.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);
}

 

이것을 styled-component로 바꿔줍니다.

const Child = styled.div`
  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);
  `;

 

3. child에서 props로 rotate각도와 색상, 테두리 색상을 받아서 처리하기

child에서 요소마다 rotate되는 각도가 다르고, 테두리 색상과 배경 색상이 달랐습니다.

이것을 props로 받아서 처리합니다.

 

const Child = styled.div`
  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);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, ${(
    props
  ) => props.border} 30%, ${(props) => props.border} 30.5%, ${(props) =>
  props.bg} 31%, ${(props) => props.bg} 50%, ${(props) =>
  props.border} 50.25%, ${(props) =>
  props.border} 51.5%, transparent 51.75%, transparent);
  transform: rotate(${(props) => props.rotate}deg);
`;

 

 

 <Wheel>
        <Child rotate="-22.5" border="#67D5B5" bg="#C89EC4"></Child>
        <Child rotate="22.5" border="#67D5B5" bg="#EE7785"></Child>
        <Child rotate="67.5" border="#67D5B5" bg="#84B1ED"></Child>
        <Child rotate="112.5" border="#67D5B5" bg="#AACD6E"></Child>
        <Child rotate="157.5" border="#67D5B5" bg="#ABD0CE"></Child>
        <Child rotate="202.5" border="#67D5B5" bg="#feee7d"></Child>
        <Child rotate="247.5" border="#67D5B5" bg="#cbe86b"></Child>
        <Child rotate="292.5" border="#67D5B5" bg="#6a60a9"></Child>
      </Wheel>

 

 

4. hover시에 애니메이션 주기

styled-component 에서 애니메이션을 props를 사용하면서 주는 방법입니다.

const bounce = (rotate) => keyframes`
  0% {
     transform: scale(1.1) rotate(${rotate}deg);
  }
  50% {
    transform: scale(1.13) rotate(${rotate}deg);
  }
  100% {
    transform: scale(1.1) rotate(${rotate}deg);
  }
`;

 

 

const Child = styled.div`
  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);
  background-image: radial-gradient(circle at 0% 100%, transparent, transparent 29.5%, ${(
    props
  ) => props.border} 30%, ${(props) => props.border} 30.5%, ${(props) =>
  props.bg} 31%, ${(props) => props.bg} 50%, ${(props) =>
  props.border} 50.25%, ${(props) =>
  props.border} 51.5%, transparent 51.75%, transparent);
  transform: rotate(${(props) => props.rotate}deg);

   &:hover{
    animation:  ${(props) => bounce(props.rotate)} 0.2s 0.1s ease-out;
    transform : rotate(${(props) => props.rotate}deg) scale(1.1);
   }
    
  
`;

 

 

결과는 이렇게 완성되었습니다 !

 

728x90