트렌드한 마우스 효과 적용해 보기

0 Shares
0
0
0

블로그 심심해 2탄을 준비해봤다. 이전 포스팅에서 스크롤할때 내가 현재 읽고 있는 글의 상태를 바형태로 넣어보았다. 🙂 그래도 뭔가 좀 심심하다… 이번에는 마우스커서를 바꿔보기로 해보자.
아래는 먼저 참고한 사이트의 튜토리얼이다. 음 상당히 복잡하고 어렵다… 그래서 최대한 요약해서 필요한것만 적용해보기로 했다.

심심해 1탄 프로그레스바 포스트보기
Screenshot of tympanus.net

Custom Cursor Effects – codrops

마크업 적용

전역에 들어가야 하니 헤더나 푸터에 넣고 싶은곳에 넣자.

<div class="cursor cursor--small"></div>
<canvas class="cursor cursor--canvas" resize></canvas>

스타일 적용

@media only screen and (min-width:769px) {
	body,
	a {
		cursor: none;
	}
   
	.cursor {
		position: fixed;
		left: 0;
		top: 0;
		pointer-events: none;
	}
	.cursor--small {
		width: 20px;
		height: 20px;
		left: -10px;
		top: -10px;
		border-radius: 50%;
		z-index: 99;
		background: #b7dde18c;
	}
	.cursor--canvas {
		width: 100vw;
		height: 100vh;
		z-index: 100;
	}
}

@media only screen and (max-width:768px) {
	body {
		cursor: none;
	}
	.cursor--small,
	.cursor--canvas {
		display: none;
	}
}

자바 스크립트 적용

const cursorModule = () => {
    const innerCursor = document.querySelector(".cursor--small");
	  const canvas = document.querySelector(".cursor--canvas");
		let clientX = -100;
		let clientY = -100;
		const initCursor = () => {
			document.addEventListener("mousemove", e => {
		    clientX = e.clientX;
		    clientY = e.clientY;
		  });
		  const render = () => {
		    TweenMax.set(innerCursor, {
		      x: clientX,
		      y: clientY
		    });
		    requestAnimationFrame(render);
		  };
		  requestAnimationFrame(render);
		};
		initCursor();
		let lastX = 0;
		let lastY = 0;
		let isStuck = false;
		let showCursor = false;
		let group;
		let stuckX;
		let stuckY;
		let fillOuterCursor;
		const initCanvas = () => {
			const shapeBounds = {
				width: 75,
				height: 75,
			};
			paper.setup(canvas);
			const strokeColor = 'rgba(60, 74, 83, 0.5)';
			const strokeWidth = 1;
			const segments = 8;
			const radius = 15;
			const noiseScale = 150;
			const noiseRange = 6;
			let isNoisy = false;
			const polygon = new paper.Path.RegularPolygon(
				new paper.Point(0,0),
				segments,
				radius,
			);
			polygon.strokeColor = strokeColor;
  		polygon.strokeWidth = strokeWidth;
  		polygon.smooth();
  		group = new paper.Group([polygon]);
  		group.applyMatrix = false;
			const noiseObjects = polygon.segments.map(() => new SimplexNoise());
  		let bigCoordinates = [];
			const lerp = (a, b, n) => {
				return (1 - n) * a + n * b;
			};
			const map = (value, in_min, in_max, out_min, out_max) => {
				return (
					((value - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min
				);
			};
			paper.view.onFrame = event => {
				if (!isStuck) {
			    // move circle around normally
			    lastX = lerp(lastX, clientX, 0.2);
			    lastY = lerp(lastY, clientY, 0.2);
			    group.position = new paper.Point(lastX, lastY);
			  } else if (isStuck) {
			    // fixed position on a nav item
			    lastX = lerp(lastX, stuckX, 0.08);
			    lastY = lerp(lastY, stuckY, 0.08);
			    group.position = new paper.Point(lastX, lastY);
			  }
				if (isStuck && polygon.bounds.width < shapeBounds.width) {
					// scale up the shape
					polygon.scale(1.15);
				} else if (!isStuck && polygon.bounds.width > 30) {
					// remove noise
					if (isNoisy) {
					  polygon.segments.forEach((segment, i) => {
					    segment.point.set(bigCoordinates[i][0], bigCoordinates[i][1]);
					  });
					  isNoisy = false;
					  bigCoordinates = [];
					}
					// scale down the shape
					const scaleDown = 0.92;
					polygon.scale(scaleDown);
				}
				// while stuck and big, apply simplex noise
			  if (isStuck && polygon.bounds.width >= shapeBounds.width) {
			    isNoisy = true;
			    // first get coordinates of large circle
			    if (bigCoordinates.length === 0) {
			      polygon.segments.forEach((segment, i) => {
			        bigCoordinates[i] = [segment.point.x, segment.point.y];
			      });
			    }
			    // loop over all points of the polygon
			    polygon.segments.forEach((segment, i) => {
			      // get new noise value
			      // we divide event.count by noiseScale to get a very smooth value
			      const noiseX = noiseObjects[i].noise2D(event.count / noiseScale, 0);
			      const noiseY = noiseObjects[i].noise2D(event.count / noiseScale, 1);
			      // map the noise value to our defined range
			      const distortionX = map(noiseX, -1, 1, -noiseRange, noiseRange);
			      const distortionY = map(noiseY, -1, 1, -noiseRange, noiseRange);
			      // apply distortion to coordinates
			      const newX = bigCoordinates[i][0] + distortionX;
			      const newY = bigCoordinates[i][1] + distortionY;
			      // set new (noisy) coordindate of point
			      segment.point.set(newX, newY);
			    });
			  }
			  polygon.smooth();
			}
		}
		initCanvas();
		const initCursorHovers = () => {
			const handleCanvasCursorMouseEnter = e => {
				const navItem = e.currentTarget;
				const navItemBox = navItem.getBoundingClientRect();
				stuckX = Math.round(navItemBox.left + navItemBox.width / 2);
				stuckY = Math.round(navItemBox.top + navItemBox.height / 2);
				isStuck = true;
				TweenMax.to(innerCursor, 1, {background:'rgba(60, 74, 83, 0.5)', scale:0.25, ease: Expo.easeOut});
			};
			const handleCanvasCursorMouseLeave = () => {
				isStuck = false;
				TweenMax.to(innerCursor, 1, {background:'#b7dde1', scale:1, ease: Expo.easeOut});
			};
			const handleBasicCursorMouseEnter = e => {
				TweenMax.to(innerCursor, 1, {background:'rgba(60, 74, 83, 0.5)', scale:2, ease: Expo.easeOut});
			};
			const handleBasicCursorMouseLeave = () => {
				TweenMax.to(innerCursor, 1, {background:'#b7dde1', scale:1, ease: Expo.easeOut});
			};
      const $links = document.querySelectorAll('.link');
			$links.forEach(link => {
				link.addEventListener("mouseenter", handleCanvasCursorMouseEnter);
				link.addEventListener("mouseleave", handleCanvasCursorMouseLeave);
			});
      const $otherLinks = document.querySelectorAll('.another-link');
			$otherLinks.forEach(link => {
				link.addEventListener("mouseenter", handleBasicCursorMouseEnter);
				link.addEventListener("mouseleave", handleBasicCursorMouseLeave);
			});
		}
		initCursorHovers();
}
window.onload = () => {
  cursorModule();
}

워드프레스 함수에서 JS 불러오기

add_action( 'wp_enqueue_scripts', 'Scripts_mouse_effect' );
function Scripts_mouse_effect() {
    wp_enqueue_script('mouse-e-script', get_stylesheet_directory_uri() . '/js/mouse-e.js', array(), '1.0.0', true );
}

라이브러리 가져오기

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.2/paper-full.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.4.0/simplex-noise.min.js"></script>

링크호버 효과 확인

[PC에서만 확인가능]

링크 호버효과 추가 클래스 link -> link A
링크 호버효과 추가 클래스 another-link -> another-link B

마우스적용화면

다른 스타일 데모 보기

Last updated on: 2022-01-29, am 12:38
Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

You May Also Like