带有 js canvas 的座位选择器

问题描述 投票:0回答:1

所以我正在使用 js 和 html 和画布为公共汽车/飞机制作一个座位选择器/选择器,我已经到了可以根据输入的行数和列数创建一组座位的地步,但现在我陷入了困境其中的选择部分。我不知道如何让用户点击座位然后如何存储。如果有更好的方法来制作参数控制的座位选择器,我很想听听它,我对用来完成任务的工具并不挑剔。

最终目标是让用户选择座位,但能够看到婴儿坐在哪里并 告诉他们根据与婴儿的距离从低到高的预期噪音水平。我不知道这是否有帮助,但以防万一。 :)

HTML

<canvas id="seats"></canvas>

JS

const canvas = document.getElementById("seats");
const ctx = canvas.getContext("2d");

const seatSize = (window.innerWidth/10);
const seatGap = 1.25;

var seatRows = 14;
var seatColumns = 4;
var busLength = (seatRows*seatSize*seatGap)+(seatSize*2)-seatSize*(seatGap-1);
var busWidth = (seatColumns*seatSize)+(seatSize);


canvas.width = busWidth+20;
canvas.height = busLength+20;

ctx.font = .15 * busWidth + "px Arial";
ctx.fillStyle = "grey"
ctx.textAlign = "center";
ctx.fillText("Front", busWidth/2+5, seatSize*1.5);

ctx.strokeStyle = "gray";
ctx.lineWidth = "2";
ctx.beginPath();
ctx.roundRect(10, 10, busWidth, busLength, [5]);
ctx.stroke();

var rowInstance = 0;
var columnInstance = 0;
var seatNumber = 1;

while (rowInstance < seatRows) {
    while (columnInstance < seatColumns) {
        if (columnInstance < seatColumns/2) {
            ctx.strokeStyle = "gray";
            ctx.lineWidth = "2";
            ctx.beginPath();
            ctx.roundRect(columnInstance*seatSize+10 ,(rowInstance*seatSize*seatGap)+(seatSize*2)+10, seatSize, seatSize, [5]);
            ctx.stroke();

            ctx.font = seatSize/2 + "px Arial";
            ctx.fillStyle = "grey"
            ctx.textAlign = "center";
            ctx.fillText(seatNumber, columnInstance*seatSize+seatSize-(seatSize/2), (rowInstance*seatSize*seatGap)+(seatSize*2.65)+10);
            
            columnInstance++;
            seatNumber++;
        }
        else {
            // Seats
            ctx.strokeStyle = "gray";
            ctx.lineWidth = "2";
            ctx.beginPath();
            ctx.roundRect(columnInstance*seatSize+seatSize+10 ,(rowInstance*seatSize*seatGap)+(seatSize*2)+10, seatSize, seatSize, [5]);
            ctx.stroke();
            // Seat Numbers
            ctx.font = seatSize/2 + "px Arial";
            ctx.fillStyle = "grey"
            ctx.textAlign = "center";
            ctx.fillText(seatNumber, columnInstance*seatSize+seatSize*2-(seatSize/2), (rowInstance*seatSize*seatGap)+(seatSize*2.65)+10);
            
            seatNumber++;
            columnInstance++;
        }
    }
    rowInstance++;
    columnInstance=0;
}

我已经研究了如何使用画布选择事物的方法,但我能找到的所有方法都要求您知道每个形状的坐标,并且由于我的对象具有响应性并更改它不起作用。

javascript html canvas
1个回答
0
投票

我看到这已经有一段时间了,我希望我对这件事仍然有用。

让我们将您的请求分成几个部分:

  1. 准备点击检测。
  • 创建一个包含每个座位位置的数组会很有趣,例如:
var seatArray = [["seat1", 100, 200, "not clicked"], ["seat2", 200, 200, "clicked"], etc..];
var clickX = 0;
var clickY = 0;
canvas.onmouseup = function (e){

    // Here we get the global clicking coordinates and subtract the starting position of the canvas
    clickX = e.clientX - canvas.offsetLeft;
    clickY = e.clientY - canvas.offsetTop;

    // Check if the click corresponds to the position of a seat
    checkClick();
}
  • 现在需要检查最后一次点击是否在上一节中调用的座位边界内。
function checkClick(){
    for(let i = 0; i < seatArray.length; i++){
        // Extract the data from the seatArray
        let currentSeat = seatArray[0];
        let posX = currentSeat[1];
        let posY = currentSeat[2];
        let click = currentSeat[3];

        // Create and initialize a variable which will determine the click
        let isClicked = 0;
        let colour = "grey";
        
        // Determine the end of the boundaries for X and Y coordinates
        let Xbound = posX + width;
        let Ybound = posY + height;
        
        // Check if the click was within the boundaries for horizontal and vertial axis
        let withinXboundaries = (clickX >= posX) && (clickX <= Xbound);
        let withinYboundaries = (clickY >= posY) && (clickY <= Ybound);
        
        // If within boundaries on both, then it's clicked
        isClicked = withinXboundaries && withinYboundaries;
    
        // Now, update the array
        if(isClicked){
            currentSeat[3] = "clicked";
        }
    }
}
  • 要正确为您的座椅着色,在您写下“ctx.linesStyle = 'gray'”的地方,您需要执行检查,例如:
if(seatArray[seatNumber][3] == "clicked"){
    ctx.strokeStyle = "red";
} else {
    ctx.strokeStyle = "grey";
} 
  1. 更新屏幕:
  • 首先,您需要将 while 循环转换为函数:
function drawSeats(){
    // Insert your while loop here ...
}
  • 在调用之前,我们需要确保画布是空白的,因此创建一个clearCanvas()函数:
function clearCanvas(){
    ctx.clearRect(0,0, canvas.width, canvas.height);
};
  • 然后我们需要时不时的调用它:
setInterval(() => {
    clearCanvas();
    drawSeats();
}, scanTime);
© www.soinside.com 2019 - 2024. All rights reserved.