バニラ JavaScript とキャンバスを使用したソリューション
位置とチェックを処理するオブジェクトに複雑な形状を埋め込むことができます。オブジェクトは次のようになります。
Full working demo here
エキス:
主なオブジェクト -
function wave(ctx, offset, width) {
/// the check function which checks point x, y in last path
this.isInPath = function(x, y) {
getPath();
return ctx.isPointInPath(x, y);
}
/// this render the object with the set fill color
this.draw = function(color) {
getPath();
ctx.fillStyle = color;
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = "red";
ctx.stroke();
}
/// common function to generate just the path.
function getPath() {
ctx.beginPath();
ctx.moveTo(offset, 0);
ctx.bezierCurveTo(50 + offset, 30, 40 + offset, 45, 13 + offset, 89);
ctx.bezierCurveTo(offset, 110, offset, 126, 27 + offset, 174);
ctx.lineTo(27 + offset + width, 174);
ctx.bezierCurveTo(offset + width, 100, offset + width + 0, 126, 27 + offset + width, 65);
ctx.bezierCurveTo(43 + offset + width, 40, 40 + offset + width, 25, offset + width, 0);
ctx.closePath();
}
this.draw('white');
return this;
}
パスが自己完結型であることを確認してください。つまり、隣接するパーツに依存しない完全な形状であることを意味します (つまり、隣接する線を使用しません)。複雑な形状を処理するために必要なことは基本的にこれだけです。
与える
レンダリングするには、次のようにします。
for(;i < parts_num; i++) {
parts.push( new wave(context, i * part_width, part_width) );
}
小切手
ポイントがパーツ内にあるかどうかを確認するには、次のようにします。
/// check mouse move in this example
canvas.addEventListener('mousemove', hover, false);
/// the function to check parts
function hover(e) {
///get mouse coord relative to canvas
var r = canvas.getBoundingClientRect();
var x = e.clientX - r.left;
var y = e.clientY - r.top;
///optimize so we only clear last selected part
if (lastPart > -1) {
parts[lastPart].draw('white');
lastPart = -1;
}
for(i = 0 ;i < parts_num; i++) {
if (parts[i].isInPath(x, y) === true) {
parts[i].draw('green');
lastPart = i;
break; //don't need to check more
}
}
}
ここには最適化の余地があります (オブジェクト内の最後のパスを再利用する、形状を画像としてキャッシュする、範囲をチェックするなど) が、バニラ キャンバスと JavaScript を使用してこれを処理するのはそれほど複雑ではないことがわかります。
これをベースとして、クリックなどを自分で処理できるはずです。
(注: ベジエの終点についてはあまり正確ではありませんでした。この解決策を使用することを選択する必要がある場合は、微調整をあなたに任せます..)。