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

[Mouse Effect] ๋งˆ์šฐ์Šค ์ดํŽ™ํŠธ 04 - ์ด๋ฏธ์ง€ ํšจ๊ณผ

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

๋งˆ์šฐ์Šค ์ดํŽ™ํŠธ 04 : ์ด๋ฏธ์ง€ ํšจ๊ณผ

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” GSAP๋ฅผ ์ด์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ์˜์—ญ ๋‚ด๋ถ€์—์„œ๋งŒ ๋งˆ์šฐ์Šค ์ปค์„œ๊ฐ€ ๋ฐ”๋€Œ๊ณ  ๋งˆ์šฐ์Šค ์œ„์น˜์— ๋”ฐ๋ผ ์‚ฌ์ง„๋„ ๊ฐ™์ด ๋ฏธ์„ธํ•˜๊ฒŒ ์›€์ง์ด๋Š” ํšจ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


HTML ์†Œ์Šค

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

<body class="img04">
    <header id="header">
        <h1>JAVASCRIPT MOUSE EFFECT 04</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 class="active"><a href="mouseEffect04.html">04</a></li>
            <li><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">
              <figure>
                    <img src="../assets/img/effect_bg02.jpg" alt="์ด๋ฏธ์ง€">
                    <figcaption>
                        <p>I never dreamed about success, I worked for it</p>
                        <p>๋‚œ ๊ฒฐ์ฝ” ์„ฑ๊ณต์— ๋Œ€ํ•ด ๊ฟˆ๊พธ์ง€ ์•Š์•˜๋‹ค, ๋‚˜๋Š” ๊ฟˆ์„ ์œ„ํ•ด ํ–‰๋™ํ–ˆ๋‹ค.</p>
                    </figcaption>
              </figure>
            </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>
            </ul>
        </div>
    </main>
    <!-- //main -->

    <footer>
        <!-- ๋ชจ๋‹ฌ ๋ฐ•์Šค ๋‚ด์šฉ ๋“ค์–ด๊ฐˆ ๊ณณ. ๊ธธ์–ด์ง€๋ฏ€๋กœ ์ƒ๋žต. -->
    </footer>
    <!-- //footer -->
</body>

CSS ์†Œ์Šค

์ด๋ฒˆ ํฌ์ŠคํŒ… ๋งˆ์šฐ์Šค ํšจ๊ณผ 04๋ฒˆ์—์„œ ์ฒ˜์Œ ์“ฐ์ธ object-fit: cover;๋Š” background์˜ cover์™€ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ์ง€๋‹Œ๋‹ค. ๊ณตํ†ต/์ดˆ๊ธฐํ™” CSS ์†Œ์Šค๋Š” ํ•˜๋‹จ์˜ [CSS ์†Œ์Šค ๋ณด๊ธฐ]๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜์—ฌ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

/* mouseType */
.mouse__wrap {
    width: 100%;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    overflow: hidden;
    flex-direction: column;
}
.mouse__wrap figure {
    width: 50vw;
    height: 50vh;
    position: relative;
    overflow: hidden;
    transition: transform 500ms ease;
    cursor: none;
}
.mouse__wrap figure:hover {
    transform: scale(1.025);
}
.mouse__wrap figure img {
    position: absolute;
    left: -5%;
    top: -5%;
    width: 110%;
    height: 110%;
    object-fit: cover;  /* background cover์™€ ๊ฐ™์€ ํšจ๊ณผ, ์ด๋ฏธ์ง€์— ์ค„ ์ˆ˜ ์žˆ์Œ  */
}
.mouse__wrap figure figcaption {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    font-size: 16px;
    white-space: nowrap;
    line-height: 1.4;
    font-weight: 300;
}

.mouse__cursor {
    position: absolute;
    left: 0;
    top: 0;
    width: 20px;
    height: 20px;
    background: #fff;
    border-radius: 50%;
    z-index: 1000;
    user-select: none;
    pointer-events: none;
}

JS ์†Œ์Šค

๋งˆ์šฐ์Šค ์ปค์„œ์˜ ์›€์ง์ž„์„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ํ•ด์ค„ gsap์„ ์ด์šฉํ•˜๊ณ , ๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’์„ ๊ตฌํ•˜๊ณ , ์ขŒํ‘œ๊ฐ’์„ ๊ฐ€์šด๋ฐ๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ, ์ด๋ฏธ์ง€ ๋˜ํ•œ gsap์œผ๋กœ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์›€์ง์—ฌ์ฃผ๋ฉฐ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋งˆ์šฐ์Šค ํŽ˜์ด์ง€ ์ขŒํ‘œ๊ฐ’์„ ์ถœ๋ ฅํ•ด์ค€๋‹ค.


    const cursor = document.querySelector(".mouse__cursor");
    const cursorRect = cursor.getBoundingClientRect();

    document.querySelector(".mouse__wrap figure").addEventListener("mousemove", (e) => {
      // ์ปค์„œ
      gsap.to(cursor, {
        duration: .5,
        left: e.pageX - cursorRect.width/2,
        top: e.pageY - cursorRect.height/2,
      });

      // ๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’
      let mousePageX = e.pageX;
      let mousePageY = e.pageY;

      // ์ „์ฒด ๊ฐ€๋กœ
      // window.innerWidth  // ๋ธŒ๋ผ์šฐ์ € ํฌ๊ธฐ 1920 (๋ธŒ๋ผ์šฐ์ € ์ค„์–ด๋“ค๋ฉด ๊ฐ’๋„ ์ค„์–ด๋“ ๋‹ค.)
      // window.outerWidth  // ๋ธŒ๋ผ์šฐ์ € ํฌ๊ธฐ(์Šคํฌ๋กค๋ฐ” ํฌํ•จ) 1920 (๋ธŒ๋ผ์šฐ์ € ์ค„์–ด๋“ค๋ฉด ๊ฐ’๋„ ์ค„์–ด๋“ ๋‹ค. / ์Šคํฌ๋กค๋ฐ” ์ƒ๊ธฐ๋ฉด ๊ฐ’์ด ์ค„์–ด๋“ ๋‹ค.)
      // wiudow.screen.width  // ํ™”๋ฉด ํฌ๊ธฐ 1920 (๋ธŒ๋ผ์šฐ์ € ์ค„์–ด๋“ค์–ด๋„ ๊ฐ’ ๊ทธ๋Œ€๋กœ 1920)

      // ๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’ ๊ฐ€์šด๋ฐ๋กœ ์ดˆ๊ธฐํ™”
      // ์ „์ฒด ๊ธธ์ด / 2 - ๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’ == 0 (์ „์ฒด ๊ธธ์ด รท 2 - ๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’ = 0)
      let centerPageX = window.innerWidth / 2 - mousePageX;
      let centerPageY = window.innerHeight / 2 - mousePageY;

      // ์ด๋ฏธ์ง€ ์›€์ง์ด๊ธฐ (๊ธฐ์กด JS ๋ฐฉ์‹)
      const imgMove = document.querySelector(".mouse__wrap figure img");
      // imgMove.style.transform = "translate("+ centerPageX/20 +"px, "+ centerPageY/20 +"px)";

      // ์ด๋ฏธ์ง€ ์›€์ง์ด๊ธฐ - GSAP ๋ฐฉ์‹ (ํ›จ์”ฌ ๋” ๋ถ€๋“œ๋Ÿฌ์›Œ์ง)
      gsap.to(imgMove, {
        duration: 0.3,
        x: centerPageX/20,
        y: centerPageY/20
      })

      // ์ถœ๋ ฅ
      document.querySelector(".mousePageX").textContent = mousePageX;
      document.querySelector(".mousePageY").textContent = mousePageY;
      document.querySelector(".centerPageX").textContent = centerPageX;
      document.querySelector(".centerPageY").textContent = centerPageY;
    });

๊ฒฐ๊ณผ

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€


Reference Book

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