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

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

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


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

Html Canvas 자세히 보기(확대 보기, 크게 보기, 미리 보기, 돋보기 기능)

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

 

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

 

이번에 소개할 기능은 돋보기 기능(확대, 크게, 미리보기) 입니다.

돋보기 기능은 원본 이미지를 대상으로 마우스를 움직이면 사진이 크게 보이는 기능 입니다.

아래 사진처럼 이미지에 마우스를 움직이면서 해당 영역 사진이 크게보이는 기능 입니다.

 * 이러한 기능을 뭐라하는지 참 어렵네요..

요런 느낌 입니다...?

 

해당 기능을 만들기 위해서 먼저 동작과 이벤트를 고려하여 봅니다.

1. 사진이 있는 영역

2. 마우스가 움직이면서 돋보기가 가르키는 영역

3. 돋보기가 가르킨 영역의 내용이 보이는 영역

 

동작과 이벤트를 고려하면 캔버스가 총 3개가 필요합니다.

캔버스를 이처럼 기능과 역할에 의해 나누는 이유는, 불필요한 렌더링을 막기 위해서 입니다.

만약 1번과 2번의 기능을 합친다면, 이벤트에 의해서 사진이 지워졌다 그려졌다가 반복 되므므로 사진의 용량이 크고 화질이 높은 경우에는 이미지를 로드하느라 화면이 끊기는 현상이 발생 할 수 있습니다.

 

위 내용을 고려하여 3개의 캔버스를 그려줍니다.

3개를 그립니다.

 

id값이 canvas인 캔버스는 이미지를 그릴 영역 입니다. 1번에 대한 내용을 수행 합니다.

id값이 hover인 캔버스는 2번에 대한 내용을 수행 합니다.

id값이 preView인 캔버스는 3번에 대한 내용을 수행 합니다.

 

그러면 가장 쉬운 이미지를 가져오는 기능 입니다.

아래 코드처럼 이미지를 가져와서 캔버스에 넣어 줍니다.

const canvas = document.getElementById('canvas')    
const ctx = canvas.getContext('2d')

let img = new Image()
img.src = "test.png"
img.onload = () => {
    ctx.clearRect(0,0, canvas.width, canvas.height)
    ctx.drawImage(img, 0 , 0, canvas.width, canvas.height)
}

 

다음으로 2번기능을 구현합니다.

2번 캔버스에 이벤트를 붙여주고, 선택된 영역에 대해서 1번 캔버스의 데이터를 가져와 담아두는 기능을 만들어 줍니다.

캔버스에서 이미지의 데이터를 가져오는 기능은 getImageData 함수 입니다.

마우스가 움직이는 이벤트에 대해서 동작을 하려면 그렸다 지웠다 행동을 반복하면 그럴싸한 모습이 나타나게 됩니다.

canvas3.addEventListener('mousemove', function (event) {
    let x1 = event.clientX - canvas3.parentElement.offsetLeft - canvas3.offsetLeft - zoomSize / 2
    let y1 = event.clientY - canvas3.parentElement.offsetTop - canvas3.offsetTop - zoomSize / 2
    
    x1 = x1 <  0 ? 0 : x1
    y1 = y1 <  0 ? 0 : y1
    
    ctxHover.save()
    ctxHover.clearRect(0,0, canvas3.width, canvas3.height)
    ctxHover.beginPath()
    ctxHover.strokeStyle = 'red'
    ctxHover.fillStyle = 'rgba(255, 73, 73, 0.2)'
    ctxHover.lineWidth = 3
    ctxHover.arc(x1 + zoomSize / 2, y1 + zoomSize / 2, zoomSize/2, (Math.PI/180)*0, (Math.PI/180)* 360 , false)
    ctxHover.stroke()
    ctxHover.fill()
    ctxHover.closePath()
    ctxHover.restore()
    
})

 

위 내용까지 기능을 구현 한 모습 입니다.

캔버스에서의 에니메이션의 기본은 지웠다, 그렸다 입니다!

 

이제 남은 기능 입니다.

2번 캔버스에 의해서 복사 해야되는 좌표값과 크기 정보가 존재 하므로 해당 정보에 대해서 1번 캔버스의 이미지 데이터를 getImageData 함수를 사용하여 가져옵니다.

가저온 데이터를 이제 3번째 캔버스에 그렸다 지웠다를 통하여 넣어주면 기능이 완성되게 됩니다.

 

putImageData함수를 사용하면 캔버스의 이미지 크기를 조절하는 데 상당히 어렵습니다.

그러므로 차라리 내부에 캔버스를 생성하여 이미지를 넣어주고, 3번 캔버스에 drawImage 함수를 사용 한 뒤에 화면의 스케일을 조정하여 주는 것이 더 낫습니다.

 

최종적으로 구현하여 본 기능 입니다.

사진의 화질이 좋지 않아서 확대된 내용이 조금 아쉽네요..  : - )

돋보기 기능입니다... ^^

 

기능 구현 난이도가 어렵지 않아서 생각보다 금방 제작 할 수 있었습니다.

아래 제 깃헙을 방문하셔서 해당 기능을 사용 해 볼 수 있습니다.

https://taeseungryu.github.io/sample/sampleView/telescope/scope.html

 

Table

 

taeseungryu.github.io

 

 

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

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

이상으로 Html Canvas 자세히 보기(확대 보기, 크게 보기, 미리 보기, 돋보기 기능)에 대해서 정리하여 보았습니다.

 

해당 포스팅은 코드를 전부 공개하지 않고 개념만 정리한 내용입니다.

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

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

댓글