如何使 canvas 个元素可点击
How to make canvas elements clickable
我正在尝试制作 MineSweeper 游戏,到目前为止我已经制作了我需要的所有单元格,但我还需要单元格可以点击以移除它们的封面,但似乎没有办法做它。
我已经将每个对象推入一个数组并尝试循环遍历它然后添加 EventListener 但它说如果我尝试在单元格数组上添加一个 onclick 函数,cell.addEventListener 不是一个相同的函数。我是做错了什么还是做不到?
const canvas = document.getElementById("myCanvas")
const ctx = canvas.getContext("2d")
canvas.style.border = "1px solid black"
class Cell {
constructor(x, y, w) {
this.x = x
this.y = y
this.w = w
let bomb = false
let revealed = false
}
show() {
ctx.beginPath()
ctx.rect(this.x, this.y, this.w, this.w)
ctx.stroke()
}
}
let w = canvas.width
let h = canvas.height
let ColumnRow = w / 15
let cell = []
function setup() {
for (let x = 0; x < w - 1; x += ColumnRow) {
for (let y = 0; y < h - 1; y += ColumnRow) {
cell.push(new Cell(x, y, ColumnRow))
}
}
}
function draw() {
for (let c of cell) {
c.show()
}
}
function update() {
setup()
draw()
requestAnimationFrame(update)
}
update()
<canvas id="myCanvas" width="500" height="500"></canvas>
您应该使用 Path2D
构造函数来检查点击事件是否在特定的 canvas 路径内:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
canvas.style.border = '1px solid black';
class Cell {
constructor(x, y, w) {
this.x = x;
this.y = y;
this.w = w;
let bomb = false;
let revealed = false;
}
create() {
// Create cell
const cell = new Path2D();
cell.rect(this.x, this.y, this.w, this.w);
ctx.stroke(cell);
this.cell = cell;
}
}
const w = canvas.width;
const h = canvas.height;
const ColumnRow = w / 15;
const cells = [];
function setup() {
for (let x = 0; x < w - 1; x += ColumnRow) {
for (let y = 0; y < h - 1; y += ColumnRow) {
cells.push(new Cell(x, y, ColumnRow));
}
}
}
function draw() {
for (const cell of cells) {
cell.create();
}
}
function addListeners() {
const handler = function (event) {
for (const cell of cells) {
if (ctx.isPointInPath(cell.cell, event.offsetX, event.offsetY)) {
ctx.strokeStyle = 'green';
ctx.fillStyle = 'green';
ctx.fill(cell.cell);
} else {
ctx.clearRect(cell.x, cell.y, cell.w, cell.w);
ctx.strokeStyle = 'red';
}
}
};
canvas.addEventListener('click', handler);
}
function update() {
setup();
draw();
requestAnimationFrame(update);
}
update();
addListeners();
<canvas id="myCanvas"></canvas>
某canvas地区:
我正在尝试制作 MineSweeper 游戏,到目前为止我已经制作了我需要的所有单元格,但我还需要单元格可以点击以移除它们的封面,但似乎没有办法做它。
我已经将每个对象推入一个数组并尝试循环遍历它然后添加 EventListener 但它说如果我尝试在单元格数组上添加一个 onclick 函数,cell.addEventListener 不是一个相同的函数。我是做错了什么还是做不到?
const canvas = document.getElementById("myCanvas")
const ctx = canvas.getContext("2d")
canvas.style.border = "1px solid black"
class Cell {
constructor(x, y, w) {
this.x = x
this.y = y
this.w = w
let bomb = false
let revealed = false
}
show() {
ctx.beginPath()
ctx.rect(this.x, this.y, this.w, this.w)
ctx.stroke()
}
}
let w = canvas.width
let h = canvas.height
let ColumnRow = w / 15
let cell = []
function setup() {
for (let x = 0; x < w - 1; x += ColumnRow) {
for (let y = 0; y < h - 1; y += ColumnRow) {
cell.push(new Cell(x, y, ColumnRow))
}
}
}
function draw() {
for (let c of cell) {
c.show()
}
}
function update() {
setup()
draw()
requestAnimationFrame(update)
}
update()
<canvas id="myCanvas" width="500" height="500"></canvas>
您应该使用 Path2D
构造函数来检查点击事件是否在特定的 canvas 路径内:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
canvas.style.border = '1px solid black';
class Cell {
constructor(x, y, w) {
this.x = x;
this.y = y;
this.w = w;
let bomb = false;
let revealed = false;
}
create() {
// Create cell
const cell = new Path2D();
cell.rect(this.x, this.y, this.w, this.w);
ctx.stroke(cell);
this.cell = cell;
}
}
const w = canvas.width;
const h = canvas.height;
const ColumnRow = w / 15;
const cells = [];
function setup() {
for (let x = 0; x < w - 1; x += ColumnRow) {
for (let y = 0; y < h - 1; y += ColumnRow) {
cells.push(new Cell(x, y, ColumnRow));
}
}
}
function draw() {
for (const cell of cells) {
cell.create();
}
}
function addListeners() {
const handler = function (event) {
for (const cell of cells) {
if (ctx.isPointInPath(cell.cell, event.offsetX, event.offsetY)) {
ctx.strokeStyle = 'green';
ctx.fillStyle = 'green';
ctx.fill(cell.cell);
} else {
ctx.clearRect(cell.x, cell.y, cell.w, cell.w);
ctx.strokeStyle = 'red';
}
}
};
canvas.addEventListener('click', handler);
}
function update() {
setup();
draw();
requestAnimationFrame(update);
}
update();
addListeners();
<canvas id="myCanvas"></canvas>
某canvas地区: