2

我试图将图层视为页面 - 即我在一个页面上绘制,然后翻页并在另一个页面上绘制,每次存储前一页以防用户返回它。

在我看来,这可以翻译为:

  • 创建current_layer全局指针。
  • 每次newPage()调用,将旧层存储在一个数组中,并覆盖指针

    layer_array.push(current_layer); //store old layer

    current_layer = new Kinetic.Layer(); //overwrite with a new

  • 然后将新对象添加到将current_layer它们绑定到图层的对象中,无论它们是否被绘制。(例如current_layer.add(myCircle)

  • 检索页面只是简单地更新指向数组中请求层的指针,然后重新绘制页面。附加到图层的所有子节点也将被绘制

    current_layer = layer_array[num-1]; //num is Page 2 e.g

    current_layer.draw()

然而什么都没有发生!我可以创建新页面并适当地存储它们 - 但我无法再次检索它们......

这是我的完整代码(我的浏览器在使用 jsfiddle 时出现问题):

<html>

  <head>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.0.min.js"></script>
    <script>
      //Global
      var stage; //canvas
      var layer_array = [];
      var current_page; //pointer to current layer

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

        //Add initial page to stage to draw on
        newPage()

      };

      //--- Functions ----//

        function newPage(){
            if(!current_page){
                console.log("current page undefined");

            } else {
                layer_array.push(current_page);
//              stage.remove(current_page); 

                //Nope, not working.
                stage.removeChildren();        
                //Works, but I think it unbinds all objects
                // from their specific layers...
//              stage.draw()

                console.log("Stored layer and removed it from stage");
            }
            current_page = new Kinetic.Layer();
            console.log("Currently on page:"+(layer_array.length+1));

            stage.add(current_page);
            stage.draw();

        }


        function gotoPage(num){
            stage.removeChildren()
            stage.draw()

            num = num-1;
            if(num >= 0) {
                current_page = layer_array[num];
                console.log("Now on page"+(num+1));

                stage.add(current_page);
                stage.draw();
            }

        }


        function addCircletoCurrentPage() 
        {
            var rand = Math.floor(3+(Math.random()*10));

            var obj = new Kinetic.Circle({
                x: rand*16, y: rand*16,
                radius: rand,
                fill: 'red'
            })

            var imagelayer = current_page;
            imagelayer.add(obj);
            imagelayer.draw();
        }
    </script>
  </head>

  <body>
    <div id="container"></div>
    <button onclick="addCircletoCurrentPage()" >click</button>
    <button onclick="newPage()" >new</button>
    <button onclick="gotoPage(1)" >page1</button>
    <button onclick="gotoPage(2)" >page2</button>
    <button onclick="gotoPage(3)" >page3</button>

  </body>

</html>
4

2 回答 2

3

这是一个有趣的问题。我认为这解决了你的麻烦:http: //jsfiddle.net/LRNHk/3/

基本上,您不应该 remove() 或 removeChildren() ,因为您可能会取消引用它们。

相反,您应该使用:

   layer.hide();  and  layer.show();

这样,您就可以保持一切平等,并获得快速的绘图性能。所以你的转到页面功能应该是这样的:

    function gotoPage(num){
       for(var i=0; i<layer_array.length; i++) {
            layer_array[i].hide();
       }
          layer_array[num].show();
          console.log("Currently on page:"+(num));
          console.log("Current layer: " + layer_array[num].getName());
          stage.draw();
    }

我还修改了您的其他功能,您可以在 jsfiddle 中看到这些功能。

于 2013-01-09T15:38:47.797 回答
-1

Okay I changed my approach and instead of swapping layers (100x easier and makes more sense), I instead opted for serializing the entire stage and loading it back.

It works, but it really shouldn't have to be like this dammit

  //Global
  var stage; //canvas
  var layer_array = [];
  var current_page; //pointer to current layer
  var page_num = 0;

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

    //Add initial page to stage to draw on
    newPage()

  };

  //--- Functions ----//

    function newPage(){
        if(!current_page){
            console.log("current page undefined");

        } else {
            savePage(page_num)
            stage.removeChildren()

            console.log("Stored layer and removed it from stage");
        }
        current_page = new Kinetic.Layer();
        console.log("Currently on page:"+(layer_array.length+1));

        stage.add(current_page);
        stage.draw();

        page_num ++;

    }

    function savePage(num){
        if( (num-1) >=0){
            var store = stage.toJSON();
            layer_array[num-1] = store;
            console.log("Stored page:"+num)
        }
    }

    function gotoPage(num){
        savePage(page_num);

        stage.removeChildren()

        if(num-1 >= 0) {
            var load = layer_array[num-1];
            document.getElementById('container').innerHTML = ""; //blank
            stage = Kinetic.Node.create(load, 'container');

            var images = stage.get(".image");

            for(i=0;i<images.length;i++)
            {  
            //function to induce scope
                (function() {
                    var image = images[i];
                    var imageObj = new Image();
                    imageObj.onload = function() {
                        image.setImage(imageObj);
                        current_page.draw();
                    };
                    imageObj.src = image.attrs.src;
                })();
            }
            stage.draw();
            page_num =num //update page

        }
    }

    function addCircletoCurrentPage() 
    {
        var rand = Math.floor(3+(Math.random()*10));

        var obj = new Kinetic.Circle({
            x: rand*16, y: rand*16, name: "image",
            radius: rand,
            fill: 'red'
        })

        var imagelayer = current_page;
        imagelayer.add(obj);
        imagelayer.draw();
    }
于 2013-01-09T15:13:24.403 回答