๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
EFFECT

[EFFECT] ๋งˆ์šฐ์Šค ํšจ๊ณผ 05 : ๊ธฐ์šธ๊ธฐ ํšจ๊ณผ / ๊ธ€์”จ ๋ฐ˜์ „ ํšจ๊ณผ

by _ํ† ๋งคํ†  2022. 9. 29.
728x90

๐Ÿ–ฑ ๋งˆ์šฐ์Šค ํšจ๊ณผ : ๊ธฐ์šธ๊ธฐ ํšจ๊ณผ / ๊ธ€์”จ ๋ฐ˜์ „ ํšจ๊ณผ ๐Ÿ–ฑ

์ด๋ฒˆ ์‹œ๊ฐ„์—๋Š” ์ด๋ฏธ์ง€์™€ ํ…์ŠคํŠธ์—๊ฒŒ 3dํšจ๊ณผ๋ฅผ ์ค€ ๋’ค ๋งˆ์šฐ์Šค๊ฐ€ ์›€์ง์ผ ๋•Œ ํ•จ๊ป˜ ๊ธฐ์šธ์–ด์ง€๋Š” ํšจ๊ณผ๋ฅผ ์„ค์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋งˆ์šฐ์Šค ์˜์—ญ์ด ์ด๋ฏธ์ง€์— ์˜ค๋ฒ„๋˜์—ˆ์„ ๋•Œ ์ƒ‰์ด ๋ฐ˜์ „๋˜๋Š” ํšจ๊ณผ๋„ ์„ค์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค! ใ… ใ… 
์ ์  ์–ด๋ ค์›Œ์ง€๋„ค์šฉ,,,๐Ÿซ 


#1. HTML / CSS ์„ค์ •ํ•˜๊ธฐ

! HTML TIP !
figure๋Š” ์ด๋ฏธ์ง€๋‚˜ ๊ทธ๋ž˜ํ”„ ๋“ฑ์˜ ๋„ํ‘œ๋ฅผ ๋ฌธ์„œ์— ์‚ฝ์ž…ํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉํ•˜๋Š” ์‹œ๋ฉ˜ํ‹ฑ ํƒœ๊ทธ์ž…๋‹ˆ๋‹ค. figure๋ฅผ ํ†ตํ•ด ์ด๋ฏธ์ง€์˜ ์˜์—ญ์„ ์žก์•„์ค๋‹ˆ๋‹ค!
figcaption์€ figure์˜ ์„ค๋ช…์„ ๋„์™€์ฃผ๋Š” ์‹œ๋ฉ˜ํ‹ฑ ํƒœ๊ทธ๋ผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. figcaption์„ ํ†ตํ•ด ํ…์ŠคํŠธ์˜ ์˜์—ญ์„ ์žก์•„์ค๋‹ˆ๋‹ค~!

โœ๏ธ HTML ์Šคํฌ๋ฆฝํŠธ ๋ณด๊ธฐ
<main id="main">
    <section id="mouseType05">
        <div class="mouse__cursor"></div>
        <div class="mouse__wrap">
            <div class="mouse__img">
                <figure>
                    <img src="../assets/img/Mountian_bg04.jpg" alt="image">
                </figure>
                <figcaption>
                    <p>The way get started is to quit talking and begin doing.</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="centerPageY">0</span>px</li>
            <li>anglePageX: <span class="anglePageX">0</span>px</li>
            <li>anglePageY: <span class="anglePageY">0</span>px</li>
        </ul>
    </div>
    <!-- //mouse__info -->
</main>

! CSS TIP !
transform: translate3d(x, y, z) : x์ถ•๊ณผ y์ถ• ๊ทธ๋ฆฌ๊ณ  z์ถ•์˜ ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ๊ฐ ์„ค์ •ํ•œ ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ 3์ฐจ์› ๋ฐฉ์‹์œผ๋กœ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค.
transform: perspective(px) : ์›๊ทผ๊ฐ์„ ์ฃผ๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค. transform์˜ ์Šคํƒ€์ผ์„ 3D๋กœ ์„ค์ •ํ•ด์•ผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค!
transform-style: preserve-3d : transform์˜ ์Šคํƒ€์ผ์„ 3D๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
will-change: transform : ํ—ค๋‹น ์†์„ฑ ๊ฐ’์˜ ๋ณ€ํ™”๋ฅผ ๋ฏธ๋ฆฌ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์•Œ๋ ค์ฃผ์–ด์„œ ๋™์  ํšจ๊ณผ๊ฐ€ ๋” ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ž‘๋™๋˜๋„๋กํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ๊ณผํ•œ ์‚ฌ์šฉ์€ ์˜คํžˆ๋ ค ๊ณผ๋ถ€ํ™”๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋ฏ€๋กœ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
mix-blend-mode: difference : ํฌํ† ์ƒต์˜ ๋ธ”๋ Œ๋“œ ๋ชจ๋“œ์™€ ์œ ์‚ฌํ•˜๋ฉฐ ์„œ๋กœ ๋‹ค๋ฅธ ์š”์†Œ(ํฌํ† ์ƒต์˜ ๊ฒฝ์šฐ ๋ ˆ์ด์–ด)๋ฅผ ๊ฒน์ณ์„œ ์ƒ‰์ƒ์— ๋Œ€ํ•œ ํšจ๊ณผ๋ฅผ ์ฃผ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
filter: blur(px) grayscale(%) : ํ•„ํ„ฐํšจ๊ณผ๋กœ blur๋Š” ์ด๋ฏธ์ง€์˜ ํ๋ฆผํšจ๊ณผ, grayscale์€ ์ด๋ฏธ์ง€๋ฅผ %๊ฐ’์— ๋”ฐ๋ผ ํšŒ์ƒ‰์กฐ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.;

โœ๏ธ CSS ์Šคํฌ๋ฆฝํŠธ ๋ณด๊ธฐ : ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ / ์ปค์„œ / ์—๋‹ˆ๋ฉ”์ด์…˜ํšจ๊ณผ
 /* 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;
    /* 3dํ–ˆ์„ ๋•Œ ์šฉ๋Ÿ‰ ์ค„์—ฌ์คŒ */
    will-change: transform;
}

.mouse__img figure {
    width: 50vw;
}

.mouse__img figure::before {
    content: '';
    position: absolute;
    left: 5%;
    bottom: -30px;
    width: 90%;
    height: 40px;
    background: url(../assets/img/Mountian_bg04.jpg) center no-repeat;
    background-size: 100% 40px;
    filter: blur(10px) grayscale(50%);
    z-index: -1;
    opacity: 0.7;

} 

.mouse__img figcaption {
    position: absolute;
    left: 50%;
    top: 50%;
    font-size: 1vw;
    line-height: 1.6;
    transform: translate3d(-50%, -50%, 150px);
    padding: 1vw;
    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;
}

/* mouse__info */
.mouse__info {
    position: absolute;
    left: 20px;
    bottom: 10px;
    font-size: 14px;
    line-height: 1.6;
    color: #fff;
}

#2. JAVASCRIPT : ์Šคํฌ๋ฆฝํŠธ ์งœ๊ธฐ

์˜ค๋Š˜์˜ ์Šคํฌ๋ฆฝํŠธ ํฌ์ธํŠธ๋Š” ๋งˆ์šฐ์Šค ์ปค์„œ์˜ ์ขŒํ‘œ๊ฐ’์„ ๊ตฌํ•œ ๋’ค ๊ทธ ์ขŒํ‘œ๊ฐ’์˜ ์ตœ์†Œ/์ตœ๋Œ€๊ฐ’์„ ๊ณ ์ •ํ•˜๊ณ  ์˜ค์ฐจ๋ฒ”์œ„๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿผ ์•„๋ž˜์˜ ์ „์ฒด ์Šคํฌ๋ฆฝํŠธ์™€ ์ฃผ์„์œผ๋กœ ํ๋ฆ„์„ ํŒŒ์•…ํ•˜๋ฉด์„œ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค.

! JAVASCRIPT TIP !
let ๋ณ€์ˆ˜๋ช… = Math.max(a, b) / Math.min(a,b) : Math๋ฉ”์„œ๋“œ ์ค‘ ํ•˜๋‚˜๋กœ a, b์ค‘ ํฐ ๊ฐ’ / ์ž‘์€ ๊ฐ’์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

//01
    const mouseMove = (e) => { // == function mouseMove(){}; ์™€ ๊ฐ™๋‹ค. ์ฆ‰ ๋งˆ์šฐ์Šค๋ฅผ ์›€์ง์ผ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ํ•จ์ˆ˜๋กœ ์„ค์ •ํ•œ ๋’ค ์‹คํ–‰๋ฌธ์—์„œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ์™€ ํ•จ๊ป˜ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚จ ๊ฒƒ!

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

    //03
    //๋งˆ์šฐ์Šค ์ขŒํ‘œ ๊ธฐ์ค€์ ์„ ๊ฐ€์šด๋ฐ๋กœ ๋ณ€๊ฒฝ : ๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’์€ ํ™”๋ฉด ์ค‘์•™ ๊ธฐ์ค€ 0px
    let centerPageX = window.innerWidth/2 - mousePageX;
    let centerPageY = window.innerHeight/2 - mousePageY;

    //04
    //๋งˆ์šฐ์Šค ์ขŒํ‘œ๊ฐ’์ด ์ตœ์†Œ๊ฐ’์€ -100 ์ตœ๋Œ€๊ฐ’์€ 100์ด ๋˜๋„๋ก ์„ค์ • : ์ขŒํ‘œ๊ฐ’์ด ์ปค์งˆ ๊ฒฝ์šฐ ์ด๋ฏธ์ง€ ์›€์ง์ž„๋„ ์ปค์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋’ค์ง‘ํ˜€ ๋ฒ„๋ฆฌ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น€ ๋•Œ๋ฌธ์— ์ตœ์†Œ, ์ตœ๋Œ€๊ฐ’์„ ๊ตฌํ•ด์ฃผ๋Š” ๊ฒƒ.
    //Math.max == ๋ฉ”์„œ๋“œ ์•ˆ์˜ ๊ฐ’ ์ค‘ ์ตœ๋Œ€๊ฐ’์„ ๋ฐ˜ํ™˜(a, b์ค‘ ๋” ํฐ ๊ฐ’ ์„ค์ •) / Math.min == ๋ฉ”์„œ๋“œ ์•ˆ์˜ ๊ฐ’ ์ค‘ ์ตœ์†Œ๊ฐ’์„ ๋ฐ˜ํ™˜(a, b์ค‘ ๋” ์ž‘์€ ๊ฐ’ ์„ค์ •)
    //Math.min์ด ๋จผ์ € ๊ตฌํ•ด์ง€๊ณ  Math.max๊ฐ€ ๊ตฌํ•ด์ง„๋‹ค. ์ฆ‰ min์—์„œ 100๋ณด๋‹ค ์ปค์ง€์ง€ ๋ชปํ•˜๋„๋ก ์ตœ์†Œ 100์„ ๊ณ ์ •ํ–ˆ์œผ๋ฏ€๋กœ ์ขŒํ‘œ๊ฐ’์ด 100์„ ๋„˜์–ด๊ฐ€๋”๋ผ๋„ 100์œผ๋กœ ๊ณ ์ •์ด ๋˜์–ด ์ตœ๋Œ€๊ฐ’์ด 100์œผ๋กœ ์„ค์ •๋œ๋‹ค. ๊ทธ ๋’ค max์—์„œ ์ขŒํ‘œ๊ฐ’์ด -100๋ณด๋‹ค ์ž‘์•„์งˆ ๊ฒฝ์šฐ ์ตœ๋Œ€๊ฐ’์€ -100์œผ๋กœ ๊ณ ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์†Ÿ๊ฐ’์€ -100์ด ์„ค์ •๋œ๋‹ค. 
    let maxPageX =  Math.max(-100, Math.min(100,centerPageX));
    let maxPageY = Math.max(-100, Math.min(100,centerPageY)); // centerPageY์™€ 100์ค‘ ์ž‘์€ ๊ฐ’ ์„ ํƒํ•œ ๋’ค -100๊ณผ ํ•ด๋‹น ๊ฐ’ ์ค‘ ํฐ ๊ฐ’์„ ์„ ํƒ!

    //05
    //๊ฐ๋„ ์ค„์ด๋Š” ์„ค์ • : ์œ„์˜ ๊ฐ’๋„ ํฐ ํŽธ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋” ๊ฐ๋„๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•จ.
    let anglePageX = maxPageX * 0.3;
    let anglePageY = maxPageY * 0.3;

    //06
    //๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์›€์ง์ž„ ์„ค์ • : ๊ณ„์‚ฐ์ฒ˜๋ฆฌ ์‹œ ํ…€์„ ์ฃผ์–ด ๋ถ€๋“œ๋Ÿฌ์šด ์›€์ง์ž„์„ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.
    let softPageX = 0 , softPageY = 0;
    softPageX += (anglePageX - softPageX) * 0.4;
    softPageY += (anglePageY - softPageY) * 0.4; //์˜ค์ฐจ๋ฒ”์œ„

    //07
    //์ด๋ฏธ์ง€ ์›€์ง์ด๊ธฐ
    //์ขŒํ‘œ๊ฐ’์— -๋ฅผ ๋ถ™์—ฌ์ค€ ์ด์œ ๋Š” ์ปค์„œ์˜ ๋ฐฉํ–ฅ๋Œ€๋กœ ์›€์ง์ด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ž…๋‹ˆ๋‹ค.
    const imgMove = document.querySelector(".mouse__img");
    imgMove.style.transform = "perspective(600px) rotateX("+ -softPageY +"deg) rotateY("+ -softPageX +"deg)";

    //08
    //์ปค์„œ
    gsap.to(".mouse__cursor" , {duration : 0.3 , left: mousePageX -50, top : mousePageY -50 });

    //09
    //์ถœ๋ ฅ
    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);

#3. ๊ฒฐ๊ณผ ๋ณด๊ธฐ ๐ŸŽ‰

728x90

๋Œ“๊ธ€


Lucky Charms Rainbow
js
html
css