728x90
안녕하세요
이번 시간에는 웹페이지에서 눈이 내리는 효과를 만들어 보겠습니다.
*결과
1. createRadialGradient
이 함수를 이용하여 눈송이의 원형 그라데이션을 지정할 수 있습니다.
createRadialGradient( x1, y1, 첫번째 원의 반지름 r1, x2, y2, 두번째 원의 반지름 r2 )
그라데이션 색은 이후에 addColorStop 함수로 정해줍니다.
2. beginPath
이 함수는 새로운 것을 화면에 그리고 싶을 때 사용하는 함수인데
원형 눈송이를 그릴 것이기 때문에 이후에 arc 함수를 사용합니다.
MDN 문서에는 아래와 같이 beginPath()를 설명하고 있습니다.
3. requestAnimationFrame
function go(){
window.requestAnimationFrame(go);
$.clearRect(0, 0, w, h);
$.fillStyle = 'hsla(242, 95%, 3%, 1)';
$.fillRect(0, 0, w, h);
$.fill();
for (var i = 0; i < arr.length; ++i) {
f = arr[i];
f.t += .05;
f.t = f.t >= Math.PI * 2 ? 0 : f.t;
f.y += f.sp;
f.x += Math.sin(f.t * tsc) * (f.sz * .3);
if (f.y > h + 50) f.y = -10 - Math.random() * mv;
if (f.x > w + mv) f.x = - mv;
if (f.x < - mv) f.x = w + mv;
f.draw();}
}
이것은 원하는 함수를 애니메이션으로 만들어줍니다. 이 함수 덕분에 모니터 주사율에 따라 최적화된 애니메이션을 제공하게 되는 것이죠.
4. Draw 조절
-아래 함수의 마지막 파라미터 값을 증가 시키면 눈송이의 크기를 키울 수 있습니다.
this.g = $.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.sz+8);
-num 변수 값을 증가 시킬수록 눈송이의 개수가 증가합니다.
1) num = 100
2) num = 1600
-만약에 소나기처럼 빠르게 눈을 내리는 효과를 원하시면 sp 변수 값을 증가 시키면 됩니다.
5. 전체 코드
<!doctype html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<title>Winter Snow</title>
<style rel="stylesheet">
body{
background-color: hsla(0,0%,0%,1);
margin: 0px;
overflow: hidden;
font-family: 'Molle', cursive;
}
h2{
left: 50%;
position: absolute;
top: 50%;
transform: translate( -50%, -50%);
font-size:3em;
color:hsla(255, 255%, 255%, .1);
}
</style>
</head>
<body>
<canvas id='canv'></canvas>
<h2>너의 곁에 눈처럼 내리면</h2>
<script type="text/javascript">
var c = document.getElementById('canv'),
$ = c.getContext("2d");
var w = c.width = window.innerWidth,
h = c.height = window.innerHeight;
Snowy();
function Snowy() {
var snow, arr = [];
var num = 600, tsc = 1, sp = 0.5; //num:눈송이 개수 , tsc:눈송이 가로 변화율, sp:내리는 속도
var sc = 0.8, t = 10, mv = 20, min = 1; //sc:눈송이 크기
for (var i = 0; i < num; ++i) {
snow = new Flake();
snow.y = Math.random() * (h + 50);
snow.x = Math.random() * w;
snow.t = Math.random() * (Math.PI * 2);
snow.sz = (100 / (10 + (Math.random() * 100))) * sc;
snow.sp = (Math.pow(snow.sz * .8, 2) * .15) * sp;
snow.sp = snow.sp < min ? min : snow.sp;
arr.push(snow);
}
go();
function go(){
window.requestAnimationFrame(go);
$.clearRect(0, 0, w, h);
$.fillStyle = 'hsla(242, 95%, 3%, 1)';
$.fillRect(0, 0, w, h);
$.fill();
for (var i = 0; i < arr.length; ++i) {
f = arr[i];
f.t += .05;
f.t = f.t >= Math.PI * 2 ? 0 : f.t;
f.y += f.sp;
f.x += Math.sin(f.t * tsc) * (f.sz * .3);
if (f.y > h + 50) f.y = -10 - Math.random() * mv;
if (f.x > w + mv) f.x = - mv;
if (f.x < - mv) f.x = w + mv;
f.draw();}
}
function Flake() {
this.draw = function() {
this.g = $.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.sz+8);
this.g.addColorStop(0, 'hsla(255,255%,255%,1)');
this.g.addColorStop(1, 'hsla(255,255%,255%,0)');
$.moveTo(this.x, this.y);
$.fillStyle = this.g;
$.beginPath();
$.arc(this.x, this.y, this.sz, 0, Math.PI * 2, true);
$.fill();}
}
}
/*________________________________________*/
window.addEventListener('resize', function(){
c.width = w = window.innerWidth;
c.height = h = window.innerHeight;
}, false);
</script>
</body>
</html>
'JavaScript' 카테고리의 다른 글
[Javascript] 사용자 PC에 연결 되어있는 미디어 디바이스 정보 가져오기 (0) | 2022.04.10 |
---|---|
[Javascript] 키보드 이벤트 (0) | 2022.04.09 |
[Javascript] 이메일 형식인지 확인하는 기능 만들기 (0) | 2022.04.07 |
[Javascript] 사용자 미디어 디바이스에 접근하여 영상 출력하기 (0) | 2022.03.29 |
[JavaScript] Select 메뉴 만들기 (0) | 2022.03.27 |