2012-11-29 48 views
4

我有一個問題,希望找到它的任何解決方案。Kinetic-js:如何將整個圖層緩存爲圖像

我使用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

在小提琴中,您可以通過更改一個參數來運行這兩個版本安靜。希望這可以幫助....

感謝您的幫助。

問候 托爾斯滕

+0

的jsfiddle是這麼容易的工作,你能做出一個? – nycynik

+0

@nycynik:我剛剛創建了我的第一個jsfiddle - 它工作(不) – bruns8234

+0

你已經解決了它,我看到小提琴中的紅色網格。 – nycynik

回答

3

其實問題比你想象的更簡單 - 緩存層成圖像後,你想添加一個圖像對象直接到舞臺(你不能這樣做)。

要解決該問題,您需要創建一個新圖層,例如cahcedLayer,將圖像添加到cachedLayer,然後將cachedLayer添加到舞臺。

退房的KineticJS信息頁面,瞭解更多有關節點嵌套:

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

+0

哦,我!我一直都被盲目擊中!你是對的!現在它像錘子一樣擊中我。我怎麼能錯過超過5天這樣的錯誤! – bruns8234

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); 
}