본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Html 캔버스/Html 캔버스 튜토리얼 (내가만든 차트!)

Html Canvas (Html 캔버스) 튜토리얼 (차트만들기!) - 3 : 선 그리기1

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2020. 1. 30.

 

캔버스 사각형 그리기와 사각형 채우기를 통해서 기본 사용법을 익혔다.

이번에는 선 그리는 방법이다.

사용법은 매우 간단하다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Canvas</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<style>
    body{padding: 5%;text-align: center;}
    canvas{border: 1px solid gray;border-radius: 3px;}
</style>
<body>
    <canvas width='600' height='600' id='canvas' ></canvas>
</body>
</html>

<script>    
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    
    ctx.beginPath();
    ctx.moveTo(30,10);
    ctx.lineTo(30,60);    
    ctx.stroke();
</script>

 

앞서 살펴본 beginPath가 나왔다. beginPath는 캔버스에서 시작을 의미한다.

즉, 내가 이제 그릴거다~ 라는 의미이다.

moveTo 함수를 통해서 선을 그리는 시작점을 주고 lineTo를 통해서 그리는 마지막 지점을 알려준다.

stroke 함수는 moveTo와 lineTo로 경로가 정해진 지점에 선을 그리는 역할을 수행한다.

위 내용을 실행하여보면 아래사진처럼 그림이 그려 진다.

수직으로 그려진 선의 모습

 

캔버스에서 선의 굵기를 따로 주지 않으면 기본값으로 1을 사용한다.

위 내용을 토대로 보면, x좌표 30 y좌표 10만큼 출발지점에서 x좌표 30 y좌표 60까지 기본 선 굵기인 1을 가지고 그림을 그린 것을 알 수 있다.

 

선의 굵기가 1인경우에 캔버스에서의 좌표는 아래 사진처럼 살펴 볼 수 있다.

선의 굵기가 1이면 분할하여 좌우 x좌표로 넘어간다.

 

x좌표가2 y좌표가 2가 출발지점이면서 굵기가 1이면 x좌표는 실제로 1.5부터 시작을 하게 된다.

선의 굵기에 따라서 시작 좌표의 1/2이 오버하게 되는 것 이다.

요 개념이 나중에 요긴하게 쓰일 것 이다.

 

선의 굵기를 담당하는 기능은 lineWidth이다.

<script>    
    ctx.beginPath();
    ctx.moveTo(30,10);
    ctx.lineTo(30,60);    
    ctx.lineWidth = 10;  //요렇게 사용한다.
    ctx.stroke();
</script>

 

선의 굵기 뿐만 아니라 선 끝 스타일을 줄 수 있다.

선 끝 스타일은 3가지를 지원한다.

 

요 내용을 토대로 적용하여 보면,

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Canvas</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<style>
    body{padding: 5%;text-align: center;}
    canvas{border: 1px solid gray;border-radius: 3px;}
</style>
<body>
    <canvas width='600' height='600' id='canvas' ></canvas>
</body>
</html>
<script>    
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    ctx.lineWidth = 10;

    ctx.beginPath();
    ctx.moveTo(30,10);
    ctx.lineTo(30,60);
    ctx.lineCap = 'butt';    
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(60,10);
    ctx.lineTo(60,60);    
    ctx.lineCap = 'round';
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(90,10);
    ctx.lineTo(90,60);    
    ctx.lineCap = 'square';
    ctx.stroke();
</script>

요렇게 잘 그려진다.

 

위 코드에서 눈여겨 보아야 할 점은 beginPath가 여러번 사용된 점 이다.

만약 beginPath를 지우고 사용한다면 square 스타일이 공통 적용된 모습의

일자형태가 나오게 된다.

왜나하면 1붓그리기를 하는 개념이기 때문이다.

beginPath를 시작하는 순간 여태껏 그려온 내용을 멈추고 새로운 내용으로 그린다는 개념으로 이해하자.

 

선을 이어그리면서 1가지 효과를 적용하려면 beginPath를 최초 한번만 사용하고 moveTo와 lineTo로 이어서 그려주면 된다.

아래 코드를 실행하여보자.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Canvas</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<style>
    body{padding: 5%;text-align: center;}
    canvas{border: 1px solid gray;border-radius: 3px;}
</style>
<body>
    <canvas width='600' height='600' id='canvas' ></canvas>
</body>
</html>

<script>    
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    ctx.lineWidth = 5;
    ctx.lineCap = 'butt';    
    ctx.beginPath();
    ctx.moveTo(0,0);
    ctx.lineTo(30, 30);
    ctx.lineTo(30, 90);
    ctx.lineTo(0, 90);
    ctx.lineTo(0, 0);
    ctx.stroke();
</script>

 

lineTo를 통해서 다음 그릴 지점을 그려 주었다.

 

자세히보면 마지막에 그린 좌측 부분이 조금 짤린 것을 볼 수 있다. (짤린게 아니라 음수값 만큼 캔버스 내부로 들어간 것 이다)

맨 처음에 설명한 선이 좌우로 1/2 을 넘어간다는 개념 때문에 나타낸 현상이다.

조금 더 정상적인 모습을 나타내려면 lineTo에서 선의 굵기 값의 절반 값을 더해 주어야 할 것 이다.

스크립트 내용을 아래처럼 수정하자.

    var lineWidth = 5;   //선의 굵기
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    ctx.lineWidth = lineWidth;
    ctx.lineCap = 'butt';    

    ctx.beginPath();
    ctx.moveTo(lineWidth / 2,0);   //0값을 선의 절반값으로 바꾸자.
    ctx.lineTo(30, 30);
    ctx.lineTo(30, 90);
    ctx.lineTo(lineWidth / 2, 90); //0값을 선의 절반값으로 바꾸자.
    ctx.lineTo(lineWidth / 2, 0);  //0값을 선의 절반값으로 바꾸자.
    ctx.stroke();

 

스크립트를 수정한 후 실행하면 같은 굵기 모양의 선이 잘 그려진다.

선의 굵기가 일정하게 그려졌당

 

 

선과 선이 만나는 구간도 효과를 줄 수 있다.

효과는 3가지를 지원 하며 lineJoin을 통해서 적용 가능하다.

round, bevel, miter

 

lineJoin이라는 함수에 위 3가지 형태의 값을 넣어주면 효과를 볼 수 있다.

    var lineWidth = 10;
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    ctx.lineWidth = lineWidth;
    ctx.lineCap = 'butt';    
    ctx.lineJoin = 'round';  //효과
    ctx.beginPath();
    ctx.moveTo(lineWidth / 2,0);
    ctx.lineTo(30, 30);
    ctx.lineTo(30, 90);
    ctx.lineTo(lineWidth / 2, 90);
    ctx.lineTo(lineWidth / 2, 0);
    ctx.stroke();

 

아래 사진처럼 정상적으로 둥근모양의 연결 처리가 된 것을 볼 수 있다.

둥글둥글하게 잘 적용 되었다.

 

* 정리하여보자!

 1. 선을 그리는 것은 beginPath로 시작을 알려주고 moveTo를 통해서 시작점을 선정 후에 lineTo로 이어가면 된다.

 2. moveTo와 lineTo 함수는 첫번째 값으로 x좌표, 두번째 값으로 y좌표를 받는다.

 3. 기본 선의 굵기는 1 이다.

 4. 선은 기본적으로 x축에 1/2(절반)을 걸쳐서 좌우로 오버되어 들어간다.

 5. beginPath를 한번만 선언하여 선을 그리면 한붓 그리기 효과가 적용 된다.

 6. beginPath를 구간마다 선언하여 선을 그리면 서로 다른 효과가 적용되는 선이 그려 진다.

 7. 선의 끝 모양은 lineCap을 통해서 정해줄 수 있다.

  -> butt, round, square

 8. 선과 선의 연결부분도 스타일을 줄 수 있으며 lineJoin을 통해서 가능 하다.

  -> round, bevel, miter

 

조금만 쉬었다가 선 그리기에 대해서 좀 더 알아보자.

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글