마우스 이펙트
자바스크립트를 이용한 마우스 효과 만들기 입니다.
마우스 이펙트 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 |
댓글