본문 바로가기
이펙트 만들기/마우스 이펙트 만들기

마우스 이펙트 05

by 코딩달림 2022. 9. 28.
728x90

마우스 이펙트

자바스크립트를 이용한 마우스 효과 만들기 입니다.


마우스 이펙트 05 - 기울기 효과 및 글씨 반전 효과

이미지에 3D 효과가 적용되어 있어 마우스 커서를 움직일 시 커서의 위치에 따라 이미지가 움직이며 이미지에 커서를 겹칠 시 커서 안의 이미지에 효과가 발생합니다.


1. 이미지를 3D로 바꾸기

이미지가 움직일 때 3D처럼 보이도록 CSS로 효과를 줍니다.

소스보기
-HTML-
<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_bg09-min.jpg" alt="이미지">
                </figure>
                <figcaption>
                    <p>If you can dream it, you can do 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>
-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;
    will-change: transform;
    transition: all 0.3s;
}

.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_bg09-min.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: 1vw;
    line-height: 1.6;
    transform: translate3d(-50%, -50%, 100px);
    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 {
    position: absolute;
    left: 20px;
    bottom: 10px;
    font-size: 14px;
    line-height: 1.6;
    color: #fff;
}

이번 효과는 사진에 3D 효과를 주기 위해 preserve-3d와 perspective 효과를 주어야 합니다.
preserve-3d 속성은 요소에 Z축을 추가해 3D 좌표값을 생성하며, perspective는 이미지를 보는 시점을 조절해 요소를 3D처럼 보도록 해줍니다.

※ 3D를 구성하는 요소

3D를 구성하는 요소는 세가지가 있습니다.
 - transform-style - preserve-3d : 요소의 자식이 3D 공간에 배치하도록 합니다.
 - perspective : 거리(length)만큼 투시점이 적용되어 3d 효과를 갖습니다. none일 시 투시점 거리를 설정하지 않습니다.
 - transform - rotateX, rotateY, rotateZ : 각 축의 좌표로 요소를 회전시킵니다.

그림자 효과는 이미지를 가상요소로 만들어 filter의 블러효과와 그레이스케일, 그리고 opacity로 이미지를 연하게 만들면 그럴듯한 효과가 갖춰집니다.

※ filter효과

속성 옵션 효과
filter none 기본값. 효과를 지정하지 않습니다
blur(px) 이미지에 흐림 효과를 적용합니다. 값이 클수록 흐림이 더 커집니다.
값을 지정하지 않으면 0이 사용됩니다.
brightness(%) 이미지의 밝기를 조정합니다.
0 %는 이미지를 완전히 검은색으로 만듭니다.
100 % (1)가 기본값이며 원본 이미지를 나타냅니다.
100 %가 넘는 값은 더 밝은 결과를 제공합니다.
contrast(%) 이미지의 대비를 조정합니다.
0 %는 이미지를 완전히 검은 색으로 만듭니다.
100 % (1)가 기본값이며 원본 이미지를 나타냅니다.
100 %가 넘는 값을 사용하면보다 명암 대비가 향상됩니다.
drop-shadow
(h- 그림자 v- 그림자 흐림 확산 색상)
이미지에 그림자 효과를 적용합니다.
가능한 값 :
h- 그림자-필수. 가로 그림자의 픽셀 값을 지정합니다. 음수 값은 그림자를 이미지 왼쪽에 배치합니다.
v- 그림자-필수. 수직 그림자의 픽셀 값을 지정합니다. 음수 값은 그림자를 이미지 위에 놓습니다.
흐림-선택 사항. 이것은 세 번째 값이며 픽셀 단위 여야합니다. 그림자에 흐림 효과를 추가합니다. 값이 클수록 흐림이 더 커집니다 (그림자가 커지고 밝아짐). 음수 값은 허용되지 않습니다. 값을 지정하지 않으면 0이 사용됩니다 (그림자의 가장자리가 뾰족합니다).
스프레드-선택 사항. 이것은 네 번째 값이며 픽셀 단위 여야합니다. 양수 값은 그림자가 확장되고 커지게하고 음수 값은 그림자가 축소됩니다. 지정하지 않으면 0이됩니다 (그림자의 크기는 요소와 동일 함).
이 필터는 box-shadow 속성과 유사합니다.
grayscale(%) 이미지를 회색조로 변환합니다.
0 % (0)가 기본값이며 원본 이미지를 나타냅니다.
100 %는 이미지를 완전히 회색으로 만듭니다 (흑백 이미지에 사용).
참고 : 음수 값은 허용되지 않습니다.
hue-rotate(deg) 이미지에 색조 회전을 적용합니다. 이 값은 이미지 샘플이 조정될 색상 원 주위의 각도 수를 정의합니다. 0deg가 기본값이며 원본 이미지를 나타냅니다.
참고 : 최대 값은 360 도입니다.
invert(%) 이미지의 샘플을 반전시킵니다.
0 % (0)가 기본값이며 원본 이미지를 나타냅니다.
100 %는 이미지를 완전히 반전시킵니다.
참고 : 음수 값은 허용되지 않습니다.
opacity(%) 이미지의 불투명도 레벨을 설정합니다. 불투명도 수준은 다음과 같은 투명도 수준을 나타냅니다.
0 %는 완전히 투명합니다.
100 % (1)가 기본값이며 원본 이미지를 나타냅니다 (투명도 없음).
참고 : 음수 값은 허용되지 않습니다.
팁 :이 필터는 불투명도 속성과 유사합니다.
saturate(%) 이미지를 포화시킵니다.
0 % (0)는 이미지의 채도를 완전히 불포화시킵니다.
100 %가 기본값이며 원본 이미지를 나타냅니다.
100 %가 넘는 값은 과포화 결과를 제공합니다.
참고 : 음수 값은 허용되지 않습니다.
sepia(%) 이미지를 세피아로 변환합니다.
0 % (0)가 기본값이며 원본 이미지를 나타냅니다.100 %는 이미지를 완전히 세피아로 만듭니다.
참고 : 음수 값은 허용되지 않습니다.

출처 : 이 곳

마지막으로 커서 이미지 반전 효과는 mix-blend-mode: difference 효과를 사용하면 됩니다. 믹스 블랜드 모드는 이미지의 겹치는 부분에 블랜드 효과를 부여하는 속성입니다.

※ mix-blend-mode

이미지 등의 요소가 겹치는 경우 중첩된 상태를 표시하는 방법입니다.

mix-blend-mode: normal : 아무효과가 없는 상태로 기본 효과입니다.
mix-blend-mode: 속성 : 속성에 따른 블랜딩 효과를 부여합니다.

mix-blend-mode의 속성에 대한 것은 이 곳을 참조하세요.

2. 커서 좌표값 출력

이미지를 움직이기 전에 마우스 커서의 좌표 값을 알아야 합니다. 커서 좌표값은 e.pageX와 e.pageY로 출력합니다.

소스보기
const mouseMove = (e) => {
    // 마우스 좌표값
    let mousePageX = e.pageX;
    let mousePageY = e.pageY;

    // 마우스 좌표 기준점을 가운데로 변경
    let centerPageX = window.innerWidth/2 - mousePageX;
    let centerPageY = window.innerHeight/2 - mousePageY;

    //커서
    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;
};

window.addEventListener("mousemove", mouseMove);

커서 좌표 값을 출력하는건 쉽지만 브라우저 기준 즉, 화편 상단 좌측이 기준이기 때문에 이미지를 움직일 때 컨트롤하기가 쉽지 않습니다.
그래서 마우스 좌표값을 중심으로 잡아줘야 하는데 중심을 좌표값 0으로 놓는 방법은 x축 y축 모두 window.innerWidth의 절반값을 마우스 좌표값(e.pageX/e.pageY)을 빼는 것 입니다.

3. 이미지 움직이기

마우스 위치에 따라 이미지를 움직이도록 설정합니다.

소스보기
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(-300, Math.min(300, centerPageX));      //Math.max는 최대값을 구해줌
    let maxPageY = Math.max(-300, Math.min(300, centerPageY));

    // 각도 줄이는 설정
    let anglePageX = maxPageX * 0.1;
    let anglePageY = maxPageY * 0.1;

    //부드럽게 설정
    let softPageX = 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);

이미지는 addEventListener 함수의 mousemove 속성을 사용하면 마우스가 움직일 때 효과의 함수가 설정되며, querySelector쿼리 셀렉터로 이미지를 선택 후 앞서 얘기한 preserve-3d를 부여하면 됩니다.

하지만 마우스 좌표값이 빠르게 바뀌기 때문에 이미지가 제한없이 빠르게 돌아가게 되는데 이걸 해결하기 위해 좌표 값을 조절해야 합니다. 이 때 사용하는게 Math.max과 Math.min으로 최대값 최소값을 정하고 그 값에 소수점을 곱해 좌표값을 조절하는 것입니다.

※ 최대값 최소값 출력 메서드

Math.max(a, b, c, d) : 메서드 안의 값 중 최대 값을 반환합니다.
Math.min(a, b, c, d) : 메서드 안의 값 중 최소 값을 반환합니다.

Math.max(-300, Math.min(300, centerPageX))의 경우 Math.max 최대값은 마우스 위치에 따라 달라지겠지만 좌표값이 -300보다 낮아지면 -300으로 고정되기 때문에 최소값은 -300이 됩니다.
그 다음 메서드 안의 최소값을 반환하는 Math.min(300, centerPageX)에 의해 좌표값이 300을 넘어갈 수가 없어 최대값이 300으로 고정되게 됩니다.
이러한 방법이 최대값과 최소값을 조절하는 방식입니다.

'이펙트 만들기 > 마우스 이펙트 만들기' 카테고리의 다른 글

마우스 이펙트 효과 04  (2) 2022.09.23
마우스 이펙트 03  (3) 2022.09.22
마우스 이펙트 02  (0) 2022.09.22
마우스 이펙트 만들기 01  (2) 2022.09.06

댓글


광고 준비중입니다.