Canvas只有最后添加的对象有光标指针

时间:2017-07-20 19:16:33

标签: javascript canvas

我在画布上有一个小问题,当鼠标悬停在元素(对象)上时,它应该将光标更改为指针,当离开时 - 返回默认值,但我的代码不能正常工作,我的想法已经用完了

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

        var canvasOffset = $("#canvas").offset();
        var offsetX = canvasOffset.left;
        var offsetY = canvasOffset.top;

        var rectList = [];

        var cursors = ['default', 'pointer'],
            currentCursor = 0;


            function createRectangle( id, x, y, width, height, fillColor ) {
                var newRectangle = {
                    x,
                    y,
                    id,
                    width,
                    height,
                    fillColor,
                    mouseX: null,
                    mouseY: null,
                    isHighlighted: false,
                    isClicked: false,
                    cursor: 0, // 0 default,  1 pointer
                        draw(  ) {
                            drawRect( this.x, this.y, this.width, this.height, this.fillColor )
                        },
                        highlight(  ) {
                            crosshair( this.x, this.y, this.width, this.height, 20, 25, 6, 1, 2, 2, 2, 2, 2, '#E15258', '#E15258', '#C25975' );
                        },
                        isPointInside( ) {
                            return (this.mouseX >= this.x && this.mouseX <= this.x + this.width && this.mouseY >= this.y && this.mouseY <= this.y + this.height);
                        }
                }
                rectList.push( newRectangle );
            }

            function crosshair( x, y, width, height, radius1, radius2, endLineWidth, circle1Width, circle2Width, topLineWidth, rightLineWidth, bottomLineWidth, leftLineWidth, circle1Color, circle2Color, linesColor) {
                drawCircle(x + width/2, y + height/2, radius1, circle1Width, circle1Color);
                drawCircle(x + width/2, y + height/2, radius2, circle2Width, circle2Color);
                drawLine(x + radius1 + width/2, y + height/2, x + (radius2 + endLineWidth) + width/2, y + height/2, linesColor, leftLineWidth);
                drawLine(x - radius1 + width/2, y + height/2, x - (radius2 + endLineWidth) + width/2, y + height/2, linesColor, rightLineWidth);
                drawLine(x + width/2, y + radius1 + height/2, x + width/2, y + (radius2 + endLineWidth) + height/2, linesColor, bottomLineWidth);
                drawLine(x + width/2, y - radius1 + height/2, x + width/2, y - (radius2 + endLineWidth) + height/2, linesColor, topLineWidth);
            }

            function drawLine(startX, startY, endX, endY, color, width) {
                ctx.save();
                ctx.strokeStyle = color;
                ctx.lineWidth = width;
                ctx.beginPath();
                ctx.moveTo(startX,startY);
                ctx.lineTo(endX,endY);
                ctx.stroke();
                ctx.restore();
            }

            function drawCircle( x, y, radius, lineWidth, strokeColor ) {
                ctx.save();
                ctx.beginPath();
                ctx.arc( x, y, radius, 0, 2 * Math.PI, false);
                ctx.lineWidth = lineWidth;
                ctx.strokeStyle = strokeColor;
                ctx.stroke();
                ctx.restore();
            }

            function drawBorder( x, y, width, height, lineWidth, strokeColor ) {
                ctx.save();
                ctx.lineWidth = lineWidth;
                ctx.strokeStyle = strokeColor;
                ctx.strokeRect( x, y, width, height);
                ctx.restore();
            }

            function drawRect( x, y, width, height, fillColor ) {
                ctx.save();
                ctx.fillStyle = fillColor;
                ctx.fillRect( x, y, width, height );
                ctx.restore();
            }

            document.onmousemove = function( mouse ) {
                var mouseX = parseInt(mouse.clientX - offsetX);
                var mouseY = parseInt(mouse.clientY - offsetY);

                rectList.forEach( rect => {
                    rect.mouseX = mouseX;
                    rect.mouseY = mouseY;

                    if(rect.isPointInside()) {
                        currentCursor = 1;
                        if(rect.isClicked) {
                            rect.isHighlighted = false;
                        } else {
                            rect.isHighlighted = true;
                        }
                    } else {
                        rect.isHighlighted = false;
                        currentCursor = 0;
                    }

                });

                canvas.style.cursor = cursors[currentCursor];
            }

            document.onclick = function( mouse ) {
                var mouseX = parseInt(mouse.clientX - offsetX);
                var mouseY = parseInt(mouse.clientY - offsetY);

                rectList.forEach( rect => {
                    rect.mouseX = mouseX;
                    rect.mouseY = mouseY;

                    if(rect.isPointInside()) {
                        if(rect.isHighlighted) {
                            rect.isHighlighted = false;
                            rect.isClicked = true;
                        } else {
                            rect.isClicked = false;
                        }
                    } else {
                        rect.isClicked = false;
                    }
                });
            }


            function update() {

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

                rectList.forEach( rect => {
                    if( rect.isHighlighted ) {
                        rect.draw();
                        rect.highlight();
                    } else {
                        rect.draw();
                    }

                    if( rect.isClicked ) {
                        rect.draw();
                        rect.highlight();
                    } else {
                        rect.draw();
                    }

                });


                requestAnimationFrame(update);
            }

            


            function startNewGame() {
                createRectangle( 'orange', 25, 25, 30/2, 30/2, 'orange' );
                createRectangle( 'green', 50, 50, 30/2, 30/2, 'green' );
                createRectangle( 'blue', 75, 75, 30/2, 30/2, 'blue' );
                createRectangle( 'yellow', 100, 100, 30/2, 30/2, 'yellow' );
                createRectangle( 'lightgreen', 125, 125, 30/2, 30/2, 'lightgreen' );

                requestAnimationFrame(update);
            }

            startNewGame();
  canvas {
            border: 1px solid black;
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<canvas id="canvas" width="400" height="200"></canvas>

我希望这是一个小问题,不会让你头疼。提前谢谢!

1 个答案:

答案 0 :(得分:2)

当鼠标悬停在任何其他矩形之上时,在currentCursor函数的ForEach的下一次迭代中,您将onmousemove直接设置为0的最后一个矩形。

我通过在循环之前将currentCursor设置为0来修复它。

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

var canvasOffset = $("#canvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

var rectList = [];

var cursors = ['default', 'pointer'];


function createRectangle( id, x, y, width, height, fillColor ) {
    var newRectangle = {
        x,
        y,
        id,
        width,
        height,
        fillColor,
        mouseX: null,
        mouseY: null,
        isHighlighted: false,
        isClicked: false,
        cursor: 0, // 0 default,  1 pointer
        draw(  ) {
            drawRect( this.x, this.y, this.width, this.height, this.fillColor )
        },
        highlight(  ) {
            crosshair( this.x, this.y, this.width, this.height, 20, 25, 6, 1, 2, 2, 2, 2, 2, '#E15258', '#E15258', '#C25975' );
        },
        isPointInside( ) {
            return (this.mouseX >= this.x && this.mouseX <= this.x + this.width && this.mouseY >= this.y && this.mouseY <= this.y + this.height);
        }
    }
    rectList.push( newRectangle );
}

function crosshair( x, y, width, height, radius1, radius2, endLineWidth, circle1Width, circle2Width, topLineWidth, rightLineWidth, bottomLineWidth, leftLineWidth, circle1Color, circle2Color, linesColor) {
    drawCircle(x + width/2, y + height/2, radius1, circle1Width, circle1Color);
    drawCircle(x + width/2, y + height/2, radius2, circle2Width, circle2Color);
    drawLine(x + radius1 + width/2, y + height/2, x + (radius2 + endLineWidth) + width/2, y + height/2, linesColor, leftLineWidth);
    drawLine(x - radius1 + width/2, y + height/2, x - (radius2 + endLineWidth) + width/2, y + height/2, linesColor, rightLineWidth);
    drawLine(x + width/2, y + radius1 + height/2, x + width/2, y + (radius2 + endLineWidth) + height/2, linesColor, bottomLineWidth);
    drawLine(x + width/2, y - radius1 + height/2, x + width/2, y - (radius2 + endLineWidth) + height/2, linesColor, topLineWidth);
}

function drawLine(startX, startY, endX, endY, color, width) {
    ctx.save();
    ctx.strokeStyle = color;
    ctx.lineWidth = width;
    ctx.beginPath();
    ctx.moveTo(startX,startY);
    ctx.lineTo(endX,endY);
    ctx.stroke();
    ctx.restore();
}

function drawCircle( x, y, radius, lineWidth, strokeColor ) {
    ctx.save();
    ctx.beginPath();
    ctx.arc( x, y, radius, 0, 2 * Math.PI, false);
    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = strokeColor;
    ctx.stroke();
    ctx.restore();
}

function drawBorder( x, y, width, height, lineWidth, strokeColor ) {
    ctx.save();
    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = strokeColor;
    ctx.strokeRect( x, y, width, height);
    ctx.restore();
}

function drawRect( x, y, width, height, fillColor ) {
    ctx.save();
    ctx.fillStyle = fillColor;
    ctx.fillRect( x, y, width, height );
    ctx.restore();
}

document.onmousemove = function( mouse ) {
    var mouseX = parseInt(mouse.clientX - offsetX);
    var mouseY = parseInt(mouse.clientY - offsetY);

    var currentCursor = 0;
    rectList.forEach(rect => {
        rect.mouseX = mouseX;
        rect.mouseY = mouseY;

        if(rect.isPointInside()) {
            currentCursor = 1;
            if(rect.isClicked) {
                rect.isHighlighted = false;
            } else {
                rect.isHighlighted = true;
            }
        } else {
            rect.isHighlighted = false;
        }

    });

    canvas.style.cursor = cursors[currentCursor];
}

document.onclick = function( mouse ) {
    var mouseX = parseInt(mouse.clientX - offsetX);
    var mouseY = parseInt(mouse.clientY - offsetY);

    rectList.forEach( rect => {
        rect.mouseX = mouseX;
        rect.mouseY = mouseY;

        if(rect.isPointInside()) {
            if(rect.isHighlighted) {
                rect.isHighlighted = false;
                rect.isClicked = true;
             } else {
                 rect.isClicked = false;
             }
         } else {
             rect.isClicked = false;
         }
    });
}


function update() {
    ctx.clearRect( 0, 0, canvas.width, canvas.height);

    rectList.forEach( rect => {
        if( rect.isHighlighted ) {
            rect.draw();
            rect.highlight();
        } else {
            rect.draw();
        }

        if( rect.isClicked ) {
            rect.draw();
            rect.highlight();
        } else {
            rect.draw();
        }
    });

    requestAnimationFrame(update);
}

            


function startNewGame() {
    createRectangle( 'orange', 25, 25, 30/2, 30/2, 'orange' );
    createRectangle( 'green', 50, 50, 30/2, 30/2, 'green' );
    createRectangle( 'blue', 75, 75, 30/2, 30/2, 'blue' );
    createRectangle( 'yellow', 100, 100, 30/2, 30/2, 'yellow' );
    createRectangle( 'lightgreen', 125, 125, 30/2, 30/2, 'lightgreen' );

    requestAnimationFrame(update);
}

startNewGame();
canvas {
    border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<canvas id="canvas" width="400" height="200"></canvas>