본문 바로가기
JavaScript

[javascript] 그림판 만들기

by teamnova 2021. 9. 25.

안녕하세요!

오늘은 스틱코드로 웹에서 사용할 수 있는,

간단한 그림판을 만들어 그림을 그리고, 지우고, 다운받을수 있는 기능을 만들어 보겠습니다.

소스는 하단 포스팅을 참조 해주세요.

 

https://stickode.com/detail.html?no=2467 

 

스틱코드

 

stickode.com

 

 

그림판은 상단에 그림을 그릴수 있는 canvas 영역, 컬러 펜두께를 선택하는 부분

되돌리기, 지우기, 다운로드 하는 버튼으로 구성이 되어 있습니다. 

 

먼저 board.php에 그림을 그릴수 있는 스케치북인 canvas를 구성하고, 도구부분을 만들어 보겠습니다.

 < board.php >  - 화면 구성하기 

상단에 CSS를 연결해주는 코드를 작성하고

그림판영역, 컬러칩, 컬러피커, 펜굵기조절, 버튼(되돌리기, 지우기, 다운로드)을 만듭니다.

하단에  Javascript를 연결하는 코드를 작성합니다.

<!-- css -->
<link rel="stylesheet" type="text/css" href="draw.css">
    
<!-- 그림판시작 -->
        <canvas id="canvas">
        </canvas>
        <div class="tools">
            <!-- 컬러칩 -->
            <div onclick="change_color(this)" class="color-field" style="background: red;"></div>
            <div onclick="change_color(this)" class="color-field" style="background: blue;"></div>
            <div onclick="change_color(this)" class="color-field" style="background: green;"></div>
            <div onclick="change_color(this)" class="color-field" style="background: yellow;"></div>

             <!-- 컬러피커  -->
            <input onInput="draw_color= this.value" type="color" class="color-picker" style="width:70px">
            <!-- 펜굵기 조절 -->
            <input type="range" min="1" max="100" class="pen-range"
                  onInput="draw_width=this.value">
            <!-- 되돌리기, 지우기, 다운로드 버튼  -->
            <button onclick="undo_last()"type="button" class="button">되돌리기</button>
            <button onclick="clear_canvas()" type="button" class="button">지우기</button>
            <button onclick="save()" type="button" class="button">다운로드</button>
        </div>

    <!-- javascript -->
    <script src="draw.js"></script>

 

 < draw.css > -   css 적용하기

기본여백을 설정하고, board.php에 만들어 놓은 class에 css를 적용해줍니다.

*{
    margin: 0;
    padding: 0;
    outline: 0;
}
/* 캔버스 설정 */
canvas{
    display: flex;
    justify-content: center;
    margin-top: 20px;
    cursor: pointer;
    background-color: whitesmoke;
}
/* 툴모음 전체 박스 */
.tools{
    max-width: 1000px;
    margin: 0 auto;
    margin-top:30px;
    display: flex;
    justify-content:center;
    flex-direction: row;
}

/* 툴 컬러 버튼 */
.tools .color-field{
    height:40px;
    width: 40px;  
    min-height:40px;
    min-width: 40px;
    cursor:pointer;
    border-radius: 50%;
    display: inline-block;
    box-sizing:border-box;
    border: 2px solid white;
    align-self:center;
}

/* 되돌리기,지우기,다운로드 버튼 */
.tools .button{
    align-self: center;
    width:100px;
    height:40px;
    border: 2px solid white;
    cursor :pointer;
    color: white;
    background:#222;
    font-weight: bold;
    margin:0 6px;
}
/* 컬러피커 */
.color-picker{
    align-self: center;
    margin:0 10px;
    height:50px;
}
/* 펜크기 */
.pen-range{
    align-self: center;
    margin:0 10px;  
}

 

 < draw.js > - JS로 펜의 움직임, 지우기, 다운로드 기능 만들어주기 

그림판에 그림을 그릴 수 있는 펜의 javascript를 만들어 보겠습니다.

캔버스 크기를 설정하고, 펜굵기 설정을 해줍니다.

 

touchstart, touchmove,mousedown, mousemove, touchend, mouseup, mouseout 이벤트 리스너를 생성합니다.

 

// 캔버스 설정
const canvas = document.getElementById("canvas");
canvas.width = window.innerWidth -0;
canvas.height =600;

let context = canvas.getContext("2d");
let start_background_color ="whitesmoke";
context.fillStyle = start_background_color;
context.fillRect(0,0,canvas.width, canvas.height);

// 펜설정, 컬러 굵기 
let draw_color ="black";
let draw_width = "2";
let is_drawing = false;

// 이전으로 돌리기 // 빈배열을 만든다.
let restore_array =[];
let index = -1;

// 컬러변경
function change_color(element){
    draw_color = element.style.background;
}

canvas.addEventListener("touchstart",start, false);
canvas.addEventListener("touchmove",draw, false);
canvas.addEventListener("mousedown",start, false);
canvas.addEventListener("mousemove",draw, false);

canvas.addEventListener("touchend",stop, false);
canvas.addEventListener("mouseup",stop, false);
canvas.addEventListener("mouseout",stop, false);

 

펜으로 이미지를 그리기

// 이미지 그리는 부분
function start(event){
    is_drawing = true;
    context.beginPath();
    context.moveTo(event.clientX - canvas.offsetLeft,
                   event.clientY - canvas.offsetTop);
    event.preventDefault();

    // 이전것 저장해두기 // 이벤트가 마우스아웃이 아닐때 마우스가 안에 있을때 위치값 저장.
    if(event.type != 'mouseout'){
    restore_array.push(context.getImageData(0,0,canvas.width, canvas.height));
    index += 1;
    }
    console.log(restore_array);
}

function draw(event){
    if(is_drawing){
        context.lineTo(event.clientX - canvas.offsetLeft,
                       event.clientY - canvas.offsetTop);
        context.strokeStyle = draw_color;
        context.lineWidth =draw_width;
        context.lineCap ="round";
        context.lineJoin ="round";
        context.stroke();
    }
}
  
function stop(event){
    if (is_drawing){
        context.stroke();
        context.closePath();
        is_drawing =false;
    }
    event.preventDefault();
}

 

전체 캔버스를 지우고, 한번 취소하기 

// 지우기
function clear_canvas(){
    context.fillStyle = start_background_color;
    context.clearRect(0,0,canvas.width, canvas.height);
    context.fillRect(0,0,canvas.width, canvas.height);

    restore_array=[];
    index =-1;
}

// 뒤로가기
function undo_last(){
    if(index <=0){
        clear_canvas();
    }else{
        index -= 1;
        restore_array.pop();
        context.putImageData(restore_array[index],0,0);
    }
}

 

그린이미지를 다운로드 버튼을 클릭하면, 다운받을 수 있습니다.

/ 저장하기
function save(){
    canvas.toBlob((blob)=>{

        const a = document.createElement('a');
        document.body.append(a);
        a.download ='export{timestamp}.png';
        a.href= URL.createObjectURL(blob);
        a.click();
        a.remove();
    });
}

 

 < 결과화면 >

 

 

스틱코드에는 더많은 꿀팁 코드들이 많이 있습니다! 다음 포스팅으로 찾아뵐꼐요~ 

더 많은 꿀팁 보러가기 ->

 

https://stickode.com/detail.html?no=2467 

 

스틱코드

 

stickode.com