Paper.js 加载图像和活动层

Paper.js Loading Images and the Active Layer

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

// 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 在创建时将新图层设置为活动状态?或者有其他解决方法吗?

简单的回答,是的。

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

};

您可能希望在创建栅格后执行 null 数据 URL 之类的操作以节省一些内存,具体取决于在任何给定时间可能加载的这些内容的数量。