Canvas

hanyoko·2023년 6월 21일
0

JAVASCRIPT

목록 보기
32/32
post-thumbnail

Canvas

HTML의 태그로서 캔버스 스크립트 API 또는 WebGL API 와 함께 사용하여
그래픽과 애니메이션을 그릴 수 있다.

html 문서 내부에 그림을 그릴 수 있는 일종의 '컨테이너' 엘리먼트이다


canvas 사용

1. html 문서에 canvas 엘리먼트 선언

2. canvas 엘리먼트에 id 속성을 설정

3. canvas 태그 내부에 width, height 를 설정

4. canvas 내장 '그리기 객체'를 취득한다.

5. 그리기 객체에 [채우기색, 선색, 그림자, 그라데이션] 등을 설정한다.

6. 그리기 객체를 통해 [선, 사각형, 원, 텍스트] 등을 그린다.

7. 자바스크립트를 통해 다양한 효과를 구현


canvas 주의사항

  1. canvasid 값으로 접근할 수 있어야 한다.

  2. canvas의 크기(width, height)는 반드시 canvas 태그 내에 설정해야 한다.

=> CSS 사용시, 화면 왜곡 및 깨짐이 발생할 수 있다.

  1. canvas 의 너비, 높이는 canvas.width, canvas.height 로 취득 가능하다.

<canvas> element

<canvas id="tutorial" width="300" height="150"></canvas>


canvas 그리기 : 직사각형

  • fillRect (x, y, width, height)
    색칠된 직사각형을 그린다.

  • strokeRect (x, y, width, height)
    직사각형 윤곽선을 그린다.

  • clearRect (x, y, width, height)
    특정 부분을 지운 직사각형을 그린다.

예시 : fillRect(10, 10, 60, 60)은 10px만큼 떨어진 곳에 60px짜리 정사각형을 그리라는 뜻


canvas 그리기 : path

path는 점들의 집합이며, 서로 연결되면서 도형을 만들 수 있다.

  • beginPath()
    새로운 path를 만든다.

  • closePath()
    path를 닫는다.

  • stroke()
    윤곽선을 이어 도형을 그린다.

  • fill()
    path 내부를 채운다.

  • beginPath()
    새로운 path를 만든다.

  • closePath()
    path를 닫는다.

  • stroke()
    윤곽선을 이어 도형을 그린다.

  • fill()
    path 내부를 채운다.

  • moveTo(x, y)
    펜을 지정된 x, y 좌표로 옮긴다.

  • lineTo(x, y)
    현재의 드로잉 위치에서 x와 y로 좌표점까지 연결하는 선을 그린다.


canvas 그리기 : 원형

  • arc(x, y, radius, startAngle, endAngle, anticlockwise)
    (x, y) 위치에 중점을 두면서, 반지름 r을 가지고,
    startAngle에서 시작해, endAngle에서 끝나며, 주어진 anticlockwise방향으로 향하는 아치를 그린다.

  • arcTo(x1, y1, x2, y2, radius)
    주어진 반지름 r과 기준점 (x1, y1)을 가지고, 다음 기준점(x2, y2)을 잇는 직선을 그린다.


canvas 그리기 : 곡선

  • quadraticCurveTo(cp1x, cp1y, x, y)
    (cp1x, cp1y)로 설정된 기준점을 사용해, 현재 펜 위치에서 (x,y)좌표로 주어진 끝점까지 이차 베지에곡선을 그린다.

  • bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
    (cp1x, cp1y)와 (cp2x, cp2y)로 설정된 기준점을 사용해,
    현재 펜 위치에서 (x, y)좌표로 주어진 끝점까지 곡선을 그린다.

ctx.beginPath();
ctx.moveTo(15, 25);
ctx.quadraticCurveTo(25, 25, 25, 65);
ctx.quadraticCurveTo(60, 80, 100, 65);
ctx.quadraticCurveTo(100, 20, 110, 25);
ctx.quadraticCurveTo(50, 30, 15, 25);
ctx.stroke();

canvas 그리기 : Path2D objects

  • Path2D()
    새로운 인스턴스화된 Path2D Object를 만든다.

canvas 색상 적용

  • fillStyle = color
    도형을 채우는 색을 설정

  • strokeStyle = color
    도형의 윤곽선 색을 설정


canvas 투명도

캔버스로 그린 도형에 투명도를 적용하려면, globalAlpha 값을 주거나 CSS 색상값에 rgba를 주면 된다.

  • globalAlpha = value
    캔버스에 그려지는 모든 도형들의 투명도를 조절한다.
function draw() {
  let ctx = document.getElementById("Canvas").getContext("2d");
  ctx.fillStyle = '#e5ff00';
  ctx.fillRect(0,0,200,200);

  for(let i = 0; i < 16; i++;){
    ctx.beginPath();
    ctx.arc(15+(Math.random()*150+i), 30+(Math.random()*140+i), 2+(Math.random()*3), 0, Math.PI*2, true);
    ctx.fillStyle = 'rgba(255,255,255,'+(0.3+(Math.random()*1))+')'
    ctx.fill();
  }
}

canvas 선 스타일

  • lineWidth = value
    선의 두께를 설정한다.

  • lineCap = type[butt | round | square]
    선의 끝 모양을 설정한다.
    butt: 끝 좌표에 딱 맞게 | round: 동그랗게 | square: 선 두께 반 만큼의 사각형 영역을 더하여

  • lineJoin = type[round | bevel | miter]
    두 선이 만나는 지점의 모양을 설정한다.


canvas 그라디언트

  • createLinearGradient(x1, y1, x2, y2)
    (x1, y1)에서 시작해 (x2, y2)에서 끝나는 선형 그라디언트 오브젝트를 생성

  • createRadialGradient(x1, y1, r1, x2, y2, r2)
    반지름 r1을 갖고 (x1, y1)을 중심으로 하는 원과,
    반지름 r2를 갖고 (x2, y2)를 중심으로 하는 원형 그라디언트 오브젝트를 생성

let gradient = ctx.createLinearGradient(0,0,200,200); //그라디언트 생성
gradient.addColorStop(0,'#c6cff8'); //그라디언트 컬러값(처음)
gradient.addColorStop(1,'#de89c0'); //그라디언트 컬러값(끝)
ctx.fillStyle = gradient; //그라디언트로 채우기
ctx.fillRect(0,0,200,200); //사각형 생성

canvas 그림자

  • shadowOffsetX = float
    그림자가 오브젝트에서 수평으로 얼마나 떨어져 있는지 설정한다.

  • shadowOffsetY = float
    그림자가 오브젝트에서 수직으로 얼마나 떨어져 있는지 설정한다.

  • shadowBlur = float
    블러 효과의 크기를 설정한다.

  • shadowColor = <color>
    그림자의 색상을 설정한다.

ctx.fillStyle = '#bfdac9';
ctx.fillRect(0,0,300,150);

ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 4;
ctx.shadowBlur = 18;
ctx.shadowColor = "rgba(0, 0, 0, 0.3)";

ctx.font = "58px Sans Serif";
ctx.fillStyle = "#fff";
ctx.fillText("make shadow", 45, 95);

사용 예시

canvas.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas { background-color: #eee; }
    </style>
</head>
<body>
    <canvas width="500" height="300"></canvas>
    <script>
        let canvas = document.querySelector("canvas");
        let ctx = canvas.getContext("2d");
        ctx.fillStyle = "yellow";
        ctx.fillRect(100,50,100,100);
        ctx.clearRect(100,50,50,50);
        ctx.strokeRect(200,200,50,50);

        //패스를 시작(펜도구 선택)
        ctx.beginPath();
        //시작위치 - 처음 점 찍기
        ctx.moveTo(250,50);
        //선 그리기 -다음 점 찍기
        ctx.lineTo(300,50);
        ctx.lineTo(300,70);
        ctx.fill();
    </script>
</body>
</html>

canvas-path.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas {
            background-color: #eee;
        }
    </style>
</head>
<body>
    <canvas width="1000" height="500"></canvas>
    <script>
        const canvas = document.querySelector("canvas");
        const ctx = canvas.getContext("2d");
        ctx.beginPath();
        ctx.moveTo(100,100);
        ctx.lineTo(150,100);
        ctx.lineTo(150,150);
        ctx.lineTo(100,150);
        ctx.closePath();
        ctx.stroke();

        let num = 100;
        for(let i=0; i<10; i++){
            ctx.fillRect(num+(i*80),200,50,50);
        }
    </script>
</body>
</html>

canvas-arc.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas { background-color: #eee; }
    </style>
</head>
<body>
    <canvas id="canvas" width="1000" height="500"></canvas>
    <script>
        let canvas = document.querySelector('canvas')
        let ctx = canvas.getContext("2d")
        ctx.beginPath();
        ctx.arc(100,100,50,0,Math.PI*2,true);
        ctx.fillStyle = "pink";
        ctx.fill();
    </script>
</body>
</html>

canvas-event.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas { background-color: #eee; }
        .color-btn {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            border: 0;
            outline: 0;
        }
        .color-btn[data-value = "red"] {background: red;}
        .color-btn[data-value = "pink"] {background: pink;}
        .color-btn[data-value = "green"] {background: green;}
    </style>
</head>
<body>
    <canvas id="canvas" width="1000" height="500"></canvas>
    <div id="btns">
        <button class="color-btn" data-type="color" data-value="red"></button>
        <button class="color-btn" data-type="color" data-value="pink"></button>
        <button class="color-btn" data-type="color" data-value="green"></button>
        <button class="clearbtn">지우기</button>
    </div>
    <script>
        const canvas = document.querySelector("#canvas");
        const ctx = canvas.getContext("2d");
        const btnDiv = document.querySelector("#btns");
        const clearBtn = document.querySelector(".clearbtn");
        let drawingMode; //true일 때만 그리기
        ctx.lineWidth = 30;
        ctx.lineCap = "round";
        //선색변경
        function downHandler(){
            drawingMode = true;
        }
        function upHandler(){
            drawingMode = false;
        }
        function moveHandler(e){
            if(!drawingMode) return;
            let x = e.pageX;
            let y = e.pageY;
            ctx.beginPath();
            ctx.moveTo(x,y);
            ctx.lineTo(x,y);
            ctx.stroke();
        }
        function chRed(){
            ctx.lineColor = "red"
        }
        //색상변경
        function setColor(e){
            let colorVal = e.target.dataset.value;
            console.log(colorVal);
            ctx.strokeStyle = colorVal;
        }
        canvas.addEventListener("mousedown", downHandler);
        canvas.addEventListener("mouseup", upHandler);
        canvas.addEventListener("mousemove", moveHandler);
        btnDiv.addEventListener("click",setColor);
        clearBtn.addEventListener("click",function(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
        })
    </script>
</body>
</html>

0개의 댓글