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

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

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


Html 캔버스/Html 캔버스 에니메이션

Html canvas 그리는 좌표 저장 기능(x, y position)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2021. 3. 4.

Html 캔버스에서 내가 원하는 그림을 그린 뒤 좌표로 나타내기 위해 제작하여 보았습니다.

좌표값은 4가지 형태로 저장하였습니다.

데이터를 단순하게 그릴 x좌표값, y좌표값 그리고 다른 캔버스에서 사용하기 위해 준비한 비율값인 rateX, rateY값 입니다.

이렇게 저장하게 하였습니다.

 

원하는 그림을 그린뒤 연결하게 하려면 2가지 이벤트가 선행 되어야 합니다.

1. 마우스가 Down 상태 입니다.
2. 1번 조건이 만족한 상태로 마우스가 move 합니다. 이때가 그리기 시작을 의미 합니다.
3. 2번 상태에서 마우스가 up 인 경우에는 그리기가 종료되었음을 의미 합니다.

 

이러한 이벤트에 기능 붙이는것은 이제 어렵지 않습니다.

아래 코드처럼 기본 틀을 만들어 줍니다.

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.clientWidth;
const height = canvas.clientHeight;
   
canvas.addEventListener('mousedown', function (event) {
    마우스 다운, 그리기가 시작됩니다.
}); 

canvas.addEventListener('mouseup', function (event) {
    그리기가 종료 입니다.
});     

canvas.addEventListener('mousemove', function (event) {
    if(마우스가다운이면) 그리기 시작입니다.
}); 

 

다음으로는 그림을 그리는 행위를 관리하기위한 변수를 선언하여 줍니다.

마우스가 down일 때 특정 변수를 참(true)로 만들어 준 뒤에 마우스가 move하는 경우 그림을 그리게 합니다.

그리고 마우스가 up인 상태에서는 특정 변수를 거짓(false)로 만들어 줍니다.

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const width = canvas.clientWidth
const height = canvas.clientHeight
  
let isDown = false  
canvas.addEventListener('mousedown', function (event) {
    isDown = true
    마우스 다운, 그리기가 시작됩니다.
})

canvas.addEventListener('mouseup', function (event) {
    그리기가 종료 입니다.
    isDown = false  
})

canvas.addEventListener('mousemove', function (event) {
    if(isDown) 그리기 시작입니다.
}) 

 

isDown이라는 변수를 통해서 그리기 시작, 종료를 제어하도록 합니다.

다음으로 마우스가 move 하는 동안에는 배열을 1개 선언한 뒤에 캔버스의 데이터를 넣어주도록 합니다.

let data = [ ]
canvas.addEventListener('mousemove', function (event) {
    let x1 = event.clientX - canvas.offsetLeft;
    let y1 = event.clientY - canvas.offsetTop;
    if(isDown){
        data.push({x : x1, y : y1, rateX : x1/width, rateY : y1/height})
        drawing()  //그림을 그립니다.
    }
})

 

drawing이라는 함수는 주어진 data 배열값에서 반복문을 통해 clearRect와 moveTo, lineTo 함수를 호출하여 주도록 합니다.

마우스가 up된 상태이면 그리기가 종료된 것이며, 다음 그림을 그릴 수 있는 상황에 대비하여 새로운 배열에 값을 넣어주도록 합니다.

let savedArr =  []
canvas.addEventListener('mouseup', function (event) {
    isDown = false
    if(data && data.length > 0){
        savedArr[savedArr.length] = data  //그리는걸 저장
        data = [ ]  //초기화
    }
})

 

위 코드처럼 수정하고 나면 drawing라는 함수에서는 savedArr배열과, data 배열의 값을 반복문을 통해서 그려주도록 합니다.

function drawing(){
    ctx.clearRect(0, 0, width, height)
    ctx.lineWidth = 3;  
    ctx.lineCap = 'round';    
    ctx.lineJoin = 'round';        
    if(savedArr.length > 0){
        savedArr.forEach( (_item)=>{
            //moveTo, lineTo 함수를 호출 합니다.
        })
    }                
    ctx.save()
    ctx.beginPath()
    ctx.lineWidth = 3;  
    data.forEach( (_item, idx)=>{
        //moveTo, lineTo 함수를 호출 합니다.
    })
    ctx.stroke()          
    ctx.closePath()
    ctx.restore()
}

 

이제 데이터가 올바르게 들어갔는지 확인하여 봅니다.

비율대로 데이터가 잘 들어가는지 옆에 절반 크기의 캔버스(canvas)를 추가하여 비율 값으로 그림을 그려 보았습니다.

* 선 그리기 기능은 어렵지 않으므로 쉽게 할 수 있습니다.

x값과 y값으로 그린것이 아니라 rateX와 rateY값으로 표현 하였습니다.

 

그림을 그린 캔버스는 500 * 500의 크기이며, 저장된 데이터를 가져와서 출력한 캔버스는 250 * 250 크기 입니다.

캔버스(canvas)의 크기가 더 작거나 크더라도 비율값으로 좌표(x, y) 데이터가 저장되어 있으므로 문제없이 그려질 것 입니다.

물론 그림을 그리는 캔버스의 형태가 서로 다르면 조금은 어색하게 나올수도 있겠네요.

또한 데이터를 배열에 저장 하였으므로 "되돌아가기" 기능도 붙일 수 있겠습니다.

* 지우개 기능은 좀 어렵겠네요..ㅠ

직사각형과 정사각형이면 좀 난해하겠습니다..

 

이상으로 캔버스의 그리기 좌표를 저장하는 개념에 대해서 작성하여 보았습니다.

아래 제 깃허브에서 실제 동작하는 모습을 만날 수 있습니다.

또한 코드 자체를 일반적인 모양으로 올렸으므로 쉽게 코드를 확인 할 수 있습니다.

https://taeseungryu.github.io/sample/sampleView/drawingTogether/index.html

 

Canvas

 

taeseungryu.github.io

 

문의사항이나 궁금한 점은 언제든 댓글 또는 메일로 연락주세요~ :)

 

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

댓글