4

この形状を html5 キャンバスで描画する必要がありますが、1 つのキャンバスとして描画できます。

http://postimg.org/image/li5mpoot3/

の各部分を一意のオブジェクトとして処理する必要があります。各部分にマウスを合わせるのを聞いて、ユーザーがマウスを置いている部分を特定し、形状の関連部分を塗りつぶすオプションをユーザーに与えます。

var canvas = document.getElementById('shape');
var context = canvas.getContext('2d'),
width = $('#shape').width(),
part_width = width / parts_num;

context.beginPath();

var start_x = 17,
end_x = 17 + part_width;
for (var i = 0; i < parts_num; i++) {
context.moveTo(start_x, 0); 
context.lineTo(end_x,0);
context.moveTo(start_x, 0);
context.bezierCurveTo(50+start_x, 30, 40+start_x, 45, 13+start_x, 89);
context.moveTo(13+start_x, 89);
context.bezierCurveTo(0+start_x, 110, 0+start_x, 126, 27+start_x, 174);
context.moveTo(28+start_x, 174);
context.lineTo(85+start_x,174);
start_x += part_width;//80 is x starting point
};
context.lineWidth = 5;
context.strokeStyle = "red";
context.stroke();
4

2 に答える 2

3

バニラ 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 を使用してこれを処理するのはそれほど複雑ではないことがわかります。

これをベースとして、クリックなどを自分で処理できるはずです。

(注: ベジエの終点についてはあまり正確ではありませんでした。この解決策を使用することを選択する必要がある場合は、微調整をあなたに任せます..)。

于 2013-07-07T14:00:33.970 に答える
3

CreateJSを使用することをお勧めします。キャンバスで作業している間、それはあなたの人生をずっと楽にしてくれます.

以下は、CreateJS を使用して各形状をオブジェクトとして処理する方法のデモです。

個々の形状をクリックして、それぞれが独自のハンドラーをトリガーする方法を確認します。

function curveShape(index, start_x, end_x) {
    var shape = new createjs.Shape();
    var context = shape.graphics.beginStroke("red").beginFill("#ffffee");    
    context.moveTo(start_x, 0);
    context.bezierCurveTo(start_x + 10, 30, start_x + 10, 45, start_x - 15, 90);
    context.bezierCurveTo(start_x - 30, 120, start_x - 30, 135, start_x, 180);
    context.lineTo(end_x, 180);
    context.bezierCurveTo(end_x - 30, 135, end_x - 30, 120, end_x - 15, 90);
    context.bezierCurveTo(end_x + 10, 45, end_x + 10, 30, end_x, 0);
    context.lineTo(start_x, 0);

    shape.name = "shape " + index;
    shape.x = shape.y = 30;
    shape.addEventListener("mousedown", function () {
        alert("I am " + shape.name);
    });

    return shape;
}

var stage = new createjs.Stage("shape");    

for(var i = 0; i < 4; i++) 
    stage.addChild(new curveShape(i+1, i * 80, (i + 1) * 80));   

stage.update();
于 2013-07-07T09:54:38.877 に答える