【发布时间】:2017-12-06 16:17:36
【问题描述】:
我正在处理某种布局,我需要在其中绘制一个需要可点击的六边形。我正在使用 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 的工作原理?提前致谢。
【问题讨论】:
-
您绘制的多条路径(六边形)正确吗?我不认为这是最好的方法。
isPointInPath()只会告诉你一个点是否在当前路径中。您必须在绘图时检查该点。您的代码现在的工作方式,它只会检查点击是否在最后绘制的六边形中。至少,我是这样理解文档的。 -
没错,drawHex函数绘制了一个六边形。但我多次调用它。现在发生了一种奇怪的行为......我正在构建一个复杂的动画......我会更新问题
标签: javascript html canvas html5-canvas path-2d