Javascript

Canvas를 원하는 모양으로 자르기(clip)

joy_lee 2021. 11. 3. 21:18

Canvas는 Javascript를 이용해 원하는대로 그림을 그릴 수 있는 API이다. 보통 직사각형의 캔버스를 사용하는데, 특이한 모양의 캔버스를 만들고 싶어서 찾아보았다.

 

캔버스 만들기

1
2
3
4
5
6
7
8
9
<body>
    <canvas id="canvas"></canvas>
</body>
<script>
    const canvas = document.getElementById("canvas");
    canvas.width = 300;
    canvas.height = 300;
    canvas.style.border = "1px solid black";
</script>
cs

300px*300px 크기의 캔버스를 화면에 만들고, 검은색 테두리로 캔버스를 구분할 수 있도록 한다.

 

원하는 모양 그리기

직사각형

직사각형 모양은 정해진 메소드로 쉽게 그릴 수 있다.

색칠된 직사각형 fillRect(x, y, width, height)
윤곽선 strokeRect(x, y, width, height)
지우기 clearRect(x, y, width, height)

 

원/호

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

x, y 원(호)의 중심 좌표
radius 반지름
startAngle 호를 그리기 시작할 각도
endAngle 호를 그리기 마칠 각도
anticlockwise startAngle부터 endAngle까지
true : 반시계방향으로 호를 그린다
false : 시계방향으로 호를 그린다

원을 그리고 싶은 경우에는 arc(x, y, radius, 0, Math.PI * 2, true); 를 입력하면 된다.(anticlockwise는 상관없다)

 

복잡한 모양

직사각형이나 원, 호가 아닌 여러가지 복합적인 모양을 가진 경우에는 직접 선(경로/path)을 그려줘야 한다.

beginPath() 새로운 경로를 만든다
moveTo(x, y) 펜을 (x, y)위치로 이동한다
lineTo(x, y) 현재 위치에서 (x, y)까지 선을 그린다
closePath() 현재 위치에서 시작점까지 직선으로 이어서 도형을 닫는다
stroke() 윤곽선을 이용해 도형을 그린다
fill() 경로의 내부를 채워서 내부가 채워진 도형을 그린다

 

양말 모양을 위의 메소드를 이용해 그려보았다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const ctx = canvas.getContext("2d");
 
// Create circular clipping region
ctx.beginPath();
ctx.moveTo(14550); // 시작점
ctx.lineTo(21050); 
ctx.lineTo(210170);
ctx.arc(17517535, 0, Math.PI*0.4false); // 양말 발꿈치
ctx.lineTo(100240);
ctx.arc(9021130, Math.PI*0.4, Math.PI*1.3false); // 양말 앞부분
ctx.lineTo(145156);
ctx.lineTo(14550);
ctx.stroke(); // 선 그리기
ctx.clip(); // 캔버스 모양대로 
cs

 

*주의할점

arc()의 시작점

arc()의 경우 직접 경로가 시작하는 점을 입력하는 것이 아니다. 원의 중심과 반지름을 입력하고, 시작하는 곳의 각도를 통해 시작점을 정해주는 것이다.

만약 경로를 그리던 마지막 점과 호가 시작하는 곳이 다르다면 두 점 사이에 직선을 그리고 호를 시작한다.

1
2
3
4
5
6
7
ctx.beginPath();
ctx.moveTo(14550); // 시작점
ctx.lineTo(21050); 
ctx.lineTo(210170);
ctx.arc(17517535, Math.PI*1.5, Math.PI*0.4true);
ctx.stroke(); // 선 그리기
ctx.clip(); // 캔버스 모양대로 잘라내기
cs

로 입력할 경우, 아래와 이 선이 그어진다.

경로의 마지막 위치와 호의 시작점을 잘 맞춰줘야 한다.

 

arc()의 반지름 정하기

직선과 arc()의 호가 만나려면 반지름을 호의 중심과 경로의 마지막 위치 사이의 거리로 지정해줘야 한다.

두 점 사이의 거리로 계산해 반지름을 정해주면 된다.

 

캔버스 자르기

위의 코드에서 ctx.stroke()까지 진행하면 경로를 따라 선을 그어준다. 마지막에 ctx.clip()을 통해 경로대로 캔버스를 잘라준다.

 

clip() 그려진 경로를 잘라 내부에서만 그림을 그릴 수 있도록 한다.

clip()으로 자른 부분에만 색을 칠할 수 있고, 외부에는 그림을 그릴 수 없다.

 

 

참고한 사이트

https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes

 

캔버스(canvas)를 이용한 도형 그리기 - Web API | MDN

앞서 캔버스 환경 설정(canvas environment)을 완료 하였다면, 이제 어떻게 캔버스에 그릴수 있는지에 대하여 자세하게 알아봅시다. 이 글을 끝내고 난 후, 여러분은 어떻게 사각형, 삼각형, 선, 아

developer.mozilla.org

https://m.blog.naver.com/javaking75/140169690495

 

HTML5 canvas - 캔버스에 사각형 그리기 ( fillRect(),strokeRect(),clearRect() )

HTML5 canvas - fillRect() 함수로 사각형 그리기 fillRect(x,y,width,height) ; 색이 채워진 사각형...

blog.naver.com

https://squll1.tistory.com/entry/canvas-arc-원호-그리기

 

[canvas] arc 원호 그리기

이제 곡선을 그려보도록 하겠습니다. 곡선중에서 원호를 그려보도록 하겠습니다. 그리는 방식은 선을 그리는 방식과 유사합니다. beginPath(), arc(), stroke() 메서드를 사용하고 넓이와 색깔은 line에

squll1.tistory.com

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip

 

CanvasRenderingContext2D.clip() - Web APIs | MDN

The CanvasRenderingContext2D.clip() method of the Canvas 2D API turns the current or given path into the current clipping region. The previous clipping region, if any, is intersected with the current or given path to create the new clipping region.

developer.mozilla.org