我有一个问题,希望找到任何解决方案。
我正在使用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
在小提琴中,您可以通过更改一个参数来运行这两个版本。希望这会有所帮助......
感谢您的帮助。
祝你好运 的Thorsten
答案 0 :(得分:3)
实际上,问题比你想象的要简单 - 在将图层缓存到图像后,你试图将图像对象直接添加到舞台上(你不能这样做)。
要解决此问题,您需要创建一个新图层,例如cahcedLayer,将图像添加到cachedLayer,然后将cachedLayer添加到舞台。
查看KineticJS信息页面以了解有关节点嵌套的更多信息:
答案 1 :(得分:1)
http://rvillani.com/testes/layer-to-image/ 我做了这个测试,但它确实有效。首先,我将1000个方块绘制到一个图层,将此图层添加到隐藏的舞台,然后使用stage.toDataURL()从此舞台制作图像。当回调返回时,我只是从数据创建一个Image,从Image创建一个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);
}