4

私はそれに対する解決策を見つけることを望んでいる問題を抱えています。

Kinetic.js を使用して、特別なルック アンド フィールの HMI ソリューションを作成しています。そのため、ステージ用に 3 つのレイヤーを作成する関数を作成しました。グリッドを含む背景レイヤー、HMI 画面の基本レイアウト用の静的形状を含むレイヤー、およびすべてのインタラクティブ要素 (ボタン、値表示など) 用の 3 番目のレイヤーです。の上...)。ここで、グリッドと静的レイヤーをキャッシュしてパフォーマンスを向上させたいと考えています。このレイヤーは、HMI 画面全体が変更されるまで変更されないためです...

テストとして、次のコードを使用してグリッド レイヤーのキャッシュのコーディングを開始しました。

// Create a grid layer if showGrid is set to TRUE...
console.log('Start to create background grid if required');
if (this.actualPageConfig.showGrid) {
    var grid = new Kinetic.Layer();
    for (var x=1; x <= this.cols; x++) {
        var eLoc = LCARSElements.posToRealPos(x, 1, this.cols, this.rows);
        if (x <= this.actualPageConfig.columns) {
            grid.add(new Kinetic.Line({
                points: [eLoc.x, eLoc.y, eLoc.x, eLoc.height],
                stroke: "red",
                strokeWidth: 1,
                lineCap: "round",
                lineJoin: "round" 
            }));
        }
    }
    for (var y=1; y <= this.rows; y++) {
        var eLoc = LCARSElements.posToRealPos(1, y, this.cols, this.rows);
        if (y <= this.actualPageConfig.rows) {
            grid.add(new Kinetic.Line({
                points: [eLoc.x, eLoc.y, eLoc.width, eLoc.y],
                stroke: "red",
                strokeWidth: 1,
                lineCap: "round",
                lineJoin: "round"
            }));
        }
    }

    // Add grid layer to stage
    //this.stage.add(grid);  <-- to be replaced by cache image

    // Convert grid into an image and add this to the stage
    console.log('convert grid to image to increase performance');
    grid.toImage({
        width:      displayManager.stage.getWidth(),
        height:     displayManager.stage.getHeight(),
        callback:   function(img) {
            var cacheGrid = new Kinetic.Image({ 
                image:  img,
                x:      0,
                y:      0,
                width:  displayManager.stage.getWidth(),
                height: displayManager.stage.getHeight()
            });
            console.log('insert grid-image to stage');
            displayManager.stage.add(cacheGrid);
            console.log('redraw stage...');
            displayManager.stage.draw();
        }
    });
}

私の問題は、それが機能していないことです。グリッドが表示されなくなり、コンソール ログに次のエラー情報が表示されます。

Type error: layer.canvas is undefined
layer.canvas.setSize(this.attrs.width, this.attrs.height);      kinetic.js (Zeile 3167)

コード「displayManger.stage.add(cacheGrid)が実行されるときにエラーが発生することはすでにわかっています(displayManagerは、このコードが切り取られた外部クラスです)。どこで間違いを犯したか誰にもわかりますか?直接追加するとレイヤーグリッドは何でもうまくいきます...

問題を示すためにjsfiddleを作成しました:jsfiddle

フィドルでは、1 つのパラメーターを変更することで両方のバージョンを実行できます。お役に立てれば....

手伝ってくれてありがとう。

よろしくトルステン

4

2 に答える 2

3

実際、問題は思ったよりも単純です。レイヤーを画像にキャッシュした後、画像オブジェクトをステージに直接追加しようとしています (それはできません)。

この問題を解決するには、cahcedLayer などの新しいレイヤーを作成し、画像を cachedLayer に追加してから、cachedLayer をステージに追加する必要があります。

ノードのネストについて詳しくは、KineticJS の情報ページをご覧ください。

https://github.com/ericdrowell/KineticJS/wiki

于 2012-12-02T03:13:24.220 に答える
1

http://rvilani.com/testes/layer-to-image/ このテストを行ったところ、うまくいきました。まず、レイヤーに 1000 個の正方形を描画し、このレイヤーを隠しステージに追加してから、stage.toDataURL() を使用してこのステージから画像を作成します。コールバックが戻ったら、データから画像を作成し、画像から Kinetic.Image を作成します。次に、メイン (可視) ステージのレイヤーに追加します。コード (必ず 'invisible' という div を用意してください):

window.onload = function()
{
    var stage = new Kinetic.Stage({
        width: 520,
        height: 480,
        container: 'container'
    });

    var outerStage = new Kinetic.Stage({
        width: stage.getWidth(),
        height: stage.getHeight(),
        container: 'invisible'
    });

    var layerToCache = new Kinetic.Layer();
    var layer = new Kinetic.Layer();
    var group = new Kinetic.Group({offset: [stage.getWidth(), stage.getHeight()]});

    var anim = new Kinetic.Animation(function(frame){
        group.rotate(0.02);
    }, layer);

    var fills = ['red', 'green', 'blue', 'orange', 'purple', 'cyan',
        'black', 'brown', 'forestgreen', 'gray', 'pink'];
    for (var i = 0; i < 10000; ++i)
    {
        (function ()
         {
            var size = Math.random() * 60 + 20;
            var square = new Kinetic.Rect({
                width: size,
                height: size,
                fill: fills[i % fills.length],
                x: Math.random() * stage.getWidth() - 20,
                y: Math.random() * stage.getHeight() - 20
            });
            layerToCache.add(square);
         })();
    }

    var squaresImg = new Kinetic.Image();
    outerStage.add(layerToCache);
    outerStage.toDataURL({
        callback: function (dataURL){
            outerStage.clear();

            var img = new Image();
            img.src = dataURL;
            img.onload = function () {
                squaresImg.setImage(img);
                squaresImg.setX(squaresImg.getWidth() >> 1);
                squaresImg.setY(squaresImg.getHeight() >> 1);
                group.setX(stage.getWidth() >> 1);
                group.setY(stage.getHeight() >> 1);

                group.add(squaresImg);
                layer.add(group);
                layer.draw();
                anim.start();
            }
        }
    });

    var div = document.getElementById('invisible');
    div.parentNode.removeChild(div);

    stage.add(layer);
}
于 2012-12-01T22:06:03.543 に答える