๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Effect/Mouse Effect

[Mouse Effect] ๋งˆ์šฐ์Šค ์ดํŽ™ํŠธ 05 - ๊ธฐ์šธ๊ธฐ ํšจ๊ณผ / ๊ธ€์”จ ๋ฐ˜์ „ ํšจ๊ณผ

by ์ฝ”๋”ฉ๊ณต์ฑ… 2022. 9. 28.
๋ฐ˜์‘ํ˜•

๋งˆ์šฐ์Šค ์ดํŽ™ํŠธ 05 : ๊ธฐ์šธ๊ธฐ ํšจ๊ณผ / ๊ธ€์”จ ๋ฐ˜์ „ ํšจ๊ณผ

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” ๋งˆ์šฐ์Šค ์ดํŽ™ํŠธ - ๊ธฐ์šธ๊ธฐ ํšจ๊ณผ ๋ฐ ๊ธ€์”จ ๋ฐ˜์ „ ํšจ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


HTML ์†Œ์Šค

header, main(๋งˆ์šฐ์Šค ์ปค์„œ & ์ด๋ฏธ์ง€ & ๋ช…์–ธ & ๋งˆ์šฐ์Šค ์ธํฌ(์ขŒํ‘œ๊ฐ’)), footer(๋ชจ๋‹ฌ ๋ฐ•์Šค) ํฌ๊ฒŒ 3๊ฐ€์ง€๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. footer์˜ ๋ชจ๋‹ฌ ๋ฐ•์Šค ๋‚ด์šฉ์€ ๋„ˆ๋ฌด ๊ธธ์–ด์ง€๋ฏ€๋กœ ์ƒ๋žตํ•œ๋‹ค. ๋ชจ๋‹ฌ ๋ฐ•์Šค๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” ์ด์ „์— ์—…๋กœ๋“œํ•œ ์Šฌ๋ผ์ด๋“œ ์ดํŽ™ํŠธ ๊ฒŒ์‹œ๋ฌผ์„ ์ฐธ์กฐํ•  ๊ฒƒ.

<body class="img04">
    <header id="header">
        <h1>JAVASCRIPT MOUSE EFFECT 05</h1>
        <p>๋งˆ์šฐ์Šค ์ดํŽ™ํŠธ - ๊ธฐ์šธ๊ธฐ ํšจ๊ณผ / ๊ธ€์”จ ๋ฐ˜์ „ ํšจ๊ณผ</p>
        <ul>
            <li><a href="mouseEffect01.html">01</a></li>
            <li><a href="mouseEffect02.html">02</a></li>
            <li><a href="mouseEffect03.html">03</a></li>
            <li><a href="mouseEffect04.html">04</a></li>
            <li class="active"><a href="mouseEffect05.html">05</a></li>
            <li><a href="mouseEffect06.html">06</a></li>
            <li><a href="mouseEffect07.html">07</a></li>
        </ul>
    </header>
    <!-- //header -->
  
    <main id="main">
      <section id="mouseType">
        <div class="mouse__cursor"></div>
        <div class="mouse__wrap">
          <div class="mouse__img">
            <figure>
              <img src="../assets/img/effect_bg06.jpg" alt="์ด๋ฏธ์ง€">
            </figure>
            <figcaption>
              <p>I never dreamed about success, I worked for it</p>
              <p>๋‚œ ๊ฒฐ์ฝ” ์„ฑ๊ณต์— ๋Œ€ํ•ด ๊ฟˆ๊พธ์ง€ ์•Š์•˜๋‹ค, ๋‚˜๋Š” ๊ฟˆ์„ ์œ„ํ•ด ํ–‰๋™ํ–ˆ๋‹ค.</p>
            </figcaption>
          </div>
        </div>
      </section>
  
      <div class="mouse__info">
        <ul>
          <li>mousePageX : <span class="mousePageX">0</span>px</li>
          <li>mousePageY : <span class="mousePageY">0</span>px</li>
          <li>centerPageX : <span class="centerPageX">0</span>px</li>
          <li>centerPageY : <span class="centerPageY">0</span>px</li>
          <li>maxPageX : <span class="maxPageX">0</span>px</li>
          <li>maxPageY : <span class="maxPageY">0</span>px</li>
          <li>anglePageX : <span class="anglePageX">0</span>px</li>
          <li>anglePageY : <span class="anglePageY">0</span>px</li>
        </ul>
      </div>
    </main>
    <!-- //main -->
  
    <footer>
        <!-- ๋ชจ๋‹ฌ ๋ฐ•์Šค ๋‚ด์šฉ ๋“ค์–ด๊ฐˆ ๊ณณ. ๊ธธ์–ด์ง€๋ฏ€๋กœ ์ƒ๋žต. -->
    </footer>
    <!-- //footer -->
  </body>

CSS ์†Œ์Šค

์ด๋ฒˆ ํฌ์ŠคํŒ… ๋งˆ์šฐ์Šค ํšจ๊ณผ 05๋ฒˆ์—์„œ ์ฒ˜์Œ ์“ฐ์ธ transform-style: preserve-3d;๋Š” transform์— 3D ํšจ๊ณผ๋ฅผ ์ ์šฉ์‹œํ‚ค๋Š” ์†์„ฑ์ด๋‹ค. ๊ณตํ†ต/์ดˆ๊ธฐํ™” CSS ์†Œ์Šค๋Š” ํ•˜๋‹จ์˜ [CSS ์†Œ์Šค ๋ณด๊ธฐ]๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

<style>
    /* mouseType */
    .mouse__wrap {
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      color: #fff;
      width: 100%;
      height: 100vh;
      overflow: hidden;
      cursor: none;
    }
    .mouse__img {
      transform: perspective(600px) rotateX(0deg) rotateY(0deg);
      transform-style: preserve-3d;
      will-change: transform;
      transition: all 0.1s;
    }
    .mouse__img figure {
      width: 50vw;
      position: relative;
    }
    .mouse__img figure::before {
      content: '';
      position: absolute;
      left: 5%;
      bottom: -30px;
      width: 90%;
      height: 40px;
      background: url(../assets/img/effect_bg06.jpg) center no-repeat;
      background-size: 100% 40px;
      filter: blur(15px) grayscale(50%);
      z-index: -1;
      opacity: 0.7;
    }
    .mouse__img figcaption {
      position: absolute;
      left: 50%;
      top: 50%;
      font-size: 16px;
      line-height: 1.6;
      transform: translate3d(-50%, -50%, 150px);
      padding: 10px;
      white-space: nowrap;
      text-align: center;
      background: rgba(0,0,0,0.4);
    }

    .mouse__cursor {
      position: absolute;
      left: 0;
      top: 0;
      width: 100px;
      height: 100px;
      border-radius: 50%;
      background: #fff;
      z-index: 1000;
      pointer-events: none;
      user-select: none;
      mix-blend-mode: difference;
    }
</style>

JS ์†Œ์Šค

๋จผ์ € e.pageX, e.pageY๋ฅผ ํ†ตํ•ด ๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’์„ ๊ตฌํ•˜๊ณ , ๋งˆ์šฐ์Šค ์ขŒํ‘œ ๊ธฐ์ค€์ ์„ ๊ฐ€์šด๋ฐ๋กœ ๋ณ€๊ฒฝํ•ด์ค€ ๋‹ค์Œ, ์ตœ์†Œ๊ฐ’์„ -100, ์ตœ๋Œ€๊ฐ’์„ 100์œผ๋กœ ์ œํ•œํ•˜์—ฌ ์›€์ง์ž„์ด ๊ฒฉํ•ด์ง€์ง€ ์•Š๋„๋ก ์„ค์ •ํ•œ๋‹ค. ์ด๋ฏธ์ง€๋ฅผ ์›€์ง์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด imgMove ์Šคํƒ€์ผ์˜ rotateX์— softPageY๊ฐ’์„, rotateY์—๋Š” -softPageX๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ์ปค์„œ๋Š” GSAP์„ ์ด์šฉํ•˜์—ฌ ์›€์ง์ž„์„ ์ฃผ๋„๋ก ํ•œ๋‹ค.

<script>
    const mouseMove = (e) => {
      // ๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’
      let mousePageX = e.pageX;
      let mousePageY = e.pageY;
  
      // ๋งˆ์šฐ์Šค ์ขŒํ‘œ ๊ธฐ์ค€์ ์„ ๊ฐ€์šด๋ฐ๋กœ ๋ณ€๊ฒฝ
      let centerPageX = window.innerWidth / 2 - mousePageX;
      let centerPageY = window.innerHeight / 2 - mousePageY;
  
      // ์ตœ์†Œ๊ฐ’์€ -100, ์ตœ๋Œ€๊ฐ’์€ 100์œผ๋กœ ์„ค์ •
      let maxPageX = Math.max(-200, Math.min(200, centerPageX));
      let maxPageY = Math.max(-200, Math.min(200, centerPageY));
  
      // ๊ฐ๋„ ์ค„์ด๋Š” ์„ค์ •
      let anglePageX = maxPageX * 0.1;
      let anglePageY = maxPageY * 0.1;
  
      // ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์„ค์ •
      let softPageX = 0, softPageY = 0;
      softPageX += (anglePageX - softPageX) * 0.4;
      softPageY += (anglePageY - softPageY) * 0.4;
  
      // ์ด๋ฏธ์ง€ ์›€์ง์ด๊ธฐ
      const imgMove = document.querySelector(".mouse__img");
      imgMove.style.transform = "perspective(600px) rotateX("+softPageY+"deg) rotateY("+ -softPageX+"deg)";
  
      // ์ปค์„œ
      gsap.to(".mouse__cursor", {duration: .3, left: mousePageX - 50, top: mousePageY - 50})
  
      // ์ถœ๋ ฅ
      document.querySelector(".mousePageX").textContent = mousePageX;
      document.querySelector(".mousePageY").textContent = mousePageY;
      document.querySelector(".centerPageX").textContent = centerPageX;
      document.querySelector(".centerPageY").textContent = centerPageY;
      document.querySelector(".maxPageX").textContent = maxPageX;
      document.querySelector(".maxPageY").textContent = maxPageY;
      document.querySelector(".anglePageX").textContent = Math.round(anglePageX);
      document.querySelector(".anglePageY").textContent = Math.round(anglePageY);
    };
  
    window.addEventListener("mousemove", mouseMove);
</script>

๊ฒฐ๊ณผ

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€


Reference Book

JavaScript
HTML
CSS
๊ด‘๊ณ  ์ค€๋น„์ค‘์ž…๋‹ˆ๋‹ค.