[clone coding] 움직이는 웨이브
in Algorithm
//index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script type="module" src="app.js"></script>
</body>
</html>
//style.css
*{
outline:0;
margin:0;
padding:0;
}
html{
width:100%;
height:100%;
}
body{
width:100%;
height:100%;
background-color: #c5beaf;
}
canvas{
width:100%;
height:100%;
}
//app.js
import { WaveGroup } from "./wavegroup.js";
class App{
constructor(){
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
document.body.appendChild(this.canvas);
this.waveGroup = new WaveGroup();
window.addEventListener('resize', this.resize.bind(this), false);
this.resize();
window.requestAnimationFrame(this.animate.bind(this));
}
resize(){
this.stageWidth = document.body.clientWidth;
this.stageHeight = document.body.clientHeight;
this.canvas.width = this.stageWidth * 2;
this.canvas.height = this.stageHeight * 2;
this.ctx.scale(2,2);
this.waveGroup.resize(this.stageWidth, this.stageHeight)
}
animate(t){
this.ctx.clearRect(0, 0, this.stageWidth, this.stageHeight); //캔버스 클리어
this.waveGroup.draw(this.ctx);
requestAnimationFrame(this.animate.bind(this));
}
}
window.onload = () =>{
new App();
}
point.js
export class Point{
//웨이브를 그린다는건 웨이브를 그린다기보다는 간격을 가진 좌표를 하나씩 만들어서 좌표의 y값을 아래위로 이동시키고 각각의 좌표를 하나의 선으로 연결한다고 생각하면 쉽다
//웨이브를 그리는게 아니라 좌표를 하나씩 찍어(왼아래, 왼위, 오아래, 오위) 그걸 연결시켜서 웨이브처럼 보이게 하는 것. 그 좌표는 단순히 위아래로만 움직인다. 그 좌표를 직선으로 연결하는게 아니라 곡선으로 연결하게 되면 웨이브처럼 보인다
constructor(index, x,y){
this.x = x;
this.y = y;
this.fixedY = y;
this.speed = 0.1;
this.cur = index;
this.max = Math.random() * 100 + 150; //얼마만큼 움직일 것인가
}
update(){ //update함수가 실행되면 위아래로 움직이게 된다
this.cur += this.speed; //현재값을 이렇게 speed만큼 증가시켜주고
this.y = this.fixedY + (Math.sin(this.cur) * this.max); //sin함수를 써서 위아래로 움직일 수 있도록 만듦
}
}
wave.js
import {Point} from './point.js';
export class Wave{
//애니메이션을 그릴때 가장 중요한것은 내가 그리고자하는 애니메이션의 좌표값을 가지고 오는 것이다.
//그러기 위해서는 애니메이션의 크기를 알아야하는데 그러기 위해서는 스테이지의 넓이와 높이를 가져오는게 굉장히 중요하다
constructor(index, totalPoints, color){
this.index = index;
this.totalPoints = totalPoints;
this.color = color;
this.points = [];
}
resize(stageWidth, stageHeight){
this.stageWidth = stageWidth;
this.stageHeight = stageHeight;
//스테이지의 중앙에 찍어질 것. 스테이지의 가로 중앙, 세로중앙으로 설정
this.centerX = stageWidth / 2;
this.centerY = stageHeight / 2;
this.pointGap = this.stageWidth / (this.totalPoints - 1);
this.init();
}
init(){
this.points = [];
for(let i =0; i < this.totalPoints; i++){
const point = new Point(
this.index + i,
this.pointGap * i,
this.centerY
);
this.points[i] = point;
}
}
draw(ctx){
ctx.beginPath();
ctx.fillStyle = this.color;
let prevX = this.points[0].x;
let prevY = this.points[0].y;
ctx.moveTo(prevX, prevY);
for(let i = 0; i < this.totalPoints; i++){
if(i < this.totalPoints - 1){
this.points[i].update();
}
const cx = (prevX + this.points[i].x) /2;
const cy = (prevY + this.points[i].y) /2;
ctx.quadraticCurveTo(prevX, prevY, cx,cy);
prevX = this.points[i].x;
prevY = this.points[i].y;
ctx.lineTo(prevX, prevY);
ctx.lineTo(this.stageWidth, this.stageHeight);
ctx.lineTo(this.points[0].x, this.stageHeight);
ctx.fill();
ctx.closePath();
}
}
}
wavegroup.js
import {Wave} from './wave.js';
export class WaveGroup{
constructor(){
this.totalWaves = 3;
this.totalPoints = 3;
this.color = ['rgba(0,199,235,0.4)', 'rgba(0,146,199,0.4)', 'rgba(0,87,158,0.4)']
this.waves = [];
for(let i = 0; i < this.totalWaves; i++){
const wave = new Wave(
i,
this.totalPoints,
this.color[i],
);
this.waves[i] = wave;
}
}
resize(stageWidth, stageHeight){
for(let i = 0; i< this.totalWaves; i ++){
const wave = this.waves[i];
wave.resize(stageWidth, stageHeight);
}
}
draw(ctx){
for(let i = 0; i< this.totalWaves; i ++){
const wave = this.waves[i];
wave.draw(ctx);
}
}
}
뭔가 이상탘ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
다시 해봐야겠다..ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ분명코드 보다가 못따라간게 분명해 큰일났다 차이점을 못찾겠음..
interative developer 김종민 슨생님 유튜브보고 고대로 따라함 😎
https://www.youtube.com/watch?v=sLCiI6d5vTM&list=PLGf_tBShGSDNGHhFBT4pKFRMpiBrZJXCm&index=8