반응형
버블 어택 애니메이션이란?
여름철 물 대신에 거품이 나오는 장난감 총을 보고 영감을 받아서 제작한 애니메이션 입니다. 그래서 이름도 버블 어택 애니메이션이죠.
완성하게 된다면, 하단 영상처럼 거대한 장난감총이 마우스의 위치에 따라 각도를 조절하고, 클릭한 위치에 무수히 많은 거품이 날아가는 애니메이션을 볼 수 있습니다.
HTML
svg 는 커서 입니다.
<div class="gun"></div>
<div class="cursor">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="48" fill="none" stroke="white" stroke-width="1" opacity="0.3" />
<circle cx="50" cy="50" r="40" fill="none" stroke="white" stroke-width="1" opacity="0.5" />
<line x1="0" y1="50" x2="100" y2="50" stroke="white" stroke-width="1" />
<line x1="50" y1="0" x2="50" y2="100" stroke="white" stroke-width="1" />
<circle cx="50" cy="50" r="2" fill="white" />
<path d="M50 15 L53 25 L47 25 Z" fill="white" />
<path d="M50 85 L53 75 L47 75 Z" fill="white" />
<path d="M15 50 L25 53 L25 47 Z" fill="white" />
<path d="M85 50 L75 53 L75 47 Z" fill="white" />
</svg>
</div>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
position: relative;
overflow: hidden;
background: #333;
height: 100vh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.gun {
position: absolute;
border: none;
background: #f3f3f3;
font-size: 1.25em;
left: -150px;
top: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
transform: translate(0, -50%);
padding: 10px;
width: 400px;
height: 95%;
z-index: 1;
box-shadow: inset -20px -80px 50px rgba(0, 0, 0, 0.4),
inset 20px 80px 50px rgba(255, 255, 255, 0.4);
}
.gun::before {
content: "";
position: absolute;
border-radius: 20%;
top: 50%;
right: 0;
transform: translate(0, -50%);
background: black;
width: 50px;
height: 90%;
}
.bubble {
position: absolute;
left: 0;
z-index: 1;
z-index: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.3);
box-shadow: inset -15px -15px 10px 0 rgba(0, 0, 0, 0.3);
height: 2px;
transform-origin: 0% 50%;
}
/* 커서 */
.cursor {
position: fixed;
pointer-events: none;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: 12s infinite rotation linear;
transform-origin: 0% 0%;
}
.cursor svg {
width: 50px;
height: 50px;
}
@keyframes rotation {
0% {
transform: rotate(0deg) translate(-50%, -50%);
}
100% {
transform: rotate(360deg) translate(-50%, -50%);
}
}
JS
const container = document.querySelector("body");
const gun = document.querySelector(".gun");
const cursor = document.querySelector(".cursor");
const bubbles = Array.from({ length: 30 });
container.addEventListener("mousemove", (e) => {
moveGunUpDown(e);
cursorMove(e);
});
container.addEventListener("click", animate);
function animate(e) {
const clientY = e.clientY;
// 거품 생성
bubbles.forEach(() => {
const bubble = document.createElement("div");
const randomSize = Math.random() * 150;
const randomY = Math.random() * 500 - 250;
const randomX = Math.random() * 500 - 250;
const randomDuration = Math.random() * 5 + 5;
bubble.classList.add("bubble");
bubble.style.transform = `translate(${randomX * 2}px, ${randomY * 1.5}px)`;
// 거품 추가
container.append(bubble);
gsap.set(bubble, {
width: `${randomSize}`,
height: `${randomSize}`,
rotate: () => {
const isTop = -(clientY - window.innerHeight / 2) > 0;
if (isTop) return -5;
else if (
-(clientY - window.innerHeight / 2) > -200 &&
-(clientY - window.innerHeight / 2) < 200
)
return 0;
else return 5;
}
});
gsap.to(bubble, {
duration: randomDuration,
x: 3000,
y: () => {
return clientY - window.innerHeight / 2;
}
});
// 2초 뒤 거품 삭제
setTimeout(() => {
container.removeChild(bubble);
}, 6000);
});
}
// 총 업 다운
function moveGunUpDown(e) {
const clientY = e.clientY;
gsap.to(gun, {
rotate: () => {
console.log((clientY / window.innerHeight) * 10 - 5);
return (clientY / window.innerHeight) * 10 - 5;
}
});
}
// 커서 무브
function cursorMove(e) {
cursor.style.left = e.clientX + "px";
cursor.style.top = e.clientY + "px";
}
구현 결과
현재 거품은 한 번에 사라지지만 setTimeout이 동작하는 시간대도 랜덤하다면 어떻게 될까요? 그리고 그 타이밍에 거품이 터지는 효과를 넣는다면? 코드 자체가 복잡한 것은 없으니 참고하셔서 더 재밌는 효과를 만들어보면 좋은 체험이 될거라 생각합니다.
See the Pen BubbleAttack by youngwan2 (@youngwan2) on CodePen.
0.25 배율로 보시는 걸 추천합니다.
반응형
'UI 디자인 애니메이션 연구소' 카테고리의 다른 글
✨AI도 그리다 포기하는 태극기, HTML과 CSS 로 제작하기 (1) | 2024.08.15 |
---|---|
JS와 GSAP stagger API 로 만드는 스트리밍 써클 애니메이션! (1) | 2024.08.06 |
바닐라 자바스크립트를 이용한 스크롤 트리거 애니메이션의 원리와 구현 (0) | 2024.07.25 |
캐러셀 라이브러리에서 보던 드래그 가능한 슬라이드, 원리 부터 구현까지!! (0) | 2024.07.18 |
HTML과 CSS 만으로 이런 것도 가능해?? 액자 모양 로고 애니메이션 (0) | 2024.07.02 |