亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如果我有多個形狀,如何將鼠標懸停在畫布中的形狀上并更改顏色?

如果我有多個形狀,如何將鼠標懸停在畫布中的形狀上并更改顏色?

ITMISS 2023-07-06 10:15:19
我希望能夠將鼠標懸停在不同的矩形上,并使矩形在懸停時改變顏色,我現在適用于最后一個矩形,但其他矩形被清除。這些矩形是使用類/構造函數、數組和循環創建的。代碼如下:/*Variables*/let canvas = document.querySelector('#canvas'),    ctx = canvas.getContext('2d'),    square;/*Board Class*/class Board {    constructor(startX, startY, height, width, angle) {      this.startX = startX;      this.startY = startY;      this.height = height;      this.width = width;      this.angle = angle;    }      drawBoard() {        let canvasWidth = window.innerWidth * .95,            drawWidth = canvasWidth * this.width,            drawHeight = canvasWidth * this.height,            drawStartX = canvasWidth * this.startX,            drawStartY = canvasWidth * this.startY;                square = new Path2D();        ctx.rotate(this.angle * Math.PI / 180);        square.rect(drawStartX, drawStartY, drawHeight, drawWidth);        ctx.fillStyle = 'red';        ctx.fill(square);      }  }/*Event Listener for changing rectangle color and redrawing*/  canvas.addEventListener('mousemove', function(event) {    if (ctx.isPointInPath(square, event.offsetX, event.offsetY)) {      ctx.fillStyle = 'white';     }    else {      ctx.fillStyle = 'red';      }      ctx.clearRect(0, 0, canvas.width, canvas.height);    ctx.fill(square);  });  /*Instantiate Array*/  let b = [];  /*Loop to create boards and push to array*/  for(let i = 1; i < 11; i++){    b.push(new Board(.05 * i, .25, .04, .03, 0));    }/*Function to loop through array and draw boards when page loads*/function loadFunctions(){    background.draw();    b.forEach(function(board){        board.drawBoard();    })}這是我使用 Canvas API 的第一個項目,它給我帶來了很多麻煩,通常我可以通過類/id 來識別形狀(如果它是用常規 HTML 元素制作的),但我不知道從這里該去哪里。 。我嘗試循環遍歷包含主板信息的數組,但無法讓任何東西起作用。任何幫助表示贊賞!
查看完整描述

1 回答

?
Qyouu

TA貢獻1786條經驗 獲得超11個贊

讓我們逐步檢查您的代碼,以便更好地了解正在發生的情況。


一旦您將鼠標移到畫布上,mousemove偵聽器就會被觸發并執行其關聯的回調函數。


在這個回調函數中,我們會發現它是第一行:


if (ctx.isPointInPath(square, event.offsetX, event.offsetY)) 

所以這個 if 語句檢查當前鼠標位置是否在square內部。好吧,最大的問題是:正方形實際上是什么?


如果我們進一步查看您的代碼,我們會發現它是一個全局變量,它在 Board類函數中獲取一些值drawBoard(),如下所示:


square = new Path2D();

square.rect(drawStartX, drawStartY, drawHeight, drawWidth);

顯然它是一個Path2D,保存著其中一個條形的矩形 - 但實際上是哪一個呢?


我們來看看這個函數:


for (let i = 0; i < 10; i++) {

  b.push(new Board(0.05 * i, 0.25, 0.04, 0.03, 0));

}


function loadFunctions() {

  b.forEach(function(board) {

    board.drawBoard();

  })

}

在第一個循環中,您將使用Board的十個實例填充數組b,并且在 forEach 循環中,您將調用每個 Board 的drawBoard()函數。


這是什么意思呢?是的,square將始終保留對 bar 的引用,該 bar 函數上次被調用 - 它始終是數組中的最后一個 Board。


總結一下:您在 mousemove 回調中檢查的唯一欄始終是數組中的最后一個欄。所以:


if (ctx.isPointInPath(square, event.offsetX, event.offsetY)) {

  ctx.fillStyle = 'white'; 

}

else {

  ctx.fillStyle = 'red';  

}  

ctx.clearRect(0, 0, canvas.width, canvas.height);

ctx.fill(square);

翻譯成簡單的英語意味著:如果該點在正方形的邊界內,則將 fillStyle 設置為紅色,清除整個屏幕,然后用紅色填充一個欄。


您需要做的是檢查數組中每個Board 實例的鼠標位置。但這并不難 - 只需將 Path2D 設為 Board 的類變量,并在回調函數內循環遍歷整個數組,并將鼠標位置與每個 Board 的 .square屬性進行比較。


這是一個示例(只需單擊“運行代碼片段”):


let canvas = document.querySelector('#canvas'),

  ctx = canvas.getContext('2d');

let b = [];


class Board {

  constructor(startX, startY, height, width, angle) {

    this.startX = startX;

    this.startY = startY;

    this.height = height;

    this.width = width;

    this.angle = angle;

    this.square = new Path2D();

  }


  drawBoard() {

    let canvasWidth = window.innerWidth * 0.95,

      drawWidth = canvasWidth * this.width,

      drawHeight = canvasWidth * this.height,

      drawStartX = canvasWidth * this.startX,

      drawStartY = canvasWidth * this.startY;


    ctx.rotate(this.angle * Math.PI / 180);

    this.square.rect(drawStartX, drawStartY, drawHeight, drawWidth);

    ctx.fillStyle = 'red';

    ctx.fill(this.square);

  }

}


canvas.addEventListener('mousemove', function(event) {

  ctx.clearRect(0, 0, canvas.width, canvas.height);

  let currentSquare;

  for (let i = 0; i < b.length; i++) {

    currentSquare = b[i].square;

    if (ctx.isPointInPath(currentSquare, event.offsetX, event.offsetY)) {

      ctx.fillStyle = 'white';

    } else {

      ctx.fillStyle = 'red';

    }

    ctx.fill(currentSquare);

  }

});


for (let i = 0; i < 10; i++) {

  b.push(new Board(0.05 * i, 0.25, 0.04, 0.03, 0));

}


function loadFunctions() {

  b.forEach(function(board) {

    board.drawBoard();

  })

}

loadFunctions();

<canvas id="canvas" width=500 height=300></canvas>


查看完整回答
反對 回復 2023-07-06
  • 1 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號