rem 단위 사용 환경에서 clipPath를 활용하여 hover 전후 영역의 모양을 변경하는 방법
해당 환경에서는 1rem = 1px
https://codepen.io/jihye1ee/pen/qEdwQoE
<div class="box">
<div class="shape-box"></div>
<svg width="0" height="0">
<defs>
<clipPath id="clipShape" clipPathUnits="objectBoundingBox">
<path d="M0.034 0 H0.965 C0.965 0 1 0 1 0.089 V0.91 C1 0.91 1 0.91 1 0.91 H1 C1 0.91 1 0.91 1 0.91 V0.91 C1 0.91 1 1 0.965 1 H0.034 C0.034 1 0 1 0 0.91 V0.089 C0 0.089 0 0 0.034 0 Z" />
</clipPath>
</defs>
</svg>
<div class="arrow">→</div>
</div>
.shape-box : 모양이 적용되는 요소
svg : 실제로 화면에 나타나지 않는 svg
clipPath : 모양을 정의하여 그 모양대로 요소를 잘라내는 기능을 함
path : CSS에서 clip-path: url(#clipShape) 이런 식으로 연결될 수 있도록 함clipPathUnits="objectBoundingBox": 경로 좌표를 비율(0~1)로 설정
path 해석
| M | Move to (좌표 위치 이동) |
|---|---|
| H | Horizontal line to (수평선) |
| V | Vertical line to (수직선) |
| C | Cubic bezier curve (곡선) |
| Z | Close path (경로 닫기) |

| hover 전 | hover 후 |
|---|---|
| M0.034 0 | |
| H0.965 | |
| C0.965 0 1 0 1 0.089 | |
| V0.91 | |
| **C1 0.91 1 0.91 1 0.91 | |
| H1 | |
| C1 0.91 1 0.91 1 0.91 | |
| V0.91** | |
| C1 0.91 1 1 0.965 1 | |
| H0.034 | |
| C0.034 1 0 1 0 0.91 | |
| V0.089 | |
| C0 0.089 0 0 0.034 0 | |
| Z | M0.034 0 |
| H0.965 | |
| C0.965 0 1 0 1 0.089 | |
| V0.6 | |
| C1 0.602 1 0.7 0.963 0.7 (border-radius: 26) | |
| H0.943 | |
| C0.943 0.7 0.886 0.7 0.886 0.85 (border-radius: 40) | |
| V0.902 | |
| C0.886 0.902 0.886 1 0.849 1 (border-radius: 26) | |
| H0.034 | |
| C0.034 1 0 1 0 0.91 | |
| V0.089 | |
| C0 0.089 0 0 0.034 0 | |
| Z |
hover 전 중간에 이동 없이 무의미하게 들어가 있는 건 hover 전후 path 구조가 동일해야 하기 때문임
html {
font-size: 0.05208334vw;
}
.box {
position: relative;
width: 705rem;
height: 267rem;
}
.shape-box {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
background-color: #000;
**clip-path: url(#clipShape);**
}
.arrow {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
bottom: 0;
right: 0;
width: 56rem;
height: 56rem;
background-color: pink;
border-radius: 50%;
font-size: 18rem;
font-weight: bold;
}
@media all and (max-width: 1023px) {
html {
font-size: 0.13vw;
}
}
@media all and (max-width: 500px) {
html {
font-size: 0.278vw;
}
}
const $box = document.querySelector(".box");
const $pathEl = $box.querySelector("path");
const pathDefault = $pathEl.getAttribute("d");
const pathHover = "M0.034 0 H0.965 C0.965 0 1 0 1 0.089 V0.6 C1 0.602 1 0.7 0.963 0.7 H0.943 C0.943 0.7 0.886 0.7 0.886 0.85 V0.902 C0.886 0.902 0.886 1 0.849 1 H0.034 C0.034 1 0 1 0 0.91 V0.089 C0 0.089 0 0 0.034 0 Z";
$box.addEventListener("mouseenter", () => {
gsap.to($pathEl, {
duration: 0.5,
attr: { d: pathHover },
ease: "power2.out",
});
});
$box.addEventListener("mouseleave", () => {
gsap.to($pathEl, {
duration: 0.5,
attr: { d: pathDefault },
ease: "power2.in",
});
});