우리 모두 알고 있듯이 캔버스는 비트맵에 그림, 선 등 다양한 것을 그릴 수 있습니다. 그렇다면 캔버스의 특정 그림에 클릭 이벤트를 추가하려면 어떻게 해야 할까요? 그리고 js는 캔버스 이벤트만 모니터링할 수 있습니다. 분명히 이 그림은 존재하지 않으며 DOM의 그림은 캔버스에 그려집니다. 다음으로 캔버스 내부의 각 이미지에 대한 이벤트 바인딩을 간단히 구현하겠습니다.
먼저 구현 원리에 대해 말씀드리겠습니다. 실제로 관련 이벤트를 캔버스에 바인딩하는 것입니다. 그림이 위치한 캔버스의 좌표를 기록하여 어떤 그림에 해당 이벤트가 작용하는지 판단합니다. 이런 점에서 이벤트 에이전트와 약간 비슷한 느낌이 듭니다. 그러나 구현하기에는 여전히 약간 복잡합니다.
ps: ts에 다음 코드를 작성했습니다. es6으로 읽어보시면 조금 다를 수 있습니다.
Typescript 문서(typescript는 정말 사용하기 쉽습니다. 이에 대해 자세히 알아보는 것이 좋습니다).
1. 그림과 캔버스 사이의 연결을 설정합니다. (여기에서는 그림 대신 컬러 블록을 사용합니다.)여기서는 단순히 렌더링하는 것이 아니라 색상 블록과 캔버스 사이에 특정 연결을 설정해야 합니다. 또한 색상 블록의 좌표, 너비 및 높이를 기록합니다. 차근차근 구현해보자
먼저 기본 HTML 페이지를 작성하여 캔버스를 만듭니다.
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width,initial-scale=1.0> <meta http-equiv=X-UA -호환되는 콘텐츠=ie=edge> <title>캔버스 이벤트</title> <style> html, body { height: 100% background: #eee } canvas { background: #fff; 표시: 블록; 여백: 0 } </style></head><body> <canvas width=500 height=500 id=canvas></body>
다음으로 Canvas 클래스를 정의해야 합니다. 이 클래스에는 어떤 기능이 있어야 합니까?
색상 블록에는 자체 매개변수도 있으므로 확장을 용이하게 하기 위해 색상 블록에 대한 클래스도 정의합니다. 이 유형에 필요한 기능은 다음과 같습니다.
너비, 높이, 색상, 좌표(x, y) 및 캔버스 인스턴스를 먼저 결정하겠습니다.
알았어 글쓰기 시작해
// 캔버스 클래스 class Canvas { blockList: Block[] ctx: any canvas: any createBlock (옵션) { option.Canvas = this this.blockList.push(new Block(option)) this.painting() } 렌더링(블록) { // 렌더링 색상 블록 함수 this.ctx.fillStyle = block.color this.ctx.fillRect(block.x, block.y, block.w, block.h) } painting () { // 컨테이너의 모든 색상 블록을 캔버스에 렌더링 // 캔버스 지우기(렌더링하기 전에 이전 블록을 지워야 함) this.ctx.fillStyle = '#fff' this.ctx.fillRect(0, 0, this.canvas. width, this .canvas.height) this.blockList.forEach(ele => { this.rendering(ele) }) } constructor (ele) { // 초기화 함수(입력은 캔버스) // 캔버스 설정 this.canvas = ele this.ctx = this.canvas.getContext('2d') // 컬러 블록 컨테이너 this.blockList = [] }}class Block { w: 숫자 h: 숫자 x: 숫자 y: 숫자 color : string Canvas: Canvas 계층 구조: 숫자 생성자 ({ w, h, x, y, color, Canvas }) { // 컬러 블록 관련 속성 초기화 및 설정 this.w = w this.h = h this.x = x this.y = y this.color = 색상 this.Canvas = 캔버스 }}
아래에서 웨이브를 실행해 보겠습니다.
// 캔버스 인스턴스를 생성하고 너비와 높이가 100px, 위치가 (100,100), (300,100) 빨간색 및 파란색 블록인 파란색 블록을 추가합니다. var canvas = new Canvas(document.getElementById('canvas')) canvas. createBlock({ // 빨간색 x: 100, y: 100, w: 100, h: 100, 색상: '#f00' }) canvas.createBlock({ // 파란색 x: 100, y: 100, w: 300, h: 100, 색상: '#00f' })
실행 결과는 다음과 같습니다.
2. 색상 블록에 클릭 이벤트를 추가합니다.여기서는 클릭 이벤트를 색상 블록에 직접 추가할 수 없으므로 좌표를 사용하여 현재 클릭된 색상 블록을 확인해야 합니다.
class Block { // ...코드 일부 생략 checkBoundary (x, y) { // 경계 방법 결정 return x > this.x && x < (this.x + this.w) && y > this.y && y < (this.y + this.h) } mousedownEvent () { // 이벤트 클릭 console.log(`${this.color} 색상의 색상 블록을 클릭했습니다`) }}class Canvas { // .. .생략된 부품 코드 생성자 (ele) { this.canvas = ele this.ctx = this.canvas.getContext('2d') this.blockList = [] // 이벤트 바인딩 (여기서 한 가지 주의할 점이 있습니다. 여기서는 바인딩 메소드를 사용했는데, is mousedownEvent 메소드의 this 포인터를 Canvas로 전환하기 위해) this.canvas.addEventListener('click', this.mousedownEvent.bind(this)) // 클릭 이벤트} mousedownEvent () { // 클릭 이벤트 const x = e.offsetX const y = e.offsetY // 여기서는 클릭의 좌표를 모든 컬러 블록에 전달하고, 경계 판단 방법을 사용하여 클릭이 내부에 있는지 확인합니다. 그렇다면 컬러 블록의 이벤트 메소드를 실행하십시오. this.blockList.forEach(ele => { if (ele.checkBoundary(x, y)) ele.mousedownEvent(e) }) }}
지금까지 우리는 해당 클릭 이벤트를 다양한 캔버스의 다양한 색상 블록에 바인딩하는 기능을 구현했습니다. 그러나 이 클릭 이벤트는 완벽하지 않습니다. 지금까지 계층 개념을 도입하지 않았기 때문입니다. 즉, 두 개의 겹치는 색상 블록을 클릭하면 둘 다 트리거된다는 의미입니다. 따라서 색상 블록에 계층적 속성도 추가해야 합니다. 컬러 블록을 클릭하여 컬러 블록을 변경하면 컬러 블록의 레벨이 가장 높은 레벨로 올라갑니다.
class Block { // ...코드 생성자 일부 생략 ({ w, h, x, y, color, Canvas, Hierarchy }) { // 컬러 블록 관련 속성 초기화 및 설정 this.w = w this .h = h this. x = x this.y = y this.color = color this.Canvas = Canvas this.hierarchy = 0 }}class Canvas { // ...코드 생성자의 일부 생략(ele) { this .canvas = 여기에서 this.ctx = this.canvas.getContext('2d') this.blockList = [] // 이벤트 바인딩(여기서 주목해야 할 사항이 하나 있습니다. 여기에서는 바인딩 메서드를 사용하여 mousedownEvent 메서드의 this 포인터를 Canvas로 전환했습니다.) this .canvas .addEventListener('click', this.mousedownEvent.bind(this)) // 클릭 이벤트 this.nowBlock = null // 현재 선택된 색상 블록} createBlock(옵션) { // 컬러 블록 생성 기능(여기서 Block은 컬러 블록의 클래스입니다.) option.Canvas = this // 최신 컬러 블록 생성 수준이 가장 높아야 합니다. option.hierarchy = this.blockList.length this.blockList.push(new Block ( 옵션)) this.rendering() } mousedownEvent (e) { // 클릭 이벤트 const x = e.offsetX const y = e.offsetY // 해당 지점에서 가장 높은 레벨의 컬러 블록을 가져옵니다. this.nowBlock = (this.blockList.filter(ele => ele.checkBoundary(x, y))).pop() // 캡처된 컬러 블록이 없으면 바로 종료합니다. (!this .nowBlock) return // 클릭한 색상 블록 수준을 가장 높은 수준으로 올립니다. this.nowBlock.hierarchy = this.blockList.length // 재정렬(작은 것에서 큰 것으로) this.blockList.sort((a, b) = > a.hierarchy - b.hierarchy) // 0부터 계층을 재할당 this.blockList.forEach((ele, idx) => ele.hierarchy = idx) // 역순으로 다시 정렬한 후 다시 렌더링합니다. this.painting() this.nowBlock.mousedownEvent(e) // 선택한 색상 블록에 대한 이벤트만 트리거}}// 여기서 빨간색 색상 블록과 겹치는 세 번째 색상 블록을 추가해야 합니다. canvas.createBlock({ x: 150 , y: 150, w: 100, h: 100, 색상: '#0f0'})
Canvas의 mousedownEvent 메소드에 있는 코드는 다소 복잡합니다. 그 이유는 주로 약간 복잡하기 때문입니다.
실행 후 효과는 다음과 같습니다.
3. 다양한 색상의 블록을 드래그 앤 드롭하세요.위에서 우리는 다양한 색상 블록을 얻고 해당 레벨을 수정하는 것을 구현했습니다. 다음으로 우리는 주로 마우스를 이동하는 동안과 마우스를 처음 클릭할 때 위치 좌표의 변화를 얻기 위해 색상 블록 드래그를 구현해야 합니다. 이 원칙은 일반적인 DOM 드래그 앤 드롭 구현의 원칙과 동일합니다.
컬러 블록을 클릭한 지점과 컬러 블록의 왼쪽과 상단으로부터의 거리(disX, disY)를 가져옵니다.
마우스가 움직일 때 캔버스의 왼쪽과 위쪽에서 마우스의 현재 거리에서 (disX, disY)를 뺍니다. 이것이 컬러 블록의 x 및 y 좌표입니다.
class Block { // ...코드 일부 생략 mousedownEvent (e: MouseEvent) { /* 여기서 disX 및 disY의 계산 방법: e.offsetX는 마우스 클릭과 캔버스 왼쪽 사이의 거리를 구합니다. .x는 색상 블록 거리입니다. 캔버스 왼쪽까지의 거리입니다. e.offsetX-this.x는 색상 블록 왼쪽까지의 거리입니다. 이해하기 쉬울 것입니다 */ const disX = e.offsetX - this.x // 클릭했을 때 색상 블록의 왼쪽으로부터의 거리 const disY = e.offsetY - this.y // 색상 블록의 상단으로부터의 거리 클릭 시 색상 블록 // 여기에 마우스 슬라이딩 이벤트를 바인딩합니다. mouseEvent.offsetX는 마우스와 캔버스 왼쪽 사이의 거리이기도 합니다. mouseEvent.offsetX - disX는 색상 블록의 x 좌표입니다. 같은 방식으로 y도 같은 방식으로 계산됩니다. 마지막으로 다시 렌더링하면 됩니다. document.onmousemove = (mouseEvent) => { this.x = mouseEvent.offsetX - disX this.y = mouseEvent.offsetY - disY this.Canvas.painting() } // 마우스를 놓을 때 모든 이벤트 지우기 document.onmouseup = ( ) => { document.onmousemove = document.onmousedown = null } // console.log(`${this.color} 색상의 색상 블록 22가 클릭되었습니다`) }}
효과는 다음과 같습니다.
전체 코드는 아래에 붙여넣어집니다(HTML 및 호출 메서드는 포함되지 않음). 이 예제는 캔버스의 콘텐츠에 이벤트를 바인딩하는 간단한 구현일 뿐입니다. 색상 블록을 그림으로 바꾸는 등 더 복잡한 코드를 구현할 수 있습니다. . 드래그 외에도 사진 확대/축소, 회전, 삭제 등이 가능합니다.
class Canvas { blockList: Block[] ctx: any canvas: any nowBlock: Block createBlock (옵션) { option.hierarchy = this.blockList.length option.Canvas = this this.blockList.push(new Block(option)) this. painting() } 렌더링(블록) { this.ctx.fillStyle = block.color this.ctx.fillRect(block.x, block.y, block.w, block.h) } painting () { // 캔버스 지우기 this.ctx.fillStyle = '#fff' this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height) this.blockList.forEach(ele => { this.rendering(ele) }) } mousedownEvent (e: MouseEvent) { // 클릭 이벤트 const x = e.offsetX const y = e.offsetY // 해당 지점에서 가장 높은 레벨의 컬러 블록을 가져옵니다. this.nowBlock = (this.blockList.filter(ele => ele.checkBoundary(x, y))).pop() // 캡처된 컬러 블록이 없으면 바로 종료합니다. (!this .nowBlock) return // 클릭한 색상 블록 수준을 가장 높은 수준으로 올립니다. this.nowBlock.hierarchy = this.blockList.length // 재정렬(작은 것에서 큰 것으로) this.blockList.sort((a, b) = > a.hierarchy - b.hierarchy) // 0부터 계층을 재할당 this.blockList.forEach((ele, idx) => ele.hierarchy = idx) // 역순으로 다시 정렬한 후 다시 렌더링합니다. this.painting() this.nowBlock.mousedownEvent(e) // this.blockList.forEach(ele => { // if (ele.checkBoundary(x, y)) ele.clickEvent(e) // }) } 생성자 (ele) { this.canvas = ele this.ctx = this.canvas.getContext('2d') this.blockList = [] // 이벤트 바인딩 this.canvas.addEventListener('mousedown', this.mousedownEvent.bind(this)) }}class Block { w: 숫자 h: 숫자 x: 숫자 y: 숫자 color: 문자열 캔버스: 캔버스 계층: 숫자 생성자( { w, h, x, y, 색상, 캔버스, 계층 구조 }) { this.w = w this.h = h this.x = x this.y = y this.color = 색상 this.Canvas = 캔버스 this.hierarchy = 계층 구조 } checkBoundary (x, y) { return x > this.x && x < (this.x + this.w) && y > this.y && y < (this.y + this.h) } mousedownEvent (e: MouseEvent) { const disX = e.offsetX - this.x const disY = e.offsetY - this.y document.onmousemove = (mouseEvent) => { this.x = mouseEvent.offsetX - disX this.y = mouseEvent.offsetY - disY this.Canvas.painting() } document.onmouseup = () => { document.onmousemove = document.onmousedown = null } // console.log(`${this.color} 색상의 색상 블록 22를 클릭했습니다`) }}
위의 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.