๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Javascript Effect

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋งˆ์šฐ์Šค ํšจ๊ณผ : ๋งˆ์šฐ์Šค ๋”ฐ๋ผ๋‹ค๋‹ˆ๊ธฐ(GSAP)

by ์ฝ”ํŒŒ์นด 2022. 9. 18.
728x90

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ : ๋งˆ์šฐ์Šค ํšจ๊ณผ : ๋งˆ์šฐ์Šค ๋”ฐ๋ผ๋‹ค๋‹ˆ๊ธฐ(GSAP)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋‹ค์–‘ํ•œ ํšจ๊ณผ๋“ค ์ค‘, ๋งˆ์šฐ์Šค ํšจ๊ณผ์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” GSAP๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋” ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์›€์ง์ด๋Š” ์ปค์„œ๋ฅผ ์ž‘์—…ํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


1. HTML ์†Œ์Šค

<section id="mouseType02">
    <div class="mouse__cursor"></div>
    <div class="mouse__cursor2"></div>
    <div class="mouse__wrap">
        <p>Only <span class="style1">I can change</span> my life, <span class="style2">No one can</span> do it <span class="style3">for me</span></p>
        <p><span class="style4">์˜ค์ง ๋‚˜๋งŒ์ด</span> ๋‚ด ์ธ์ƒ์„ <span class="style5">๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.</span> <span class="style6">์•„๋ฌด๋„</span> ๋‚  ๋Œ€์‹ ํ•  ์ˆ˜๋Š” ์—†๋‹ค</p>
    </div>
</section>

์ด๋ฒˆ์—๋Š” ์ปค์„œ๋ฅผ ๋‘ ๊ฐœ ์ž‘์—…ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. HTML๋กœ ๊ตฌ์กฐ๋ฅผ ์žก์€ ํ›„, CSS๋กœ ์Šคํƒ€์ผ์„ ์ ์šฉํ•ด ์ค๋‹ˆ๋‹ค.

2. CSS ์†Œ์Šค

.mouse__wrap {
    width: 100%;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    overflow: hidden;
    flex-direction: column;
    /* cursor: none; */
}
.mouse__wrap p {
    font-size: 2vw;
    line-height: 2;
    font-weight: 300;
}
.mouse__wrap p:last-child {
    font-size: 3vw;
}
.mouse__wrap p span {
    border-bottom: 0.35vw dashed rgb(77, 46, 128);
    color: rgb(77, 46, 128);
}
@media (max-width: 800px) {
    .mouse__wrap p {
        font-size: 20px;
        padding: 0 20px;
        text-align: center;
        line-height: 1.5;
        word-break: keep-all;
        margin-bottom: 10px;
    }
    .mouse__wrap p:last-child {
        font-size: 40px;
    }
}
.mouse__cursor {
    position: absolute;
    left: 0;
    top: 0;
    width: 10px;
    height: 10px;
    z-index: 9999;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.1);
    user-select: none;
    pointer-events: none;
    transition: transform 0.3s, opacity 0.2s;
}
.mouse__cursor2 {
    position: absolute;
    left: 0;
    top: 0;
    width: 30px;
    height: 30px;
    z-index: 9998;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.3);
    user-select: none;
    pointer-events: none;
    transition: transform 0.3s, opacity 0.2s;
}
.mouse__cursor.menuactive {
    transform: scale(0);
}
.mouse__cursor2.menuactive {
    transform: scale(2) rotate(720deg);
    background: rgba(164, 123, 22, 0.6);
    border-radius: 0;
}
.mouse__cursor.active {
    transform: scale(0);
}
.mouse__cursor2.active {
    transform: scale(10);
    background: rgba(77, 46, 128, 0.6);
}
.mouse__cursor.sourceactive {
    transform: scale(0);
}
.mouse__cursor2.sourceactive {
    transform: scaleX(3);
    background: rgba(240, 92, 92, 0.6);
}

์ฒซ๋ฒˆ์งธ ์ปค์„œ๋Š” ์ž‘์€ ๋™๊ทธ๋ผ๋ฏธ, ๋‘๋ฒˆ์งธ ์ปค์„œ๋Š” ํฐ ๋™๊ทธ๋ผ๋ฏธ๋กœ ์Šคํƒ€์ผ์„ ์ ์šฉํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ปค์„œ๊ฐ€ ํ—ค๋”์˜ ๋ฉ”๋‰ด์— ์œ„์น˜ํ–ˆ์„ ๋•Œ, ๋ช…์–ธ์˜ span ํƒœ๊ทธ ์•ˆ์— ์œ„์น˜ํ–ˆ์„ ๋•Œ, ํ‘ธํ„ฐ์˜ ์†Œ์Šค ๋ณด๊ธฐ ๋ฒ„ํŠผ์— ์œ„์น˜ํ–ˆ์„ ๋•Œ 3๊ฐ€์ง€ ๋ชจ์–‘์œผ๋กœ ๋ณ€ํ˜•๋  ์ˆ˜ ์žˆ๋„๋ก menuactive, active, sourceactive ํด๋ž˜์Šค๋ฅผ ๊ฐ๊ฐ ์ž‘์—…ํ•ด ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

3. JAVASCRIPT ์†Œ์Šค

3-1) ์„ ํƒ์ž ๋งŒ๋“ค์–ด ์ฃผ๊ธฐ

const cursor = document.querySelector(".mouse__cursor");
const cursor2 = document.querySelector(".mouse__cursor2");
const menu = document.querySelectorAll("#header ul li");
const span = document.querySelectorAll(".mouse__wrap span");
const sourceBtn = document.querySelectorAll(".modal__btn");

๋งˆ์šฐ์Šค ์ปค์„œ, ๋ฉ”๋‰ด, ๋ช…์–ธ, ์†Œ์Šค ๋ณด๊ธฐ ๋ฒ„ํŠผ์— ๋Œ€ํ•œ ์„ ํƒ์ž๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

3-2) ๋งˆ์šฐ์Šค ์˜ค๋ฒ„ ์ด๋ฒคํŠธ ๋งŒ๋“ค์–ด ์ฃผ๊ธฐ

window.addEventListener("mousemove", (e) => {});

์ด์ œ addEventListener๋ฅผ ์ด์šฉํ•˜์—ฌ ๋งˆ์šฐ์Šค ์˜ค๋ฒ„ ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค. ์•„๋ž˜ ์†Œ์Šค๋“ค์€ ๋งˆ์šฐ์Šค ์˜ค๋ฒ„ ์ด๋ฒคํŠธ ์•ˆ์—์„œ ์ž‘์—…ํ•œ ์†Œ์Šค๋“ค์ž…๋‹ˆ๋‹ค.

    // ์ปค์„œ ์ขŒํ‘œ๊ฐ’ ํ• ๋‹น
    // cursor.style.left = e.pageX - 5 + "px";
    // cursor.style.top = e.pageY - 5 + "px";
    // cursor2.style.left = e.pageX - 15 + "px";
    // cursor2.style.top = e.pageY - 15 + "px";

    // GSAP
    gsap.to(cursor, { duration: 0.3, left: e.pageX - 5, top: e.pageY - 5 });
    gsap.to(cursor2, { duration: 0.8, left: e.pageX - 15, top: e.pageY - 15 });

์œ„์˜ ๋ฐฉ๋ฒ•์œผ๋กœ ์ง์ ‘ ์ปค์„œ ์ขŒํ‘œ๊ฐ’์„ ํ• ๋‹นํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ๋” ๋ถ€๋“œ๋Ÿฌ์šด ์›€์ง์ž„์„ ์œ„ํ•˜์—ฌ GSAP๋ฅผ ์ด์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. GSAP๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์Šคํฌ๋ฆฝํŠธ ๋งํฌ๋ฅผ ๊ผญ ๊ฑธ์–ด ์ค์‹œ๋‹ค.

// ๋ฉ”๋‰ด์— ์ปค์„œ๋ฅผ ์˜ค๋ฒ„ํ–ˆ์„ ๋•Œ
menu.forEach((menu) => {
    menu.addEventListener("mouseenter", () => {
        cursor.classList.add("menuactive");
        cursor2.classList.add("menuactive");
    });
    menu.addEventListener("mouseleave", () => {
        cursor.classList.remove("menuactive");
        cursor2.classList.remove("menuactive");
    });
});

// ์ฝ˜ํ…์ธ ์— ์ปค์„œ๋ฅผ ์˜ค๋ฒ„ํ–ˆ์„ ๋•Œ
span.forEach((span) => {
    span.addEventListener("mouseenter", () => {
        cursor.classList.add("active");
        cursor2.classList.add("active");
    });
    span.addEventListener("mouseleave", () => {
        cursor.classList.remove("active");
        cursor2.classList.remove("active");
    });
});

// ์†Œ์Šค ๋ณด๊ธฐ ๋ฒ„ํŠผ์— ์ปค์„œ๋ฅผ ์˜ค๋ฒ„ํ–ˆ์„ ๋•Œ
sourceBtn.forEach((source) => {
    source.addEventListener("mouseenter", () => {
        cursor.classList.add("sourceactive");
        cursor2.classList.add("sourceactive");
    });
    source.addEventListener("mouseleave", () => {
        cursor.classList.remove("sourceactive");
        cursor2.classList.remove("sourceactive");
    });
});

๋งˆ์šฐ์Šค ์˜ค๋ฒ„ ์ด๋ฒคํŠธ ๋ฉ”์„œ๋“œ๋Š” mouseenter, mouseover ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์ง€๋งŒ, mouseenter ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋‘ ๋ฉ”์„œ๋“œ์˜ ์ฐจ์ด๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ : ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ ๋ฉ”์„œ๋“œ : mouseover VS mouseenter๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.
๋ฉ”๋‰ด ๋ฒ„ํŠผ, ๋ช…์–ธ, ์†Œ์Šค ๋ณด๊ธฐ ๋ฒ„ํŠผ ๊ฐ๊ฐ์— ์ปค์„œ๋ฅผ ์œ„์น˜ํ–ˆ์„ ๋•Œ, ๊ฐ๊ฐ์— ํ•ด๋‹นํ•˜๋Š” active ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ๊ณ , ์ปค์„œ์˜ ์œ„์น˜๊ฐ€ ๋ฒ—์–ด๋‚˜๋ฉด active ํด๋ž˜์Šค๋ฅผ ์ œ๊ฑฐํ•˜๋„๋ก ์ž‘์—…ํ•ด ์ค๋‹ˆ๋‹ค.


๊ฒฐ๊ณผ

728x90

๋Œ“๊ธ€

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿฆ™

CSS
๊ด‘๊ณ  ์ค€๋น„์ค‘