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

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

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


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

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

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

선 그리기에 대해서 좀더 알아보자.

앞선 내용처럼 선은 굵기를 줄 수 있고 시작과 종료점을 주어 다양한 모양으로 그릴 수 있다.

선의 굵기가 굵어지면 문제되는 것이 굵은 선의 끝부분이 넘처서 생각하는바와 다른 모양이 나온다는 점 이다.

아래코드를 보자.

<!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.strokeStyle = 'gray';
    ctx.lineWidth = 23;
    ctx.moveTo(20, 100);
    ctx.lineTo(30, 50);
    ctx.lineTo(45, 100);
    ctx.lineTo(65, 50);
    ctx.lineTo(90, 100);
    ctx.stroke();
</script>

 

자세히보면 y값은 100 ~ 50 사이만 증감하는 것을 볼 수 있다.

그렇다면 선은 예상하건데 높이가 일정한 패턴을 보여야 하는게 맞다.

그러나 실제로 실행하여보면..

엥...높낮이가 틀리다??!?

 

이상하다...y값이 50 또는 100이기 때문에 높이는 같아야 하는데 말이다.

위 현상은 선의 굵기 때문에 선의 끝 부분이 삐져(?)나오는 현상이다.

아래 사진을 보자.

 

대략 요러한 현상때문에 오버되는 효과가 나타나게 되는 것 이다.

 

같은 y좌표 값을 가지더라도 선의 굵기가 굵어질수록 무언가 위로 솟구치는 모양이 나와버리게 된다.

요러한 현상이 발생하게되면 선이 오버됨에 따라서 잘못 그려진 것이라 볼 수도 있다.

선이 연결되는 스타일이 기본(mitter)인 경우에는 miterLimit를 활용해서 삐져나온 부분을 잘라낼 수 있다.

스크립트 내용을 바꾸어보자.

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    
    ctx.miterLimit = 1;  //요렇게 1값을 줘 보자
    
    ctx.beginPath();
    ctx.strokeStyle = 'gray';
    ctx.lineWidth = 23;
    ctx.moveTo(20, 100);
    ctx.lineTo(30, 50);
    ctx.lineTo(45, 100);
    ctx.lineTo(65, 50);
    ctx.lineTo(90, 100);
    ctx.stroke();

 

결과는...위에 올라온 부분이 뎅겅 잘려버렸다.

해당 값이 커지면 커질수록 삐져나온 부분에 대해서 허용하는 값이 늘어나는 효과가 발생하게 된다.

뎅겅~

 

그러면 문득 이러한 생각을 하게 된다.

선을 그렸으면 안에 내용을 채울수는 없는 것 인가?

정답은 : 가능하다이다.

스크립트를  수정하여보자.

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    ctx.beginPath();
    ctx.strokeStyle = 'gray';
    ctx.lineWidth = 3;
    ctx.moveTo(20, 100);
    ctx.lineTo(30, 50);
    ctx.lineTo(45, 100);
    ctx.lineTo(65, 50);
    ctx.lineTo(90, 100);
    ctx.stroke();
    ctx.fillStyle = 'rgba(130, 130, 10, 0.5)'; //채우는 색상 지정
    ctx.fill();  //채우기

 

선이 그어진 부분에 놀랍게도 색깔이 채워진 것을 볼 수 있다.

내부가 채워졌다.

 

그러면 위치값을 조금 바꾸어 채워보도록 하자.

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    
    ctx.beginPath();
    ctx.strokeStyle = 'gray';
    ctx.lineWidth = 3;
    ctx.moveTo(20, 100);
    ctx.lineTo(30, 50);
    ctx.lineTo(45, 100);
    ctx.lineTo(30, 150);

    ctx.stroke();
    ctx.fillStyle = 'rgba(130, 130, 10, 0.5)';
    ctx.fill();

 

다이아몬드 모양으로 색이 채워짐을 볼 수 있다.

다이아몬드 모양으로 색이 채워졌다.

 

한번더 스크립트를 변경하여보도록 하자.

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    ctx.beginPath();
    ctx.strokeStyle = 'gray';
    ctx.lineWidth = 3;
    ctx.moveTo(20, 100);
    ctx.lineTo(50, 150);
    ctx.lineTo(80, 100);
    ctx.stroke();
    ctx.fillStyle = 'rgba(130, 130, 10, 0.5)';
    ctx.fill();

 

이번에도 색이 잘 채워진 것을 볼 수 있다.

색이 위로 잘 채워졌다.

 

여기서 그러면 선이 채워지는 패턴을 볼 수 있다.

기본적으로 캔버스에서 선은 3개부터 이어진 상태에서 채우기 기능이 동작 한다.

또한 첫번째, 두번째 선에서 세번째 선으로 이동 할 때 방향을 고려하여 채우기가 진행이 된다.

세번째 선이 아래로가면 위 > 아래로 채우기를 실시하고, 세번째 선이 위로가면 아래 > 위로 채우기를 실시한다.

참 너무나 똑똑하지 않은가..

 

이러한 선 부분을 점선(dashed) 효과를 주어서 나타날 수도 있다.

setLineDash라는 함수를 사용하여 보자.

기존 코드에서 해당 setLineDash를 추가하여보자.

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    ctx.setLineDash([3, 2]); //선의 길이는3, 선과 선의 여백은2

    ctx.beginPath();
    ctx.strokeStyle = 'gray';
    ctx.lineWidth = 3;
    ctx.moveTo(20, 100);
    ctx.lineTo(50, 150);
    ctx.lineTo(80, 100);
    

    ctx.stroke();
    ctx.fillStyle = 'rgba(130, 130, 10, 0.5)';
    ctx.fill();

 

점선이 생겼다!!

 

요 점선에 offset(시작점)을 lineDashOffset 값을 줄 수도 있다.

음..그러니까 lineDashOffset 값을 변화시키면 시작지점이 바뀌어 선이 움직이는 모양이 나타나게 된다.

한줄 더 추가하여보자~

    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    ctx.setLineDash([5, 5]);   //변화가 잘 안보여 간격을 좀 더 주었다.
    ctx.lineDashOffset = -1;  //시작점

    ctx.beginPath();
    ctx.strokeStyle = 'gray';
    ctx.lineWidth = 3;
    ctx.moveTo(20, 100);
    ctx.lineTo(50, 150);
    ctx.lineTo(80, 100);
    

    ctx.stroke();
    ctx.fillStyle = 'rgba(130, 130, 10, 0.5)';
    ctx.fill();

 

요렇게 하고나면 사실 차이가 잘 안느껴진다.

lineDashOffset 값을 계속해서 -1씩 추가하여 새로고침을 해보면 미세하게 시작점이 뒤로가게되어 움직이는 효과가 나타난다.

그래서 setTimeout함수를 통해서 해당 간격을 계속해서 바꾸어보았다.

돈다돌아~

 

 

사실 원리는 별거아니지만..굳이 지금 알 필요는 없을 것 같다. ^^

 

 

정리하여보자!

* 선과 선의 연결이 mitter인 경우에는 miterLimit 값을 통해서 모서리 부분의 한계를 줄 수 있다.

* 선과 선의 연결 후 채우기는 최소 선이 3개 이상일 때 부터 가능하다.

* 선과 선의 연결 후 채우기를 실시하면 3번째 선 부터의 방향에 따라 캔버스가 채우기를 실시 한다.

* setLineDash를 통해서 점선 및 점선의 간격을 주어 선을 표현 할 수 있다.

* lineDashOffset을 통해서 점선의 시작점을 바꿀 수 있다.

 

이정도까지 하면 선과 관련된 기초내용을 살펴보았다고 할 수 있다.

다음번에는 텍스트와 관련된 내용에 대해서 살펴보자.

 

 

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

댓글