for문과 forEach 메서드는 모두 반복문을 작성할 때 사용하지만, 작동 과정이 조금 다릅니다. 이 작동과정의 차이에서 발생하는 차이점에 대해 알아보겠습니다.

for문과 forEach메서드의 차이점 비교

 

for문과 forEach메서드의 차이점 비교

 

0. 여는글

1. `forEach`의 작동 과정

2. `for``문의 작동 과정

3. `forEach` 메서드와 `for`문은 언제 사용해야 될까?

4. 정리하기

 

여는글

 데이터를 저장하기 위해 서버로 보내기 전, 알맞은 값을 넣었는지 확인하는 작업이 필요했다. 그래서 forEach 메서드를 통해 값을 확인한 후, 적절하지 않은 경우에는 alert 창을 띄우고 저장 작업을 멈추도록 했다. 하지만 값에 문제가 있더라도 루프가 계속 진행되었고, 함수의 진행도 멈추지 않았다. 결국 forEach에서의 return문이 내가 생각한 방식과 차이가 있음을 알게 되었다.

const test = [
  { name: "김철수", age: 30 },
  { name: "김영희", age: undefined },
];

const handleSave = async (infos) => {
  // 값의 유효성 확인, 값이 없으면 alert 창 띄우기
  infos.forEach((info) => {
    if (!info.age) {
      console.log(`${info.name}의 나이를 입력해주세요!`);
      return;
    }
  });

  console.log("유효성 검사 통과!");
};

handleSave(test);
// 출력: "김영희의 나이를 입력해주세요!"와 "유효성 검사 통과!"가 모두 출력된다.

1. `forEach`의 작동 과정

 상기한 예시처럼 forEach의 콜백 함수에 return문을 넣더라도 루프가 계속 동작한다. 그 이유는 forEach가 각 요소마다 콜백 함수를 호출하는 방식으로 진행되기 때문이다.


const test2 = [2, 3, 4];
test2.forEach((num) => {
  if (num === 3) {
    console.log('3을 찾았다! 이제 루프 그만 두고 싶어!');
    return;
  }
  console.log('못 찾았다!');
});

 만약 이렇게 작성한 forEach 메서드가 있다고 가정해보겠다. 이러한 경우 아래의 코드와 같은 방식으로 실행된다.


callback(2);
callback(3);
callback(4);

 결국 콜백 함수 내부에 return문을 작성하더라도 그건 전체 반복문에 대한 return이 아닌, 콜백 함수 한 개의 return문이기 때문에 3을 찾은 이후에도 4를 대상으로 콜백 함수가 실행된다.

2. `for`문의 작동 과정

 상기한 `forEach` 메서드를 `for`문으로 바꿔보겠다.

const test2 = [2, 3, 4];

for (const num of test2) {
  if (num === 3) {
    console.log('3을 찾았다! 이제 루프 그만 두고 싶어!');
    return;
  }
  console.log('못 찾았다!');
}

 `for`문 안에서 작성된 `return`문은 전체 반복문을 종료하기에, 3을 찾은 이후에는 루프를 종료한다. 따라서 4를 대상으로는 루프를 진행하지 않는다. 결국 `forEach` 메서드와 `for`문의 차이는 콜백 함수 사용 여부에서 발생한다고 볼 수 있다.

3. `forEach` 메서드와 `for`문은 언제 사용해야 할까?

 `forEach` 메서드와 `for`문은 콜백 함수를 사용하느냐에서 차이가 있다. 그래서 장단점을 비교한다면 이 부분을 고려해서 살펴보면 된다.

 

  • `forEach` 메서드의 장점
    • `for`문에 비해 작성이 편리하다.
    • 코드가 간결하고 명확하여 가독성이 높다.
  • `forEach` 메서드의 단점
    • 배열의 요소가 많아질 시, 실행되는 콜백 함수의 갯수도 증가하므로 자원 소모(오버헤드)가 심해질 수 있다.
    • 각 요소마다 실행되는 콜백 함수의 내부 코드가 복잡해질 경우에도 자원 소모(오버헤드)가 심해질 수 있다.
    • `break`, `continue`를 사용할 수 없어 루프를 중간에 종료하거나 건너뛸 수 없다.

  • `for`문의 장점
    • `break`, `continue`를 통해 루프에 대한 제어가 가능하다.
    • 콜백 함수를 사용하지 않으므로, 배열이 길어지거나 루프 내에 실행하는 코드가 복잡하더라도 오버헤드가 심해지지 않는다.
    • 복잡한 반복 논리를 구현할 때 유리하다.
  • `for`문의 단점
    • 함수형 프로그래밍에서 형태가 다소 이질적이다.
    • 코드가 길어지거나 복잡해질 수 있어 가독성이 떨어질 수 있다.

4. 정리하기

forEach 메서드와 for문은 콜백 함수 사용 여부에서 차이가 있다. forEach 메서드는 작성하기는 간편하지만 성능 면에서는 for문에 밀릴 수 있다. 단순 루프일 경우에는 forEach를 사용해도 괜찮지만, 성능이나 반복문의 제어가 필요한 경우에는 for문을 사용하는 것이 좋다.

'javascript > 이론' 카테고리의 다른 글

자바스크립트의 이벤트 루프  (0) 2024.04.24

JQuery 에서 html 요소에 이벤트를 부여할 때는 위임과, 할당 2가지 방식이 있습니다. 위임은 상위 요소에 이벤트를 할당하여 자식 요소에서 이벤트가 발생하도록 지정하는 방식이다. 할당은 이벤트가 일어날 대상을 직접 선택자로 불러와 이벤트를 부여 합니다.

[JQuery] 이벤트 할당과 위임

 

[JQuery] 이벤트 할당과 위임

 

0. 요약

1. 할당

2. 위임

 

요약

 JQuery 에서 html 요소에 이벤트를 부여할 때는 위임과, 할당 2가지 방식이 있다. 위임은 상위 요소에 이벤트를 할당하여 자식 요소에서 이벤트가 발생하도록 지정하는 방식이다. 할당은 이벤트가 일어날 대상을 직접 선택자로 불러와 이벤트를 부여한다.
 전자는 최초 실행 이후에 생긴 요소에도 이벤트가 발생하지만, 후자는 최초의 요소에만 이벤트가 발생한다.

할당

$(".row").on("click", function () {
  alert("클릭!");
});

 대상이 되는 요소에 직접 이벤트를 할당한다.

 장점

  • 코드가 직관적이다.

 단점

  • 새로 만들어진 요소에는 이벤트가 할당되지 않는다.
  • 각 요소마다 이벤트가 할당되어 위임에 비해 메모리 사용이 비효율적이다.

위임

$("#row-container").on("click", ".row", function () {
  alert("클릭!");
});

 부모요소에 이벤트를 할당해 자식 요소의 이벤트를 관리한다.


 장점

  • 새로 생긴 요소에도 이벤트가 부여된다.
  • 부모 요소에만 이벤트를 할당하여 메모리 효율이 좋다.

 단점

  • 자식요소에 개별화된 이벤트를 부여하기 위해서는 분기 처리 등 세분화된 코드가 필요하다

삽입 정렬에 대해 알아봅니다.

삽입 정렬

 

삽입 정렬

 

1. 삽입 정렬이란 무엇이고, 어떻게 이뤄지는가?

2. 코드로 살펴보기

 

1. 삽입 정렬이란 무엇이고, 어떻게 이뤄지는가?

 정렬된 요소를 왼쪽으로, 정렬 되지 않은 요소는 오른쪽에 있다고 가정한다. 오른쪽에서 정렬이 되지 않은 요소를 가져와 이미 정렬된 요소들과 비교하여 적절한 위치에 삽입한다.
 이중 반복문을 사용하며, 시간 복잡도는 항상 n^2이다. 따라서 배열의 길이가 늘어날수록 시간이 급격히 증가한다.

2. 코드로 살펴보기

function insertionSort(arr) {
  const len = arr.length;

  for (let i = 1; i < len; i++) {
  // 인덱스 0 요소는 이미 왼쪽에서 정렬되어 있다고 가정한다.
  
    const current = arr[i];
    // 이번 회차에서 정렬하고차 하는 요소

    let j = i - 1;
    // 이미 정렬된 요소의 가장 오른쪽부터 비교를 시작한다.

    while (j >= 0 && arr[j] > current) {
      arr[j + 1] = arr[j];
      j--;
      // 현재 비교하는 수가 정렬 요소의 수보다 작을 때, 정렬된 요소를 오른쪽으로 한칸 땡긴다.
      // 그리고 왼쪽 요소와 비교를 한번 더 진행한다.
    }

    arr[j + 1] = current;
    // 정렬된 요소 중에서 더 작은 수가 없을 경우, 현재 요소를 정렬된 요소의 인덱스로 집어 넣는다.
    
  }

  return arr;
}

'컴퓨터 과학 > 알고리즘' 카테고리의 다른 글

선택 정렬  (0) 2024.04.25
버블 정렬  (0) 2024.04.24

선택 정렬에 대해 알아봅니다.

선택 정렬

 

선택 정렬

 

1. 선택 정렬이란 무엇이고, 어떻게 이뤄지는가?

2. 코드로 살펴보기

 

1. 선택 정렬이란 무엇이고, 어떻게 이뤄지는가?

 가장 큰 수, 혹은 가장 작은 수를 선택해서 정렬을 반복하는 과정이다. 이중 반복문을 사용하며, 각 회차마다 정렬이 되지 않은 모든 요소를 조회하여 가장 큰 수(가장 작은 수)를 찾아 제일 오른쪽(왼쪽)으로 위치를 변경한다.
 이중 반복문을 사용하므로 시간 복잡도는 항상 n^2으로, 배열의 길이가 늘어날수록 시간이 급격히 늘어난다.

2. 코드로 살펴보기

function selectionSort(arr) {
  const len = arr.length;

  for (let i = 0; i < len - 1; i++) {
  // 전체 요소를 조회하면서 가장 작은 수의 인덱스를 찾는다.
  // len - 2 인덱스까지 정렬을 하면, 마지막 인덱스인 len - 1도 자동 정렬이 되기 때문에
  // len - 1 인덱스 까지만 반복문을 실행한다.
  
    let minIndex = i;
    // 반복문을 시작하는 인덱스가 가장 작은 수의 인덱스라고 가정하고 시작한다.

    for (let j = i + 1; j < len; j++) {
    // i 다음 인덱스부터 시작해서 남은 모든 요소를 조회한다.
    
      if (arr[minIndex] > arr[j]) {
        minIndex = j;
        // 만약 현재까지 찾은 가장 작은 수보다 더 작은 수가 나오면, 
        // 해당 수의 인덱스로 변경한다.
        
      }
    }

    if (i !== minIndex) {
      [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
      // 조회하면서 찾은 가장 작은 수의 위치를 가장 왼쪽으로 변경한다.
      
    }
  }

  return arr;
}

'컴퓨터 과학 > 알고리즘' 카테고리의 다른 글

삽입 정렬  (0) 2024.04.25
버블 정렬  (0) 2024.04.24

버블 정렬에 대해 알아봅니다.

버블 정렬

 

버블 정렬

 

1. 버블 정렬이란 무엇이고, 어떻게 이뤄지는가?

2. 코드로 살펴보기

 

1. 버블 정렬이란 무엇이고, 어떻게 이뤄지는가?

 물 속에서 물방울이 수면 위로 올라오는 것처럼 가장 큰 수가 계속 오른쪽으로 자리를 옮겨가면서 진행되는 정렬 알고리즘이다. 이중 반복문으로 진행되며, 각 회차마다 인접한 두 요소 (앞, 뒤)를 비교하고 앞의 요소가 뒤 요소보다 클 시 자리를 교환한다.
 이중 반복문을 사용하여 시간 복잡도는 항상 n^2으로 배열의 크기가 클수록 실행 시간이 크게 늘어난다.

2. 코드로 살펴보기

function bubbleSort(arr) {
  const len = arr.length;

  for (let i = 0; i < len - 1; i++) {
  // 배열의 전체 요소를 조회합니다. 단, 앞, 뒤 요소를 비교하므로 len - 1 미만으로 범위를 지정합니다.
  // 만약 len 미만으로 지정할 시, 맨 마지막 요소는 비교할 대상이 없어 문제가 발생합니다.
  
    for (let j = 0; j < len - 1 - i; j++) {
    // j의 범위는 len -1 -i 미만으로 지정합니다. len -1 -i 이상 인덱스 요소들은 이전 회차에서
    // 이미 정렬이 된 요소 이므로 다시 비교를 진행하지 않습니다.
    
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
        // 만약 앞의 요소가 뒤의 요소보다 클 시, 위치를 변경합니다.
        
      }
    }
  }

  return arr;
}

'컴퓨터 과학 > 알고리즘' 카테고리의 다른 글

삽입 정렬  (0) 2024.04.25
선택 정렬  (0) 2024.04.25

자바스크립트에서 비동기 작업을 가능하게 하는 이벤트 루프에 대해 알아봅니다.

자바스크립트의 이벤트 루프

 

자바스크립트의 이벤트 루프

 

1. 이벤트 루프는 왜 필요한가?

2. 이벤트 루프는 어떻게 작동할까?

3. 예시 코드로 살펴보기

 

1. 이벤트 루프는 왜 필요한가?

 자바스크립트는 싱글스레드 언어이다. 따라서 한번에 하나의 작업만 수행한다. 하지만 이 때의 문제는 만약 시간이 오래 걸리는 작업이 있을 시, 전체 서비스가 멈출 수 있다는 것이다. 예를 들어 서버에서 데이터를 모두 받아올 때까지 서비스의 작동이 멈춘다면 어떻게 될까?
 이러한 상황을 해결하기 위한 것이 이벤트 루프다.

2. 이벤트 루프는 어떻게 작동할까?

 알아야 할 주요 개념은 콜스택, 태스크 큐 2가지다. 콜 스택은 함수가 실행될 때, 콜스택에 추가된다. 콜스택에 담긴 작업은 순차적으로 실행된다.
 만약 당장 실행을 끝마치지 않아도 되는 작업 (비동기 작업)일 시 백그라운드로 옮겨 작업을 진행한다. 비동기 작업이 끝난 후 발생한 작업 (콜백 함수, 데이터 전처리 작업 등이 해당)은 태스크 큐에 추가된다.
 이후 콜스택이 비었을 때 테스크 큐에 있는 작업을 콜스택으로 옮겨 진행한다.

3. 예시 코드로 살펴보기

function fetchData() {
  console.log("fetchData 함수 시작");

  fetch("https://example.com").then((response) => {
    console.log("받아온 데이터를 json으로 변환");
    return response.json();
  });

  console.log("fetchData 함수 끝");
}
 상단의 코드가 실행되는 과정은 다음과 같다.

 1. fetchData 함수가 콜스택에 추가된다.
 2. 'fetchData 함수 시작' 문자열이 출력된다.
 3. 서버에서 데이터를 불러오는 작업을 백그라운드로 옮겨 진행한다.
 3 - 1. 데이터를 모두 불러왔으면, '받아온 데이터를 json으로 변환' 문자열을 출력하는 작업을 태스크 큐에 추가한다.
 4. 'fetchData 함수 끝' 문자열을 출력하고, 콜스택에 fetchData 함수를 제거한다.
 5. 콜스택에 비었으므로, 태스크 큐에서 담긴 '받아온 데이터를 json으로 변환' 작업을 옮겨와 실행한다.

'javascript > 이론' 카테고리의 다른 글

for문과 forEach의 차이점 비교  (0) 2024.06.16

 npm이 아닌 yarn 쓰는 이유에 대해 알아봅니다.

yarn은 왜 쓰는가?

 

0. 여는글

1. npm과 yarn

2. yarn은 뭐가 더 좋은가

3. 정리

추천글

 

여는글

 처음 배웠던 것이 npm이었기에 프로젝트에 모듈을 설치할 때에 언제나 'npm start'를 입력하곤 했다. 하지만 입사한 회사에서는 yarn을 사용하고 있었기에 자동반사로 뛰쳐나오는 'npm install'을 억누르는 중이다. npm 대신 yarn을 쓰게 되면 뭐가 더 좋은 걸까?

npm과 yarn

    • 공통점
      • 자바스크립트의 패키지 매니저

    • npm
      • nodejs의 기본 패키지 관리자
      • 'npm install' 사용시 package-lock.json 파일로 의존성 관리

  • yarn
    • facebook에서 개발한 javascript 패키지 관리자
    • 'yarn insall' 사용 시 yarn.lock 파일로 의존성 관리

yarn은 뭐가 더 좋은가

  • 빠른 패키지 설치 (병렬 설치)
    • 여러 패키지를 설치할 때에 동시에 진행됨.
    • npm은 패키지 설치를 순차적으로 진행하므로 yarn을 사용한다면 설치 시간을 단축시킬 수 있음.

  • 오프라인 패키지 설치
    • yarn은 패키지를 설치할 때에 해당 패키지를 캐시에 저장(.yarn-cache 폴더)
    • 이후 오프라인일 때에도 해당 캐시를 이용해 설치 가능

정리

  • 시간을 단축할 수 있다!
    • yarn을 사용한다면 패키지를 병렬 설치할 수 있다는 점, 기존 패키지들이 캐시에 저장된다는 점을 통해 설치 속도를 줄일 수 있다.

추천글

canvas로 애니메이션을 구현해보겠습니다. 좌표를 어떻게 변경해야 할지 고려해 봅시다.

canvas로 간단 애니메이션 구현하기

 

 목차

 

1. 알아두기

2. 직선 이동 애니메이션

3. 원모양 이동 애니메이션

4. 반복되는 애니메이션

5. 왕복 이동 애니메이션

6. 구현 코드로 보기

추천글

 

1. 알아두기

  • x, y 좌표로 이동시키기
    • canvas의 애니메이션은 애니메이션의 x, y좌표를 변경하면서 진행됨
    • 연속되는 그림이 빠르게 지나가면서 애니메이션으로 보여진다라고 생각할 수 있음

 

  • 애니메이션의 속도는 좌표 변경 값의 크기에 따라 정해짐
    • 좌표 변경 값이 클 수록 속도가 빨라지고, 변경 값이 작을 수록 속도가 느려짐

 

  • 이전 화면이 필요 없다면 clearRect 메서드를 이용해 canvas를 지우기
    • clearRect를 사용하지 않으면 이전 화면도 그대로 남아있음. 상황에 따라 사용 여부 결정할 것.

 

  • requestAnimationFrame 함수를 이용하자
    • 작성한 애니메이션 함수를 requestAnimationFrame을 이용해 애니메이션으로 구현할 수 있음

2. 직선 이동 애니메이션

  • 애니메이션 시작 좌표 정하기
  • 좌표 증가 값 정하기 (애니메이션의 속도)
  • 애니메이션 함수 작성
    • 좌표 증가 시키기
    • 달라진 좌표에 맞춰 그림 그리기
    • 애니메이션 맞춤 설정
// lineAnimation.js

const canvas1 = document.getElementById("my-canvas1");
const ctx1 = canvas1.getContext("2d");

// 애니메이션 시작 좌표 정하기
let startX1 = 10;
let startY1 = 10;

const dx1 = 10;

function lineAnimation() {
  // 캔버스 지우기
  // 캔버스의 width, height 값 입력
  ctx1.clearRect(0, 0, canvas1.width, canvas1.height);

  ctx1.fillStyle = "black";

  // 좌표 증가 시키기
  startX1 += dx1;

  // 달라진 좌표에 맞춰서 그림 그리기
  ctx1.fillRect(startX1, startY1, 100, 100);

  // 애니메이션 맞춤 설정
  requestAnimationFrame(lineAnimation);
}

lineAnimation();

3. 원모양 이동 애니메이션

 

  • 시작 각도 지정
  • 각도 늘어나는 값 지정 (애니메이션 속도)
  • 애니메이션 함수 작성
    • 원의 중심 좌표 업데이트
    • 코사인(cos), 사인(sin)을 이용해  x 좌표, y 좌표를 반지름에 맞춰 비율 조정
      • cos(각도) = b / c
      • sin(각도) = a / c
      • 현재 각도에서 생성된 b와 c의 비율 값을 통해 원 외곽의 x 좌표 구하기
      • 현재 각도에서 생성된 a와 c의 비율 값을 통해 원 외곽의 y 좌표 구하기
      • 생성된 x, y 좌표에 경로의 둘레를 얼마나 크게 할 것 인지 값 설정
원 외곽의 x, y 좌표를 구하는 과정
cos(각도) = b / c, 가로 b를 사용하므로 x좌표에 사용

 

sin(각도) = a / c, 세로 a를 사용하므로 y 좌표에 사용

 

// circleAnimation.js

const canvas2 = document.getElementById("my-canvas2");
const ctx2 = canvas2.getContext("2d");

let startX2 = 50;
let startY2 = 50;

// 각도 지정
let angle = 0;

// 애니메이션 속도, 각도가 늘어나는 값
const speed = 0.1;

function circleAnimation() {
  ctx2.clearRect(0, 0, canvas2.width, canvas2.height);

  ctx2.beginPath();

  ctx2.arc(startX2, startY2, 10, 0, 2 * Math.PI);

  ctx2.fillStyle = "white";
  ctx2.fill();
  ctx2.strokeStyle = "black";
  ctx2.lineWidth = 2;
  ctx2.stroke();

  angle += speed;

  // 원의 중심 좌표 업데이트
  // 코사인, 사인을 이용해 x 좌표, y 좌표를 반지름에 맞춰 비율 조정
  // 뒤에 곱하는 값이 커질수록 경로의 둘레가 커짐
  startX2 = 50 + Math.cos(angle) * 40;
  startY2 = 50 + Math.sin(angle) * 40;

  // 다음 프레임 요청
  requestAnimationFrame(circleAnimation);
}

circleAnimation();

 

4. 반복되는 애니메이션

 

  • 직선 이동 애니메이션 재활용
  • 애니메이션 그림이 화면을 벗어나게 되면 좌표 초기화
// infiniteAnimation.js

const canvas3 = document.getElementById("my-canvas3");
const ctx3 = canvas3.getContext("2d");

let startX3 = 10;
let startY3 = 10;
let dx3 = 10;

function infiniteAnimation() {
  ctx3.clearRect(0, 0, canvas3.width, canvas3.height);

  ctx3.fillStyle = "black";

  // 화면을 벗어나게 되면 좌표 초기화
  if (startX3 === canvas3.width) {
    startX3 = 10;
  } else {
    startX3 += dx3;
  }

  ctx3.fillRect(startX3, startY3, 100, 100);

  requestAnimationFrame(infiniteAnimation);
}

infiniteAnimation();

5. 왕복 이동 애니메이션

  • 직선 이동 애니메이션 재활용
  • 이동 방향 결정하는 변수 추가
  • 특정 지점에 도달할 때마다 이동 방향 변경
  • 이동 방향에 따라 좌표 증감
// leftRightAnimation.js

const canvas4 = document.getElementById("my-canvas4");
const ctx4 = canvas4.getContext("2d");

let startX4 = 10;
let startY4 = 10;

let dx4 = 10;

// 이동 방향 결정하는 변수 추가
let isMoveRight = true;

function leftRightAnimation() {
  ctx4.clearRect(0, 0, canvas4.width, canvas4.height);

  ctx4.fillStyle = "black";

  // 특정 지점에 도달할 때마다 이동 방향 변경
  if (startX4 + 100 === canvas4.width) {
    isMoveRight = false;
  } else if (startX4 === 10) {
    isMoveRight = true;
  }

  // 이동 방향에 따라 좌표 증감
  if (isMoveRight) {
    startX4 += dx4;
  } else {
    startX4 -= dx4;
  }

  ctx4.fillRect(startX4, startY4, 100, 100);

  requestAnimationFrame(leftRightAnimation);
}

leftRightAnimation();

6. 구현 코드로 보기

추천글

2023.10.08 - [javascript/canvas] - 캔버스로 기본 도형(2d) 그리기

 

캔버스로 기본 도형(2d) 그리기

캔버스는 웹 페이지에 그래픽을 그리는 데에 사용되며, 이미지, 그래프, 애니메이션 등 시각적 요소를 생성하고 조작할 수 있습니다. 이 포스팅에서는 캔버스를 이용해 2d 기본 도형을 그리는 방

ddmoonddmoon.tistory.com

 

 

'javascript > canvas' 카테고리의 다른 글

canvas 캐릭터 방향키로 좌우 이동하기  (1) 2023.10.12
캔버스로 기본 도형(2d) 그리기  (0) 2023.10.08

 캔버스는 웹 페이지에 그래픽을 그리는 데에 사용되며, 이미지, 그래프, 애니메이션 등 시각적 요소를 생성하고 조작할 수 있습니다. 이 포스팅에서는 캔버스를 이용해 2d 기본 도형을 그리는 방법을 알아보겠습니다.

캔버스로 기본 도형(2d) 그리기

 

 목차

 

1. 캔버스란?

2. 직선 그리기

3. 사각형 그리기

4. 삼각형 그리기

5. 곡선 그리기

6. 원 그리기

7. 구현된 코드로 보기

 

1. 캔버스란?

  • 웹 페이지에 그래픽을 그리는 데 사용
  • 이미지, 그래프, 애니메이션, 게임에 활용 가능
  • 빠른 그래픽 렌더링으로 고성능
  • 복잡한 시각적 효과, 애니메이션에 적용 가능

 

  • 캔버스 생성하기
    • canvas 생성 후, id를 이용해 canvas 변수에 할당하기
    • canvas에서 ctx 가져오기
   <canvas id="my-canvas1" width="400" height="400"></canvas>
   
   <script>
   	
    // canvas 변수에 할당하기
 	const canvas1 = document.getElementById("my-canvas1");
    
    // "context"의 약자로, 캔버스의 요소를 조작할 때 사용
	const ctx1 = canvas1.getContext("2d");
   </script>

2. 직선 그리기

  • 시작점, 끝점 좌표 정하기
  • 선 설정하기
  • 좌표 이으면서 선 그리기
const canvas1 = document.getElementById("my-canvas1");
const ctx1 = canvas1.getContext("2d");

// 시작점, 끝점 좌표 정하기
const startX = 50;
const startY = 50;
const endX = 100;
const endY = 100;

// 선 설정 정하기
ctx1.strokeStyle = "black";
ctx1.lineWidth = 2;

// 선 그리기 시작
ctx1.beginPath();

// 시작점 설정
ctx1.moveTo(startX, startY);

// 끝점 설정
ctx1.lineTo(endX, endY);

// 선 그리기
ctx1.stroke();

3. 사각형 그리기

  • 사각형 스타일 설정하기
  • 사각형 위치, 크기 설정하기
    • ctx.fillRect(x 좌표,  y 좌표, 가로 길이, 세로 길이)
    • fillRect는 색이 채워진 사각형, strokeRect는 테두리만 그려진 사각형이 그려짐
const canvas2 = document.getElementById("my-canvas2");
const ctx2 = canvas2.getContext("2d");

// 사각형 스타일 설정

// 채우기 색상
ctx2.fillStyle = "black"; 

// 테두리 색상
ctx2.strokeStyle = "black"; 

// 테두리 두께
ctx2.lineWidth = 2; 

// 사각형 그리기
// x 좌표, y 좌표, 가로 크기, 세로 크기
// 색깔 채워진 사각형
ctx2.fillRect(50, 50, 100, 100); 

// 테두리만 있는 사각형
ctx2.strokeRect(50, 150, 100, 100);

4. 삼각형 그리기

  • 삼각형의 세 꼭지점 좌표 정한 후 이어주기
const canvas3 = document.getElementById("my-canvas3");
const ctx3 = canvas3.getContext("2d");

ctx3.beginPath();

// 시작점
ctx3.moveTo(100, 50);

// 두번째 점
ctx3.lineTo(150, 150);

// 세번째 점
ctx3.lineTo(50, 150); 

// 경로 닫기
ctx3.closePath(); 

// 테두리 색상
ctx3.strokeStyle = "black"; 

// 테두리 두께
ctx3.lineWidth = 2; 

// 삼각형 채울 색상
ctx3.fillStyle = "blue"; 

// 삼각형 내부 색상 채우기
ctx3.fill(); 

// 삼각형 테두리 그리기
ctx3.stroke();

5. 곡선 그리기

  • quadraticCurveTo() 혹은 bezierCurveTo() 함수 사용
    • quadraticCurveTo(곡선 제어점 x 좌표, 곡선 제어점 y 좌표, 최종 x 좌표, 최종 y좌표)
    • bezierCurveTo(1차 곡선 제어점 x 좌표, 1차 곡선 제어점 y 좌표, 2차 제어점 x, 2차 제어점 y, 최종  x, 최종 y)
const canvas4 = document.getElementById("my-canvas4");
const ctx4 = canvas4.getContext("2d");

ctx4.beginPath();

// 시작점 정하기
ctx4.moveTo(50, 50);

// 두 개의 제어점을 사용한 곡선 그리기
// 첫번째로 꺾을 지점 x 좌표, y좌표, 2번째로 꺾을 지점 x 좌표, y 좌표, 최종 x 좌표, y 좌표
ctx4.bezierCurveTo(50, 100, 150, 20, 250, 50);

ctx4.strokeStyle = "black";
ctx4.lineWidth = 2;

// 곡선을 테두리로 그리기
ctx4.stroke();

6. 원 그리기

  • arc 메서드 사용
    • arc(중심 x 좌표, 중심 y좌표, 반지름, 원의 시작 각도, 원의 끝 각도)
    • 시작 각도, 끝 각도를 통해 원의 일부만 그릴 수도 있음
const canvas5 = document.getElementById("my-canvas5");
const ctx5 = canvas5.getContext("2d");

ctx5.beginPath();

// 중심 x 좌표,  중심 y, 좌표, 반지름, 원의 시작 각도, 원의 끝 각도
// 시작각도, 끝각도를 통해 원의 일부만 그릴 수도 있음
ctx5.arc(100, 100, 50, 0, 2 * Math.PI);

ctx5.fillStyle = "white";
ctx5.fill();
ctx5.strokeStyle = "black";
ctx5.lineWidth = 2;
ctx5.stroke();

7. 구현된 코드로 보기

'Set'은 중복된 값을 허용하지 않는 자료 구조 입니다. Set 자료구조를 사용하면 배열 내에서 중복된 값을 빠르게 제거할 수 있습니다.

Set 이용하여 배열에서 중복되는 값 제외하기

 

 목차

 

1. Set이란?

2. Set 사용법

3. Set으로 배열의 중복된 값 제거하기

 

1. Set이란?

  • Javascript에서 제공하는 내장 객체로, 중복된 값을 허용하지 않는 값들의 집합
  • 중복된 값을 허용하지 않음
  • 순서를 보장하지 않음(인덱스 없음)
  • 고유 메서드 존재 (add, delete, has, clear 등의 메서드 사용)

2. Set 사용법

  • add : 값을 추가
    - 이미 해당 값이 있다면 무시
const mySet = new Set();
mySet.add(1);
mySet.add(2);
mySet.add(2); // 이미 중복된 값이 있으므로 무시됨
console.log(mySet); // Set { 1, 2 }
  • delete: 값을 삭제
    - 해당 요소가 없다면 무시
const mySet = new Set([1, 2, 3]);
mySet.delete(2); // 2를 제거
mySet.delete(4); // Set에 없으므로 아무런 작업도 하지 않음
console.log(mySet); // Set { 1, 3 }
  • has: 해당 값이 있는지 확인
    - 있으면 true, 없으면 false 반환
const mySet = new Set([1, 2, 3]);
console.log(mySet.has(2)); // true
console.log(mySet.has(4)); // false
  • clear: 모든 요소 제거
const mySet = new Set([1, 2, 3]);
mySet.clear(); // Set을 비움
console.log(mySet); // Set {}

3. Set으로 배열의 중복된 값 제거하기

  • 해당 배열 Set으로 변환
  • 생성한 Set 다시 배열로 변경
const arr = [1, 2, 1, 4, 2];
const mySet = new Set(arr);
const result = [...mySet];
console.log(result); // [1, 2, 4]

+ Recent posts