4

我有一个问题,希望找到任何解决方案。

我正在使用 Kinetic.js 创建具有特殊外观的 HMI 解决方案。因此,我创建了一个为舞台创建 3 层的函数:一个带有网格的背景层,一个用于 HMI 屏幕基本布局的静态形状层和一个用于所有交互元素(如按钮、值显示等)的第三层在...)。现在我想缓存网格和静态层以提高性能,因为在整个 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

在小提琴中,您可以通过更改一个参数来运行这两个版本。希望这可以帮助....

感谢帮助。

最好的问候托尔斯滕

4

2 回答 2

3

实际上,问题比您想象的要简单 - 将图层缓存到图像后,您尝试将图像对象直接添加到舞台(您不能这样做)。

要解决此问题,您需要创建一个新层,例如 cahcedLayer,将图像添加到 cachedLayer,然后将 cachedLayer 添加到舞台。

查看 KineticJS 信息页面以了解有关节点嵌套的更多信息:

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

于 2012-12-02T03:13:24.220 回答
1

http://rvillani.com/testes/layer-to-image/ 我已经做了这个测试并且它有效。首先,我在一个图层上绘制 1000 个正方形,将此图层添加到隐藏阶段,然后使用 stage.toDataURL() 从该阶段制作图像。当回调返回时,我只是从数据中创建一个图像,并从图像中创建一个 Kinetic.Image。然后我将它添加到我的主(可见)舞台上的一个图层中。代码(确保有一个名为“不可见”的 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 回答