如何使用isPointInPath和调整大小的画布

时间:2017-11-05 12:10:46

标签: javascript canvas

我想用canvas元素实现悬停效果。如果画布没有调整大小,它工作正常。 代码示例:jsFiddle

window.onload = function (e)
    {
        var canvas  = document.getElementById('canvas');
        var context = canvas.getContext('2d');

        // Draw the rectangle
        context.beginPath();
        context.rect(50,50,100,100);
        context.fill();

        context.fillStyle = 'red';

        // Draw the circle
        context.beginPath();
        context.arc(450,175, 50, 0,2 * Math.PI, false);
        context.fill();

        context.fillStyle = 'green';

        // Draw the shape
        context.beginPath();
        context.moveTo(250,100);
        context.lineTo(350,175);
        context.lineTo(325,215);
        context.lineTo(185,195);
        context.fill();



        canvas.onmousemove = function (e)
        {
            var canvas = e.target;
            var context = canvas.getContext('2d');




            // This gets the mouse coordinates (relative to the canvas)
            var mouseX  = e.clientX;
            var mouseY  = e.clientY;


            // Replay the rectangle path (no need to fill() it) and test it
            context.beginPath();
            context.rect(50,50,100,100);

            if (context.isPointInPath(mouseX, mouseY)) {
                canvas.style.cursor = 'pointer';
                return;
            }
            ///////////////////////////////////////////////////////////////


            // Replay the circle path (no need to fill() it) and test it
            context.beginPath();
            context.arc(450,175, 50, 0,2 * Math.PI, false);

            if (context.isPointInPath(mouseX, mouseY)) {
                canvas.style.cursor = 'pointer';
                return;
            }
            ///////////////////////////////////////////////////////////////


            // Replay the irregular shape path (no need to fill() it) and test it
            context.beginPath();
            context.moveTo(250,100);
            context.lineTo(350,175);
            context.lineTo(325,215);
            context.lineTo(185,195);

            if (context.isPointInPath(mouseX, mouseY)) {
                canvas.style.cursor = 'pointer';
                return;
            }
            ///////////////////////////////////////////////////////////////


            // Return the cursor to the default style
            canvas.style.cursor = 'default';
        }
    }
html, body {
    margin: 0;
    padding: 0;
}
<canvas id="canvas" width="500" height="500"></canvas>

style="width: 100%; height: 100%;"添加到<canvas>后 它不再起作用了。我认为isPointInPath正在使用画布的“未缩放”版本?

编辑:几分钟前,我读到了在单独的canvas元素中测试isPointInPath,该元素未调整大小并且对用户也不可见。这是解决方案吗?它就像一个性能杀手,因为每次移动鼠标都需要创建一个画布,测试然后删除。

1 个答案:

答案 0 :(得分:0)

您的问题是您要将画布设置为100%。 但是你需要请求浏览器的宽度和高度。

&#13;
&#13;
var canvas  = document.getElementById('canvas'),
    context = canvas.getContext('2d'),
    Browser = {
  //get the width of the browser
  width : window.innerWidth ||
      root.clientWidth ||
      body.clientWidth,
  //get the height of the browser
  height : window.innerHeight ||
      root.clientHeight ||
      body.clientHeight
};

canvas.style.position = "fixed";
canvas.style.left = 0;
canvas.style.top = 0;
canvas.width = Browser.width;
canvas.height = Browser.height;

// Draw the rectangle
context.beginPath();
context.rect(50,50,100,100);
context.fill();

context.fillStyle = 'red';

// Draw the circle
context.beginPath();
context.arc(450,175, 50, 0,2 * Math.PI, false);
context.fill();

context.fillStyle = 'green';

// Draw the shape
context.beginPath();
context.moveTo(250,100);
context.lineTo(350,175);
context.lineTo(325,215);
context.lineTo(185,195);
context.fill();



canvas.onmousemove = function (e)
{
    var canvas = e.target;
    var context = canvas.getContext('2d');




    // This gets the mouse coordinates (relative to the canvas)
    var mouseX  = e.clientX;
    var mouseY  = e.clientY;


    // Replay the rectangle path (no need to fill() it) and test it
    context.beginPath();
    context.rect(50,50,100,100);

    if (context.isPointInPath(mouseX, mouseY)) {
        canvas.style.cursor = 'pointer';
        return;
    }
    ///////////////////////////////////////////////////////////////


    // Replay the circle path (no need to fill() it) and test it
    context.beginPath();
    context.arc(450,175, 50, 0,2 * Math.PI, false);

    if (context.isPointInPath(mouseX, mouseY)) {
        canvas.style.cursor = 'pointer';
        return;
    }
    ///////////////////////////////////////////////////////////////


    // Replay the irregular shape path (no need to fill() it) and test it
    context.beginPath();
    context.moveTo(250,100);
    context.lineTo(350,175);
    context.lineTo(325,215);
    context.lineTo(185,195);

    if (context.isPointInPath(mouseX, mouseY)) {
        canvas.style.cursor = 'pointer';
        return;
    }
    ///////////////////////////////////////////////////////////////


    // Return the cursor to the default style
    canvas.style.cursor = 'default';
}
   
&#13;
html, body {
    margin: 0;
    padding: 0;
}
&#13;
<canvas id="canvas" width="500" height="500"></canvas>
&#13;
&#13;
&#13;

也许你对我如何抓住problem有点了解。

这是我简单的浏览器对象:

Browser = {
    runTime: 0,
    //Updates Browser Info
    Update(time = 0) {
        this.runTime = time;
        //get the width of the browser
        this.width = window.innerWidth ||
            root.clientWidth ||
            body.clientWidth;
        //get the height of the browser
        this.height = window.innerHeight ||
            root.clientHeight ||
            body.clientHeight;

        //the center of the browser
        this.centerX = this.width / 2;
        this.centerY = this.height / 2;
    }
}

在每个框架中调用Browser.Update(),以便在更改时更新浏览器的大小。

var requestAnimation = window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;

function AnimationFrame(time) {
    Browser.Update(time);
    requestAnimationFrame(AnimationFrame);
}

// To start the loop.
AnimationFrame();