Paper.js加载图片和活动图层

时间:2015-11-18 16:31:27

标签: javascript image asynchronous layer paperjs

我正在使用Paper.js制作一个处理图像队列的图像编辑器。这些图像来自上传到服务器并转换为图像的PDF。根据此question中的建议,我将每个图片加载到自己的图层中。

// Load images of pdf, each into its own layer
var loadPdf = function(pdfAsImages) {
  toolsSetup();

  // Loop through images for pdf
  pdfToLayerMap[pdfAsImages.id] = [];
  for(var i = 0; i < pdfAsImages.images.length; i++) {
    var layerForImage = new paper.Layer();
    layerForImage.visible = false;
    pdfToLayerMap[pdfAsImages.id][i] = {
      layerIndex: paper.project.activeLayer.index,
      imageHeight: pdfAsImages.images[i].height
    };

    var imageDataUrl = 'data:image/png;base64,' + pdfAsImages.images[i].imageData;
    var raster = new paper.Raster(imageDataUrl, new paper.Point(canvas.width / 2, canvas.height / 2));
    layerForImage.addChild(raster);

    selectedItemsByLayer[layerForImage.index] = new paper.Group();

    registerLayerEvents(layerForImage);
  }
};

var setActive = function(pdfIndex, imageIndex) {
  var imageHeight =  pdfToLayerMap[pdfIndex][imageIndex].imageHeight;
  paper.project.activeLayer.visible = false;
  var layerToActivate = pdfToLayerMap[pdfIndex][imageIndex].layerIndex;
  paper.project.layers[layerToActivate].activate();
  paper.project.layers[layerToActivate].visible = true;
  fitToPage(imageHeight);
};
每次从服务器接收图像时都会调用

loadPdf。这为pdf中的每个页面的每个图像添加了一个新图层。问题在于,当创建新图层时,它被设置为活动图层。因此,当从服务器加载图像时,我们希望能够对已加载的图像执行编辑。但是当图像加载时,活动层与我们当前正在编辑的已加载图像不同步。因此,如果我尝试添加文本,例如,它会将其添加到错误的图像,因为它会将其添加到活动图层,这是错误的图层。不知何故,我们需要将活动图层与我们当前正在编辑的图像保持在一起。 (这可以通过单独的Paper上下文来完成吗?)

由于我们事先不知道图像的数量(我们知道PDF的数量,但不知道每个页面的数量),我们不能做这样的事情,事先初始化所有图层:

var initializeLayers = function(numberOfLayers) {
  for(var i = 0; i < numberOfLayers; i++) {
    var layerForImage = new paper.Layer();
    layerForImage.visible = false;
    selectedItemsByLayer[i] = new paper.Group();
  }

  paper.project.layers[0].activate();
};

那么有没有办法阻止Paper.js在创建时将新图层设置为活动状态?或者还有另一种解决方法吗?

1 个答案:

答案 0 :(得分:1)

简单回答,是的。

var layer = new paper.Layer({insert: false});

编辑以解决以下提问者的评论:

您提到的草图试图直接操纵纸张的内部数据结构。这就是为什么它不起作用。

这是一个经过修改的sketch,可以在不弄乱纸张内部的情况下处理事情。

顺便说一句,在有意思的情况下,这是一个按需方法的元解决方案,我在昨天意识到纸张可以创建一个层而不是将其插入到项目中之前就已融合在一起。我说元解决方案,因为我只是在没有任何测试的情况下编写它,所以如果你遇到问题让我知道,我会修复它们。

// Load images of pdf, each into its own layer
var loadPdf = function(pdfAsImages) {
    toolsSetup();

    // Loop through images for pdf
    pdfToLayerMap[pdfAsImages.id] = [];
    for(var i = 0; i < pdfAsImages.images.length; i++) {
        pdfToLayerMap[pdfAsImages.id][i] = {
            layerIndex: null,
            imageHeight: pdfAsImages.images[i].height,
            dataURL: 'data:image/png;base64,' + pdfAsImages.images[i].imageData;
        };
    };
};

var setActive = function(pdfIndex, imageIndex) {
    var image = pdfToLayerMap[pdfIndex][imageIndex];

    // make the current layer invisible
    paper.project.activeLayer.visible = false;

    // if the layer has already been created just enable it and return
    if (image.layerIndex !== null) {
        paper.project.layers[image.layerIndex].activate();
        paper.project.layers[image.layerIndex].visible = true;
        fitToPage(image.imageHeight);
        return;
    } 

    // the layer hasn't been created, create it
    var layer = new paper.Layer();
    image.layerIndex = layer.index;
    layer.addChild(new paper.Raster(image.dataURL,
                                paper.view.bounds.center));
    selectedItemsByLayer[layer.index] = new paper.Group();
    registerLayerEvents(layer);
    }

};

创建栅格后,您可能希望在dataURL中执行null之类的操作以保存一些内存,具体取决于在任何给定时间可以加载多少内存。