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

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

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


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

HTML Canvas 복권 긁기 효과(scratch, lottery)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2022. 2. 16.

 

* 게시글 하단의 제 깃허브 주소를 통해 실제 구현된 모습을 볼 수 있습니다

 

이번 기능은 웹에서 가려진 화면을 긁어서 가려진 내용을 보는 기능 입니다.

현실에서의 예를 들면, 즉석복권(lottery)을 사면 가려진 부분을 긁게 되면 당첨여부를 볼 수 있는 것과 같습니다.

동전같은 것으로 가려진걸 긁으면 나오게되죠^^

 

사실 이러한 기능을 만드는 것은 매우 쉽습니다.

캔버스 뒷부분에 이미지를 넣고, 캔버스 전체 영역을 색상을주어서 채우고 난 뒤에 마우스 이벤트 여부에 따라서 캔버스의 globalCompositeOperation 객체의 값을 "destination-out" 으로 주면 끝날 일 입니다.

 

그런데 사용자는 모든 화면을 전부 지우고 싶어하지 않습니다.

일정 수준으로 그림이 지워지게 된 경우면 자동으로 지워져서 내용물이 보여지기를 원합니다.

그러면 여기서 고려해야되는 점이..

"사용자가 얼만큼을 지워야 나머지가 자동으로 지워지는가"

라는 내용을 계산 해야 되는 것 이였습니다.

 

맨 처음 생각한 방법은 원을 그리면서 지우는 방식에서, 원과 원의 교점을 제거하여 넓이를 구한뒤에 총 크기에서 빼주는 방법 이였습니다.

아래 사진은 사용자가 원형으로 생긴 지우개를 이동하여 지우는 모습을 나타낸 사진 입니다.

요런식으로 지우개를 하는 것을 구상했습니다.

 

이런식으로 지우개를 원이라 가정하고, 마우스가 움직이면서 원이 추가되면 서로 겹치는 영역을 제외한 넓이값을 구하려고 하였습니다.

이러한 경우에는 부채꼴과 이등변삼각형, 피타고라스의 정리를 합하여 해당 기능을 구현하려 했습니다.

각 원의 중심점이 만나는 거리를 구한뒤에 부채꼴을 구하고, 삼각형 값을 빼주는 방법을 생각했습니다.

 

이렇게 원들의 교점값을 빼준다음에 넓이를 구해서,

"캔버스 전체 영역 - 원들의 넓이" 값을 백분률로 환산한뒤 70~80%정도가 지워지면 자연스럽게 다 지우려 했습니다.

그런데 원이 2개인 경우에는 해당 기능을 구하기가 쉬운데..

아래 처럼 마우스가 이동하면서 다양한 영역을 지운 경우에는 답이 없었습니다...

음....

 

원의 교점이 N개인경우에는 위 방법을 통한 공식으로 해결하기 어려웠습니다.

그러다가 생각을 좀 바꾸어 보았습니다.

"각각의 원과 원의 거리가 반지름보다 큰 경우 해당 영역을 추가하자"

이해를 위해서 일단 원을 그려보았습니다.

캔버스에 지우개라고 가정하고 원을 그렸습니다

 

캔버스의 넓이와, 높이를 가져와서 지우개의 크기만큼 지운뒤에 해당 값을 지우개의 크기만큼 간격(반지름+A)을 주어서 그리게 하였습니다.

위 캔버스는 넓이와 높이가 300픽셀이고, 지우개의 크기는 20픽셀 입니다.

대략적으로 원은 25개 정도가 들어갈 수 있습니다.

이에 사용한 계산방법 입니다.

    const canvas = document.getElementById("id")
    let ctx = canvas.getContext('2d')
    let width = canvas.width
    let height = canvas.height
    let size = 20

    let row = height / size / 2
    let column = width / size / 2
    let maxSize = row * column

    let inSideArray = []
    let dataArray = []


    //갯수 구한게 맞는지 확인식
    for(let i=0;i < column;i++){
        for(let j=0;j < row;j++){
            _drawding(size + column * column * i , size + row * row * j)
        }
    }

 

그러면 사용자가 마우스를 이동하여 캔버스를 지우기 시작한 첫 좌표값을 배열에 넣어주고, 

다음 마우스가 이동한 뒤에 해당 원이 첫 좌표값과의 중심점의 거리가 반지름보다 큰 경우 다시 배열에 넣어줍니다.

이러한 방법으로 해당 배열값을 채우면서, 위 공식에 의해서 구해진 원의 최대 갯수 값에서의 70~80% 사이에 원의 갯수가 도달하게 된 다면 전체 영역을 지워버리게 해 줍니다.

 

이때 지워지고 있는 좌표값을 추가로 선언한 배열에 담아두고, 

사용자의 지우기 행위가 70~80% 만큼 도달하게 된 다면, 전체 그리기 지우기 기법을 시간차이(setInterval)를 주어 점점 엹어지게 합니다.

 

두근거리는 마음을 안고 한번 테스트를 해 봅니다.

잘 되네요!!

 

원의 갯수를 줄이거나 늘리게되면 해당 갯수만큼의 비율로 산정되게 될 것 입니다.

물론...HTML을 아는 개발자라면 캔버스를 제거해서 바로 뒤의 사진부터 보겠네요.. : - )

 

제 깃허브(gitHub)에서 실제 동작하는 모습을 확인 할 수 있습니다.

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

 

스크래치

 

taeseungryu.github.io

 

아래 깃허브 주소는 실제 동작에 사용된 코드입니다.

간격을 구하는 공식이 브라우저에 따라서 다소 약간의 차이가 날 수 있습니다. ^^;

https://github.com/TaeSeungRyu/sample/tree/main/Html 캔버스 복권

 

GitHub - TaeSeungRyu/sample

Contribute to TaeSeungRyu/sample development by creating an account on GitHub.

github.com

 

 

위 모든 내용이 웹(web)에서 동작하는 캔버스(canvas)로 이루어진 내용 입니다.

 * 플래쉬, 액션스크립트, 유니티 같은 응용 프로그램이 아닙니다~

이상으로 HTML Canvas 복권 긁기 효과(scratch, lottery) 에 대해서 살펴보았습니다.

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

 

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

댓글