0

私は KineticJS の初心者で、交差点で特定の色に変わる 2 つのドラッグ可能なウェッジを作成したいと考えています。このフォーラムでシェイプ クリッピングのチュートリアルとシェイプの交差に関する質問を見てきました。一般的な戦術は、ドラッグ イベントをキャッチし、KineticJS 形状を再描画し、その形状の drawFunc 内で context.rect/context.arc を使用して形状を複製し、それをクリップすることであることを理解しています。

私の問題は、KineticJS ウェッジをシミュレートするための便利な context.wedge がないことです。そのため、ウェッジの使用をやめるか、複雑な計算を実行して context.arc と線でウェッジをシミュレートするか、より良い方法を見つけます。誰もがより良い方法を知っていますか?

ありがとう、
メイ

JSFiddle のコード: http://jsfiddle.net/kdRjP/5/ (機能しません。あちこちに重複したウェッジを作成し、クリップされたものでさえありません。)

コード:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" charset="utf-8" src="js/kinetic-v4.3.1.min.js"></script>
</head>



<body>
    <div id="container"></div>

    <script type="text/javascript">

        drawWedges();


        function drawWedges() {
            var stage = new Kinetic.Stage({
                container: "container",
                width: 400,
                height: 400
            });
            window.console.log("Wedges: 1");

            var wedgeLayer = new Kinetic.Layer();


            var wedgeGroup = new Kinetic.Group({
                x: stage.getWidth() / 2,
                y: stage.getWidth() / 2
            });


            var wedge_1 = new Kinetic.Wedge({
                x: -100,
                y: 0,
                radius: 80,
                angleDeg: 40,
                opacity: 0.7,
                fill: 'red',
                stroke: 'black',
                strokeWidth: 2,
                draggable: true,
                rotationDeg: 0
            });


            var wedge_2 = new Kinetic.Wedge({
                x: 100,
                y: 0,
                radius: 80,
                angleDeg: 40,
                opacity: 0.7,
                fill: 'cyan',
                stroke: 'black',
                strokeWidth: 2,
                draggable: true,
                rotationDeg: 0
            });             



            function makeShapeClip(clipShape, compositeShape) {
                clipShape.attrs.drawFunc_bak = clipShape.attrs.drawFunc;
                clipShape.attrs.drawFunc = function() {
                    var context = this.getContext();
                    context.save();
                    context.beginPath();
                    this.attrs.drawFunc_bak.call(this, context);
                    context.clip();
                    context.beginPath();
                    compositeShape.attrs.drawFunc.call(this, context);
                    context.fill();
                    context.closePath();
                    context.restore();
                };

                return compositeShape;
            };   


            wedge_1.on("dragend", function(evt) {
                var mousePos = stage.getMousePosition();

                var stageIntersections = stage.getIntersections({"x": mousePos.x, "y": mousePos.y});
                if (stageIntersections.length > 0) {
                    // Want to draw a piece of wedge_1 clipped around wedge_2.
                    // Since can't turn wedge_2 into a clip path after it's been drawn, 
                    // draw a duplicate of wedge_2 superimposed on top of wedge_2, 
                    // turn that duplicate into a clip path, 
                    // and then try to draw a duplicate of wedge_1 into it.


                    // Start by creating the wedge_1 duplicate in proper "intersection area color"
                    var wedgeComposite = new Kinetic.Wedge({
                        x: wedge_1.getX(),
                        y: wedge_1.getY(),
                        radius: wedge_1.getRadius(),
                        angleDeg: wedge_1.getAngleDeg(),
                        opacity: 0.5,
                        fill: 'yellow',
                        stroke: 'blue',
                        strokeWidth: 2,
                        draggable: true,
                        rotationDeg: wedge_1.getRotationDeg()
                    });


                    // Now pass that wedge_1 duplicate into a special function that 
                    // creates wedge_2 duplicate and makes it into a clip path.
                    var wedgeClip = makeShapeClip(new Kinetic.Wedge({
                        x: stageIntersections[0].getX(),
                        y: stageIntersections[0].getY(),
                        radius: stageIntersections[0].getRadius(),
                        angleDeg: stageIntersections[0].getAngleDeg(),
                        opacity: 0.5,
                        fill: '#999999',
                        stroke: 'red',
                        strokeWidth: 2,
                        draggable: true,
                        rotationDeg: stageIntersections[0].getRotationDeg()
                    }), wedgeComposite);


                    wedgeGroup.add(wedgeClip);
                }

                wedgeLayer.draw();
            });




            wedgeGroup.add(wedge_1);
            wedgeGroup.add(wedge_2);
            wedgeLayer.add(wedgeGroup);
            stage.add(wedgeLayer);
        }   
    </script>


</body>
</html>
4

1 に答える 1

0

解決策は次のとおりです。

2つのKineticJsウェッジ(赤とシアン)を備えたキャンバス#1があると仮定します。

ユーザーがドラッグを完​​了したとき:

  1. 現在の位置/回転にちょうど赤いウェッジを使用して、新しいキャンバス#2(キャンバス#1と同じサイズ)を作成します。canvas#2(visibility:hidden)を表示しないでください。

  2. 現在の位置/回転にシアンのくさびだけを使用して、新しいキャンバス#3(キャンバス#1と同じサイズ)を作成します。canvas#3(visibility:hidden)を表示しないでください。

  3. canvas#2とcanvas#3の両方の左上のピクセルから始めて、canvas#2とcanvas#3の対応するすべてのピクセルを繰り返し処理します。

  4. #2と#3の対応するピクセルが両方とも「色付き」の場合、ウェッジはそのピクセルで交差しています。

  5. 手順4の「ヒット」については、canvas#1の交差するピクセルに必要なものを描画します(そのピクセルを指定した色に変更するなど)。

パフォーマンスを向上させるために、2つのウェッジのバウンディングボックスを計算して、それらが交差するかどうかを確認できます。

ウェッジがまったく交差しない場合は、ピクセルヒットテストを気にしないでください。

それらが交差する場合は、結合されたウェッジのバウンディングボックスをピクセルヒットテストします。

于 2013-02-10T19:32:57.863 に答える