본문 바로가기
JavaScript

[Javascript] 공기방울 효과 만들기

by teamnova 2022. 5. 2.
728x90

안녕하세요

 

이번시간에는 공기방울 파티클 효과를 만들어 보겠습니다.

 

*결과

1. push함수

배열에 요소를 추가 할 때 사용하는 함수입니다.

Cicle 객체를 생성하여 circleArray에 추가하고 maxCount 만큼 만들어냅니다.

 

function createCircle(max) {
	for (var i = 0; i < max; i++) {
		var circleObject = new Circle;
		circleObject.id = i;
		circleArray.push(circleObject);
	}
	//After creation of circle attributes, the animations begin
	moveCircle();
}

 

*참고

- push 메서드 : 배열의 마지막에 새로운 요소를 추가한 후, 변경된 배열의 길이를 반환

- pop 메서드 : 배열의 마지막 요소를 제거한 후, 제거한 요소를 반환

- unshift 메서드 : 배열의 첫 번째 자리에 새로운 요소를 추가한 후, 변경된 배열의 길이를 반환

- shift 메서드 : 배열의 첫 번째 요소를 제거한 후, 제거한 요소를 반환

 

 

2. clearRect

특정영역을 깨끗하게 지우는 함수입니다.

  context.clearRect(0,0,canvas.width,canvas.height);

requestAnimationFrame을 통해 애니메이션을 구현하면서 매 프레임마다 캔버스를 깨끗하게 지우고 다시 도형을 그려주면서 공기방울이 움직이는 것처럼 보이게 합니다.

	requestAnimationFrame(moveCircle);

 

 

3. 전체코드 

<!doctype html>
<html lang="kr">
	<head>
	<meta charset="UTF-8">
	<title>공기방울 만들기</title>

<style>
canvas {
  -webkit-filter: blur(1px);
          filter: blur(1px);
}

body { 
  background-image: -webkit-linear-gradient(bottom, #0B2E59 -10%, #69D2E7 20%, #6fDaEF 80%, #fffabb 105%); 
  background-image: linear-gradient(to top, #0B2E59 -10%, #69D2E7 20%, #6fDaEF 80%, #fffabb 105%);
}
</style>
</head>
<body>

<canvas id="canvas"></canvas>


<script type="text/javascript">
//Converting this code into a particle system soonnn!

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var circleArray = [];
//Color array to look like bubbles
var ballColorSelections = ['#A7DBD8', '#EFEFEF', '#ADF7D3', '#88F7D2'];

//Global settings
var settings = {
	maxCount: 400,
  //Reversed the bounce from collisions to create an attraction
	bounce: -0.05,
	force: -1.25,
	gravity: -0.01
}

//Just for my profile background, using the CSS here for it too ;)
document.body.style.overflow = 'hidden';

canvas.height = window.innerHeight;
canvas.width = window.innerWidth;

createCircle(settings.maxCount);

window.addEventListener('resize', function() {
	canvas.height = window.innerHeight;
	canvas.width = window.innerWidth;
});

function Circle() {
	this.positionX = (Math.random() * window.innerWidth/2) + window.innerWidth/4;
	this.positionY = window.innerHeight;
	this.radius = Math.floor((Math.random() * window.innerWidth * 0.005) + 1);
	this.velocityY = (Math.random() * 100) / 100 * -1;
	this.velocityX = (Math.random() * 100) / 100 * -1;
	this.color = ballColorSelections[Math.floor(Math.random() * 5)];
}

function createCircle(max) {
	for (var i = 0; i < max; i++) {
		var circleObject = new Circle;
		circleObject.id = i;
		circleArray.push(circleObject);
	}
	//After creation of circle attributes, the animations begin
	moveCircle();
}

function drawCircle(object) {

	for (var i = 0; i < object.length; i++) {
		context.beginPath();
		context.arc(object[i].positionX, object[i].positionY, object[i].radius, 0, 2 * Math.PI);
		context.fillStyle = object[i].color;
		context.fill();
		context.closePath();
	}

}

function moveCircle() {
	
	context.fillStyle = "#69D2E7"; 
  context.clearRect(0,0,canvas.width,canvas.height);

	for (var i = 0; i < circleArray.length; i++) {

		collideCircle(circleArray, circleArray[i]);
		circleArray[i].velocityY += settings.gravity;
		circleArray[i].positionY += circleArray[i].velocityY;
		circleArray[i].positionX += circleArray[i].velocityX;

		if(circleArray[i].positionY > 0 - circleArray[i].radius) {
			circleArray[i].positionY += circleArray[i].velocityY;
		} else {
			circleArray[i].velocityY = (Math.random() * 100) / 100 * -1;
      circleArray[i].positionX = (Math.random() * window.innerWidth);
      circleArray[i].positionY = window.innerHeight;
		}

		if(circleArray[i].positionX > canvas.width + circleArray[i].radius 
       || circleArray[i].positionX < 0 - circleArray[i].radius) {
      circleArray[i].positionX = (Math.random() * window.innerWidth);
      circleArray[i].positionY = window.innerHeight;
		}

	}

	function collideCircle(collideObject, circleObject) {
		for (var j = circleObject.id + 1; j < collideObject.length; j++) {
			var distanceX = collideObject[j].positionX - circleObject.positionX;
			var distanceY = collideObject[j].positionY - circleObject.positionY;
			var distance = Math.floor(Math.sqrt((distanceX * distanceX) + (distanceY * distanceY)));
      //Inflated the minimum distance to attract other particles
			var minimumDistance = collideObject[j].radius + circleObject.radius * 10;
			if (distance <= minimumDistance) {
				var angle = Math.atan2(distanceY, distanceX);
        var targetX = circleObject.positionX + Math.cos(angle) * minimumDistance;
        var targetY = circleObject.positionY + Math.sin(angle) * minimumDistance;
        var angleX = parseInt((targetX - collideObject[j].positionX) * settings.bounce) / 50;
        var angleY = parseInt((targetY - collideObject[j].positionY) * settings.bounce) / 50;
        circleObject.velocityX -= angleX;
        circleObject.velocityY -= angleY;
        collideObject[j].velocityX += angleX;
        collideObject[j].velocityY += angleY;
			}

		}
	}

	drawCircle(circleArray);

	requestAnimationFrame(moveCircle);

}
</script>
</body>
</html>