상세 컨텐츠

본문 제목

PathToHeart 좌표로 하트 그리는 HTML 코드

Web/HTML JS

by cepiloth 2024. 2. 21. 15:19

본문

728x90
반응형

created with DALL·E

1. 초기 변수 설정

  • e: 입자의 궤적을 저장하는 배열입니다.
  • h: 하트 모양의 경로를 정의하는 노드들의 배열입니다.
  • O, Q: 캔버스의 너비와 높이입니다.
  • v: 궤적의 수, 각 궤적에 있는 입자의 수, 하트 경로에 있는 노드의 수를 정의합니다.
  • M: Math 객체의 단축형입니다.
  • R, C, Y: 각각 Math.random, Math.cos 함수와 하트 경로 계산에 사용되는 상수입니다.

2. 하트 경로 계산

하트 모양의 경로를 계산하기 위해 for 루프를 사용하여 h 배열에 노드를 추가합니다. 이 노드는 하트의 수학적 공식을 기반으로 계산됩니다.

3. 입자 초기화

while 루프를 사용하여 각 궤적에 대한 입자 배열을 생성합니다. 각 입자는 위치, 속도, 반경, 가속도, 타겟 노드, 방향, 마찰, 색상 등의 속성을 가집니다.

4. render 함수

이 함수는 캔버스에 입자를 그립니다. 입자의 색상, 위치 및 크기에 따라 캔버스에 원을 그립니다.

5. loop 함수

이 함수는 애니메이션의 주요 부분입니다. 캔버스를 지우고, 각 입자의 위치를 업데이트하며, 입자가 하트 경로의 노드에 도달했는지 확인합니다. 입자가 노드에 도달하면 새로운 목표를 설정합니다. 그런 다음 모든 입자를 새 위치에 그립니다.

6. 애니메이션 루프

requestAnimationFrame을 사용하여 loop 함수를 반복적으로 호출합니다. 이는 웹 브라우저에게 애니메이션을 수행하도록 요청하고, 브라우저가 최적화된 방식으로 애니메이션을 수행할 수 있게 합니다.

이 코드를 블로그에 설명할 때는 각 단계를 상세히 설명하고, 코드의 각 부분이 어떻게 함께 작동하는지를 독자가 이해할 수 있도록 해야 합니다. 또한, 코드의 수학적인 부분이나 프로그래밍 개념을 설명할 때는 독자가 기초적인 지식을 가지고 있지 않다고 가정하고 설명하는 것이 좋습니다.

소스코드

#heart.js

e = [];// trails
h = [];// heart path
O = c.width = innerWidth;
Q = c.height = innerHeight;

v = 32; // num trails, num particles per trail & num nodes in heart path
M = Math;
R = M.random;
C = M.cos;
Y = 6.3;// close to 44/7 or Math.PI * 2 - 6.3 seems is close enough. 
for( i = 0; i <Y; i+= .2 ) { // calculate heart nodes, from http://mathworld.wolfram.com/HeartCurve.html
	h.push([
		O/2 + 180*M.pow(M.sin(i), 3),
		Q/2 + 10 * (-(15*C(i) - 5*C(2*i) - 2*C(3*i) - C(4*i)))
	])
}

i = 0;
while (i < v ) {

	x = R() * O;
	y = R() * Q;
	//r = R() * 50 + 200;
	//b = R() * r;
	//g = R() * b;

	H = i/v * 80 + 280;
	S = R() * 40 + 60;
	B = R() * 60 + 20;

	f = []; // create new trail

	k = 0;
	while ( k < v ) { 
		f[k++] = { // create new particle
			x : x, // position 
			y : y,
			X : 0, // velocity
			Y : 0,
			R : (1 - k/v)  + 1, // radius
			S : R() + 1, // acceleration 
			q : ~~(R() * v), // target node on heart path
			//D : R()>.5?1:-1,
			D : i%2*2-1, // direction around heart path
			F : R() * .2 + .7, // friction
			//f : "rgba(" + ~~r + "," + ~~g + "," + ~~b + ",.1)"
			f : "hsla("+~~H+","+~~S+"%,"+~~B+"%,.1)" // colour
		}
	}

	e[i++] = f; // dots are a 2d array of trails x particles
}

function render(_) { // draw particle
	a.fillStyle = _.f;
	a.beginPath();
	a.arc(_.x, _.y, _.R, 0, Y, 1);
	a.closePath();
	a.fill();
}

function loop(){

	a.fillStyle = "rgba(0,0,0,.2)"; // clear screen
	a.fillRect(0,0,O,Q);

	i = v;
	while (i--) {

		f = e[ i ]; // get worm
		u = f[ 0 ]; // get 1st particle of worm
		q = h[ u.q ]; // get current node on heart path
		D = u.x - q[0]; // calc distance
		E = u.y - q[1];
		G = M.sqrt( (D * D) + (E * E) );
		
		if ( G < 10 ) { // has trail reached target node?
			if (R() > .95 ) { // randomly send a trail elsewhere
				u.q = ~~(R() * v);
			} else {
				if ( R() > .99) u.D *= -1; // randomly change direction
				u.q += u.D;
				u.q %= v;
				if ( u.q < 0 ) u.q += v;
			 }
		}

		u.X += -D / G * u.S; // calculate velocity
		u.Y += -E / G * u.S;

		u.x += u.X; // apply velocity
		u.y += u.Y;

		render(u); // draw the first particle

		u.X *= u.F; // apply friction
		u.Y *= u.F;

		k = 0;
		while ( k < v-1 ) { // loop through remaining dots
			
			T = f[ k ]; // this particle
			N = f[ ++k ]; // next particle

			N.x -= (N.x - T.x) * .7; // use zenos paradox to create trail
			N.y -= (N.y - T.y) * .7;

			render(N);

		}

	}
}; // eo loop()

(function doit(){
	requestAnimationFrame(doit);
	loop();
}());

index.html
<!doctype html>
<html>
	<head>
		<title>heart</title>
		<meta charset="utf-8">
	</head>
	<body>
		<canvas id="c"></canvas>
		<script>
			var b = document.body;
			var c = document.getElementsByTagName('canvas')[0];
			var a = c.getContext('2d');
			document.body.clientWidth; 
		</script>
		<script src="https://raw.github.com/gist/1579671/7f515ade253afbc860dac1f84e21998d54359d79/rAF.js"></script>
		<script src="heart.js"></script>
	</body>
</html>

 

영상

https://www.youtube.com/watch?v=PndFxaz4TnU

 

728x90
반응형

관련글 더보기

댓글 영역