React Hooks⚡️를 사용한 멋진 애니메이션 커서
11342 단어 cursorreactreacthooksjavascript
커서에 기본 스타일과 논리를 추가하여 시작하겠습니다.
.cursor {
width: 40px;
height: 40px;
border: 2px solid #fefefe;
border-radius: 100%;
position: fixed;
transform: translate(-50%, -50%);
pointer-events: none;
z-index: 9999;
mix-blend-mode: difference;
}
html, body {
cursor: none;
background-color: #121212;
}
const Cursor = () => {
return <div className="cursor"/>
}
ReactDOM.render(
<div className="App">
<Cursor/>
</div>,
document.getElementById('root')
);
이제 마우스 이동에 따라 커서의 위치를 변경하려고 합니다.
const Cursor = () => {
+ const [position, setPosition] = useState({x: 0, y: 0});
+
+ useEffect(() => {
+ addEventListeners();
+ return () => removeEventListeners();
+ }, []);
+
+ const addEventListeners = () => {
+ document.addEventListener("mousemove", onMouseMove);
+ };
+
+ const removeEventListeners = () => {
+ document.removeEventListener("mousemove", onMouseMove);
+ };
+
+ const onMouseMove = (e) => {
+ setPosition({x: e.clientX, y: e.clientY});
+ };
+
- return <div className="cursor"/>
+ return <div className="cursor"
+ style={{
+ left: `${position.x}px`,
+ top: `${position.y}px`
+ }}/>
}
...
구성 요소가 마운트되면 이벤트를 처리하는 이벤트 리스너를 추가하고
mousemove
구성 요소가 마운트 해제될 때 제거합니다. onMouseMove
함수에서 e.clientX
및 e.clientY
속성을 기반으로 새 커서의 위치를 설정합니다.이제 커서가 마우스 움직임에 반응하지만 보시다시피 마우스가 화면을 떠날 때 커서가 숨겨지지 않습니다. 그래서 그것을 고치자!
.cursor {
...
+ transition: all 150ms ease;
+ transition-property: opacity;
}
+ .cursor--hidden {
+ opacity: 0;
+ }
...
+ import classNames from "classnames";
const Cursor = () => {
const [position, setPosition] = useState({x: 0, y: 0});
+ const [hidden, setHidden] = useState(false);
...
const addEventListeners = () => {
document.addEventListener("mousemove", onMouseMove);
+ document.addEventListener("mouseenter", onMouseEnter);
+ document.addEventListener("mouseleave", onMouseLeave);
};
const removeEventListeners = () => {
document.removeEventListener("mousemove", onMouseMove);
+ document.removeEventListener("mouseenter", onMouseEnter);
+ document.removeEventListener("mouseleave", onMouseLeave);
};
+
+ const onMouseLeave = () => {
+ setHidden(true);
+ };
+
+ const onMouseEnter = () => {
+ setHidden(false);
+ };
...
+
+ const cursorClasses = classNames(
+ 'cursor',
+ {
+ 'cursor--hidden': hidden
+ }
+ );
+
- return <div className="cursor"
+ return <div className={cursorClasses}
style={{
left: `${position.x}px`,
top: `${position.y}px`
}}/>
}
...
그래서
mouseleave
및 mouseenter
처리기를 추가합니다. 마우스가 화면에 들어올 때 opacity
는 1
가 되고 떠날 때 - 는 0
가 됩니다. 또한 classNames를 조건부로 결합하기 위한 간단한 유틸리티인 라이브러리classnames
를 추가합니다.이제 훨씬 좋아 보이지만 더 많은 것을 추가해 봅시다!
클릭 애니메이션을 추가해 보겠습니다.
.cursor {
...
- transition-property: opacity;
+ transition-property: opacity, background-color, transform, mix-blend-mode;
...
}
+ .cursor--clicked {
+ transform: translate(-50%, -50%) scale(0.9);
+ background-color: #fefefe;
+ }
...
const Cursor = () => {
...
+ const [clicked, setClicked] = useState(false);
const addEventListeners = () => {
...
+ document.addEventListener("mousedown", onMouseDown);
+ document.addEventListener("mouseup", onMouseUp);
};
const removeEventListeners = () => {
...
+ document.removeEventListener("mousedown", onMouseDown);
+ document.removeEventListener("mouseup", onMouseUp);
};
+
+ const onMouseDown = () => {
+ setClicked(true);
+ };
+
+ const onMouseUp = () => {
+ setClicked(false);
+ };
...
const cursorClasses = classNames(
'cursor',
{
+ 'cursor--clicked': clicked,
'cursor--hidden': hidden
}
);
...
마우스 클릭은
mousedown
및 mouseup
이벤트에 의해 처리됩니다. 마우스를 클릭하면 커서의 눈금이 0.9
로, 배경이 #fefefe
로 변경됩니다.마지막 애니메이션으로 넘어갑시다!
이제 링크가 떠 있을 때 몇 가지 효과를 추가합니다.
...
+ .cursor--link-hovered {
+ transform: translate(-50%, -50%) scale(1.25);
+ background-color: #fefefe;
+ }
+
+ a {
+ text-decoration: underline;
+ color: #fefefe;
+ }
...
const Cursor = () => {
...
+ const [linkHovered, setLinkHovered] = useState(false);
useEffect(() => {
addEventListeners();
+ handleLinkHoverEvents();
return () => removeEventListeners();
}, []);
+
...
+
+ const handleLinkHoverEvents = () => {
+ document.querySelectorAll("a").forEach(el => {
+ el.addEventListener("mouseover", () => setLinkHovered(true));
+ el.addEventListener("mouseout", () => setLinkHovered(false));
+ });
+ };
const cursorClasses = classNames(
'cursor',
{
'cursor--clicked': clicked,
'cursor--hidden': hidden,
+ 'cursor--link-hovered': linkHovered
}
);
...
}
ReactDOM.render(
<div className="App">
+ <a>This is a link</a>
<Cursor/>
</div>,
document.getElementById('root')
);
구성 요소가 마운트되면
handleLinkHoverEvents
모든 링크 요소에 이벤트 수신기를 추가합니다. 링크가 가리키면 cursor--link-hovered
클래스가 추가됩니다.마지막 단계에서는 모바일/터치 장치에서 렌더링
<Cursor/>
하지 않습니다.+ const isMobile = () => {
+ const ua = navigator.userAgent;
+ return /Android|Mobi/i.test(ua);
+ };
const Cursor = () => {
+ if (typeof navigator !== 'undefined' && isMobile()) return null;
...
}
...
그리고 끝났습니다! 전체 코드펜 예제는 다음과 같습니다.
사용자 지정 커서 애니메이션을 추가하는 것은 생각보다 어렵지 않습니다. 이 문서가 자신의 커서를 사용자 지정하기 위해 수행할 수 있는 작업에 대한 기본 아이디어를 제공하기를 바랍니다.
읽어 주셔서 감사합니다!
Reference
이 문제에 관하여(React Hooks⚡️를 사용한 멋진 애니메이션 커서), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/andrewchmr/awesome-animated-cursor-with-react-hooks-5ec3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)