Javascript

삼각함수, 캔버스, arc, 비동기, JSON, 디스트럭처링 활용하여 데이터 받아오기

Antonio Bae 2023. 7. 31. 17:44
 

오늘은 삼각함수를 배우고 이를 활용하여 캔버스에 자바스크립트로 원을 그려보는 시간입니다.

중학생 때 이후로 15년만에 다시 꺼내보는 삼각함수인데요..

 

먼저 삼각함수란?

 

삼각함수는 동경의 크기에 따라 변화하는 함수입니다.

주기함수를 사인 및 코사인의 무한합으로 전개하는 것을 말합니다.

동경위의 점과 원점, x축에 내린 발이 직각삼각형을 이루기 때문에 삼각함수라고 부릅니다.

 

삼각함수에는 3개의 기본적인 함수가 있으며,

이들은 사인,코사인,탄젠트가 있습니다.

 

좌표평면 상 원점 O

O가 중심인 단위원을 고려하자. 단위원 위의 한 점 P(�, �)

P(x,y)에 대하여 �

x축의 양의 방향을 시초선[6]으로 잡는다. O

O를 중심으로 시초선에서 반시계 방향 회전을 각의 양의 방향으로 잡고, 그 각의 크기를 �

θ라고 하면, 다음으로 정의한다.

사진 설명을 입력하세요.

 

이 sin cos 활용하여 X좌표,Y좌표 구하고 원그리는 방법을 알아보겠습니다.

예시: X좌표: 95, Y좌표: 50, 반지름 40px 기준으로 원 그리기

 

1.arc메서드 활용

arc(x, y, radius, startAngle, endAngle)

= arc(x, y, 반지름, 시작각도, 종료각도, 그리는 방향);

매개변수 x 호 중심의 수평 좌표

y 호 중심의 세로 좌표

radius 호의 반지름입니다. 양수여야 함

startAngle 호가 시작하는 각도(라디안)로, 양의 x축에서 측정

endAngle 양의 x축에서 측정한 라디안 단위의 호가 끝나는 각도

 

2. 캔버스 그리기

전형적인 포맷으로 다음과 같은 메소드를 활용하여 캔버스로 그릴 수 있습니다.

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.arc(100, 75, 50, 0, 2 * Math.PI);
ctx.stroke();
 

 

전체코드1

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sin cos 활용하여 X좌표,Y좌표 구하고 원그리기</title>
</head>
<body>
    <canvas id="myCanvas" width="200" height="200"></canvas>
    <script>
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        function drawArc(startDegree, endDegree) {

            //보정된 좌표계
            ctx.beginPath();
            // pie / 180 * degree
            // 각도(degree) 표기를 라디안(Radian)으로 변경
            ctx.arc(95, 50, 40, Math.PI / 180 * endDegree * -1, Math.PI / 180 * startDegree * -1);
            //                ---------끝각도-2---------------,--------------시작각도-------------
            // x,y,반지름,시작r, 끝r
            ctx.stroke();
            ctx.fillRect(95, 50, 1, 1);// (95, 50) 좌표에 크기가 1x1인 사각형을 그림 (점으로 표현)

            //사인 코사인 그리기
            //x = r * cos(degree)
            //y = r * sin(degree)
            let locX = 40 * Math.cos(Math.PI / 180 *45);// 45도에 해당하는 끝점의 X 좌표를 구함
            let locY = 40 * Math.sin(Math.PI / 180 *45);// 45도에 해당하는 끝점의 Y 좌표를 구함
            
            // 사인과 코사인 함수를 사용하여 원호의 끝점에 점을 그림
            ctx.moveTo(95,50); // 이동시키기
            ctx.lineTo(95+locX,50-locY); // (95, 50)에서 (95 + locX, 50 - locY)까지 선을 그림
            ctx.stroke(); // 그리기

            //밑변 그리기
            ctx.moveTo(95,50);
            ctx.lineTo(95+40,50-0);
            ctx.stroke();
        }
        drawArc(0, 45);
        // drawArc(220, 320);

    </script>
</body>

</html>
 

응용코드

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas id="myCanvas" width="200" height="200"></canvas>
    <script>
        //삼각함수 sin = y/r cos = x/r, tan = y/x
        //0도만 처리가 가능한 코드 -> 10도에서도 가능하게 만들어 볼것
        //x,y 좌표계로 원 그리기
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        function drawArc(setX, setY, setR, startDegree, endDegree) {
            //보정된 좌표계
            ctx.beginPath();
            // pie / 180 * degree
            // 각도(degree) 표기를 라디안(Radian)으로 변경
            ctx.arc(setX, setY, setR, Math.PI / 180 * endDegree * -1, Math.PI / 180 * startDegree * -1);
            //                ---------끝각도-2----------,---------시작각도----------
            // x,y,반지름,시작r, 끝r
            ctx.stroke();
            ctx.fillRect(setX,setY, 1, 1);// (95, 50) 좌표에 크기가 1x1인 사각형을 그림 (점으로 표현)

            //사인 코사인 그리기
            //x = r * cos(degree)
            //y = r * sin(degree)
            let locX = setR * Math.cos(Math.PI/180 * endDegree);// 45도에 해당하는 끝점의 X 좌표를 구함
            let locY = setR * Math.sin(Math.PI / 180 * endDegree);// 45도에 해당하는 끝점의 Y 좌표를 구함
            
            // 사인과 코사인 함수를 사용하여 원호의 끝점에 점을 그림
            ctx.moveTo(setX,setY); // 이동시키기
            ctx.lineTo(setX+locX,setY-locY); // (95, 50)에서 (95 + locX, 50 - locY)까지 선을 그림
            ctx.stroke(); // 그리기

            //밑변 그리기
            ctx.moveTo(setX,setY);
            ctx.lineTo(setX+setR*Math.cos(Math.PI/180*startDegree),setY-setR*Math.sin(Math.PI/180*startDegree));
            ctx.stroke();
        }
        drawArc(55, 50, 30, 20, 290); //x,y,반지름,시작각,끝각
        // drawArc(220, 320);

    </script>
</body>

</html>
 

input버튼으로 x,y,반지름길이 받아 원을 그리는 응용 코드 3

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>x,y 좌표계로 원 그리기</title>
</head>
<body>
    <canvas id="myCanvas" width="200" height="200"></canvas>
    <br>
    <label for="xCoord">X 좌표:</label>
    <input type="number" id="xCoord" name="xCoord" min="0" max="200">
    <br>
    <label for="yCoord">Y 좌표:</label>
    <input type="number" id="yCoord" name="yCoord" min="0" max="200">
    <br>
    <label for="radius">반지름:</label>
    <input type="number" id="radius" name="radius" min="1" max="100">
    <button id="drawButton">원 그리기</button>
    <script>
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        
        // 원호 그리는 함수 정의
        function drawArc(setX, setY, setR, startDegree, endDegree) {
            ctx.beginPath();
            ctx.arc(setX, setY, setR, Math.PI / 180 * endDegree * -1, Math.PI / 180 * startDegree * -1);
            ctx.stroke();
            ctx.fillRect(setX, setY, 1, 1);

            let locX = setR * Math.cos(Math.PI / 180 * endDegree);
            let locY = setR * Math.sin(Math.PI / 180 * endDegree);
            ctx.moveTo(setX, setY);
            ctx.lineTo(setX + locX, setY - locY);
            ctx.stroke();

            ctx.moveTo(setX, setY);
            ctx.lineTo(setX + setR * Math.cos(Math.PI / 180 * startDegree), setY - setR * Math.sin(Math.PI / 180 * startDegree));
            ctx.stroke();
        }

        // 초기 원 그리기
        drawArc(55, 50, 30, 20, 290);

        // 원 그리기 버튼 클릭 시 호출되는 함수
        document.getElementById("drawButton").addEventListener("click", function () {
            ctx.clearRect(0, 0, canvas.width, canvas.height); // 캔버스 초기화
            var xCoord = parseInt(document.getElementById("xCoord").value);
            var yCoord = parseInt(document.getElementById("yCoord").value);
            var radius = parseInt(document.getElementById("radius").value);

            // 입력받은 좌표를 기준으로 원을 그림
            drawArc(xCoord, yCoord, radius, 0, 360);
        });
    </script>
</body>

</html>

fillText 메서드

형식: fillText(text, x, y [, maxWidth])

ctx.fillText("텍스트", x좌표, y좌표, 최대 너비)

function draw() {
  const ctx = document.getElementById("canvas").getContext("2d");
  ctx.font = "48px serif";
  ctx.fillText("Hello world", 10, 50);
}
 

 

JSON 형태로 데이터 받는 방법

JSON은 KEY:VALUE형태로 다음과 같이 받습니다.

 

사진 설명을 입력하세요.

var myJSON = '{"name":"John", "age":31, "city":"New York"}';

var myObj = JSON.parse(myJSON);

document.getElementById("demo").innerHTML = myObj.name;

 

json이란

JavaScript Object Notation라는 의미의 축약어로 데이터를 저장하거나 전송할 때 많이 사용되는 경량의 DATA 교환 형식

문자열을 자바스크립트 객체로 바꿈

 

☆☆☆☆☆☆☆매우중요한 메서드 ☆☆☆☆☆☆

JSON.stringify() => 자바스크립트 객체를 문자열로

JSON.parse() ==> 문자열을 자바스크립트 객체로 바꿈

 

 

JSON 형태

{ "name":"John" }

 

JAVASCRIPT 형태

{ name:"John" }

 

올바른 데이터 타입

짧게 줄여서 SNABNO!!

a string

a number

an array

a boolean

null

an object (JSON object)

 

 

JSON 형태 예시

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}');
 
<p id="demo"></p>
 
<script>
var txt = '{"name":"John", "age":30, "city":"New York"}' // 서버에서 온 자료로 가정
var obj = JSON.parse(txt);
document.getElementById("demo").innerHTML = obj.name + ", " + obj.age;
</script>
 

서버쪽 파일 json_demo.txt

{
    "name":"John",
    "age":31,
    "pets":[
        { "animal":"dog", "name":"Fido" },
        { "animal":"cat", "name":"Felix" },
        { "animal":"hamster", "name":"Lightning" }
    ]
}
 

파싱 형태 예시(클라이언트쪽 로직)

var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    var myObj = JSON.parse(this.responseText);
    document.getElementById("demo").innerHTML = myObj.name;
  }
};
xmlhttp.open("GET", "json_demo.txt", true);
xmlhttp.send();
 

날짜 처리 형태 예시 1

<p id="demo"></p>
 
<script>
var text = '{"name":"John", "birth":"1986-12-14", "city":"New York"}';
var obj = JSON.parse(text);
obj.birth = new Date(obj.birth);
document.getElementById("demo").innerHTML = obj.name + ", " + obj.birth; 
</script>
 

예시2

<p id="demo"></p>
 
<script>
var text = '{"name":"John", "birth":"1986-12-14", "city":"New York"}';
var obj = JSON.parse(text, function (key, value) {
  if (key == "birth") {
    return new Date(value);
  } else {
    return value;
  }
});
document.getElementById("demo").innerHTML = obj.name + ", " + obj.birth; 
</script>
 

 

데이터분석의 대표적인 사이트죠

공공데이터 포털에서 데이터를 받아올 때도 보통 JSON 형태를 많이 이용합니다.

홈페이지 예시

오픈API 예시로 하나 알려드리겠습니다.

한국환경공단_자원순환정보시스템_폐기물통계정보

https://www.data.go.kr/data/15106003/openapi.do

데이터를 받아올때, 디스트럭처링을 할 수 있으면 매우 편합니다.

디스트럭처링이란?

스트럭처링은 객체와 배열을 구성하는 개별 요소를 독립적인 상수나 변수에 저장하는 방법입니다

예제1

<script> const Dip2K = { name: "bts", company: { name: "빅히트", contacts: { address: "42 Teheran-ro 108-gil, Gangnam-gu, Seoul", telephone: "02-525-0421", president: "방시혁" } } } const { name } = Dip2K console.log(name) // bts const { address, telephone } = Dip2K.company.contacts console.log(address, telephone) // 42 Teheran-ro 108-gil, Gangnam-gu, Seoul 02-525-0421 const { name: companyName } = Dip2K.company console.log(companyName) // 빅히트 const { alias = "닌자" } = Dip2K.company console.log(alias) // 닌자 </script>