检测使用画布绘制的六边形内的咔嗒声?

时间:2017-12-05 15:13:00

标签: javascript html5 canvas html5-canvas path-2d

我正在处理某个布局,我需要绘制一个需要点击的六边形。我使用Path2D构造和isPointInPath函数。我正在构建一个动画,其中创建了许多六边形,然后每个都移动到某个位置。移动完成后,我将onclick事件处理程序附加到某些六边形。但是有一种奇怪的行为。

一些初始化变量

const COLOR_DARK = "#73b6c6";
const COLOR_LIGHT = "#c3dadd";
const COLOR_PRIMARY = "#39a4c9";

const TYPE_PRIMARY = 'primary';

let hexagons = [];

下面是绘制六边形的函数。

function drawHex(ctx, x, y, hexProps, stroke, color) {

    let myPath = new Path2D();

    myPath.moveTo(x + hexProps.width*0.5, y);
    myPath.lineTo(x, y + hexProps.height*hexProps.facShort);
    myPath.lineTo(x, y + hexProps.height*hexProps.facLong);
    myPath.lineTo(x + hexProps.width*0.5, y + hexProps.height);
    myPath.lineTo(x + hexProps.width, y + hexProps.height*hexProps.facLong);
    myPath.lineTo(x + hexProps.width, y + hexProps.height*hexProps.facShort);
    myPath.lineTo(x + hexProps.width*0.5, y);
    myPath.closePath();

    if (stroke){
        ctx.strokeStyle = color;
        ctx.stroke(myPath);
    } else {
        ctx.fillStyle = color;
        ctx.fill(myPath);
    }

    return myPath;
}

此函数填充六边形数组

function populateLeftHex(canvasWidth, canvasHeight, hexProps) {

const startX = canvasWidth / 2;
const startY = canvasHeight / 2;
const baseLeft = canvasWidth * 0.05;

for(let i = 0; i < 5; i++){
    let hexNumber = (i % 4 == 0)? 2: 1;

    for(let j = 0; j < hexNumber; j++){
        hexagons.push({
            startX: startX,
            startY: startY,
            endX: baseLeft + (2 * j) + ((i % 2 == 0)? (hexProps.width * j) : (hexProps.width/2)),
            endY: ((i + 1) * hexProps.height) - ((i) * hexProps.height * hexProps.facShort)  + (i* 2),
            stroke: true,
            color: ( i % 2 == 0 && j % 2 == 0)? COLOR_DARK : COLOR_LIGHT,
            type: TYPE_PRIMARY
        });
    }
}

}

这就是我调用isPointInPath函数的地方。

   window.onload = function (){
const c = document.getElementById('canvas');

const canvasWidth = c.width = window.innerWidth,
    canvasHeight = c.height = window.innerHeight,
    ctx = c.getContext('2d');

window.requestAnimFrame = (function (callback) {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
            window.setTimeout(callback, 1000 / 60);
        };
})();

console.log(canvasWidth);

let hexProps = {
  width: canvasWidth * 0.075,
    get height () {
      return this.width/Math.sqrt(3) + (1.5)*(this.width/Math.sqrt(2)/2);
    } ,
    facShort: 0.225,
    get facLong () {
      return 1 - this.facShort;
    }
};


populateLeftHex(canvasWidth, canvasHeight, hexProps);

let pct = 0;
const fps = 200;

animate();


function animate () {

    setTimeout(function () {
    // increment pct towards 100%
    pct += .03;

    // if we're not done, request another animation frame
    if (pct < 1.00) {
        requestAnimFrame(animate);
    } else { //if pct is no longer less than 1.00, then the movement animation is over.
        hexagons.forEach(function (hex) {
            if(hex.type === TYPE_PRIMARY) {

                console.info(hex.path);


                c.onclick = function(e) {

                    let x = e.clientX - c.offsetLeft,
                        y = e.clientY - c.offsetTop;
                    console.info(ctx.isPointInPath(hex.path, (e.clientX - c.offsetLeft), (e.clientY - c.offsetTop) ));
                };
            }
        })
    }

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

        // draw all hexagons
        for ( let i = 0; i < hexagons.length; i++) {

            // get reference to next shape
            let hex = hexagons[i];

            // note: dx/dy are fixed values
            // they could be put in the shape object for efficiency
            let dx = hex.endX - hex.startX;
            let dy = hex.endY - hex.startY;
            let nextX = hex.startX + dx * pct;
            let nextY = hex.startY + dy * pct;
            hex = hexagons[i];
            ctx.fillStyle = hex.color;
            hex.path = drawHex(ctx, nextX, nextY, hexProps, hex.stroke, hex.color);


        }

    }, 1000 / fps);
}
你可以帮我弄清楚我做错了什么吗?也许我误解了Path2D是如何工作的?提前谢谢。

1 个答案:

答案 0 :(得分:0)

由于你的例子不完整,我不得不做一些建立测试页面的工作,但这对我有用 - 虽然我的六边形是凹的...

&#13;
&#13;
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");

var hexProps = {width:100, height:100, facShort:-2, facLong:10};

var hexagons = [];

 function drawHex(ctx, x, y, hexProps, stroke, color) {

     let myPath = new Path2D();

     myPath.moveTo(x + hexProps.width*0.5, y);
     myPath.lineTo(x, y + hexProps.height*hexProps.facShort);
     myPath.lineTo(x, y + hexProps.height*hexProps.facLong);
     myPath.lineTo(x + hexProps.width*0.5, y + hexProps.height);
     myPath.lineTo(x + hexProps.width, y + hexProps.height*hexProps.facLong);
     myPath.lineTo(x + hexProps.width, y + hexProps.height*hexProps.facShort);
     myPath.lineTo(x + hexProps.width*0.5, y);
     myPath.closePath();

     if (stroke){
         ctx.strokeStyle = color;
         ctx.stroke(myPath);
     } else {
         ctx.fillStyle = color;
         ctx.fill(myPath);
     }

     return myPath;
 }

hexagons.push({type:0, path:drawHex(ctx,100,100,hexProps,false,"#0f0")});

   hexagons.forEach(function (hex) {
            if(hex.type === 0) {

                console.info(hex.path);


                myCanvas.onclick = function(e) {

                    let x = e.clientX - myCanvas.offsetLeft,
                        y = e.clientY - myCanvas.offsetTop;
                    console.info(x,y);
                    console.info(ctx.isPointInPath(hex.path, (e.clientX - 
 myCanvas.offsetLeft), (e.clientY - myCanvas.offsetTop) ));

                };
            }
        })
&#13;
<canvas width=500 height=500 id=myCanvas style='border:1px solid red'></canvas>
&#13;
&#13;
&#13;

测试点击在预期的地方给出true和false:

test.htm:48 165 168
test.htm:49 true
test.htm:48 151 336
test.htm:49 false
test.htm:48 124 314
test.htm:49 true
test.htm:48 87 311
test.htm:49 false