【问题标题】:Fabricjs load multipage PDF as multiple canvasesFabricjs将多页PDF加载为多个画布
【发布时间】:2020-05-06 08:27:45
【问题描述】:

我想在fabricjs中将多页PDF加载为每个画布一页,但我无法为每个PDF页面初始化画布。由于 PDF 的最后一页使用 PDFjs 作为背景图像加载到画布中,我只想对所有页面执行此操作。

欢迎提出任何建议。

var canvas = new fabric.Canvas('pdfcanvas', {
  width: 420,
  height: 594,
  selection: false,
});

//load pdf
document.querySelector('#pdf-upload').addEventListener('change', function(e) {
  var file = e.target.files[0];

  if (file.type == 'application/pdf') {
    var fileReader = new FileReader();
    fileReader.onload = function() {
      var typedarray = new Uint8Array(this.result);
      PDFJS.getDocument(typedarray).then(function(pdf) {
        console.log('the pdf has ', pdf.numPages, 'page(s).');
        pdf.getPage(pdf.numPages).then(function(pageEl) {
          var viewport = pageEl.getViewport(2.0);
          var canvasEl = document.querySelector('canvas');
          canvasEl.height = viewport.height;
          canvasEl.width = viewport.width;
          pageEl.render({
            'canvasContext': canvasEl.getContext('2d'),
            'viewport': viewport
          }).then(function() {

            var bg = canvasEl.toDataURL('image/png');

            fabric.Image.fromURL(bg, function(img) {
              canvas.setBackgroundImage(img);
              var pageEl = document.getElementById('page-container');
              var currentW = canvas.backgroundImage.width;
              var currentH = canvas.backgroundImage.height;
              var windowW = $(window).width();
              var windowH = $(window).height();
              if (currentW < currentH) {
                img.scaleToHeight(594);
              }
            });
            canvas.renderAll();
          });
        });
      });
    };
    fileReader.readAsArrayBuffer(file);
  }
});

var currentColor;
var defaultIcon = {
  width: 62.5,
  height: 50,
  originX: 'center',
  originY: 'center'
};
var iconTriangle = new fabric.Triangle(defaultIcon);
setColor('green');
canvas.add(iconTriangle);
//disable icon & hide when hovering over existing icon
canvas.on('mouse:over', function(obj) {
  iconTriangle.set('opacity', 0);
  canvas.renderAll();
});
//restor icon & unhide
canvas.on('mouse:out', function(e) {
  // if 'target' is null, means mouse is out of canvas
  if (e.target) {
    iconTriangle.set('opacity', 1);
  } else {
    iconTriangle.left = -100;
    iconTriangle.top = -100;
  }
  canvas.renderAll();
});
//move pointer icon
canvas.on('mouse:move', function(obj) {
  iconTriangle.top = obj.e.y - 80;
  iconTriangle.left = obj.e.x - 10;
  canvas.renderAll();
});

//count each by type and place new icon
canvas.on('mouse:up', function(e) {
  if (e.target) {
    return
  }
  var red = getObjectsBy((obj) => obj.fill === 'red').length;
  var green = getObjectsBy((obj) => obj.fill === 'green').length;
  var yellow = getObjectsBy((obj) => obj.fill === 'yellow').length;
  document.getElementById("greentally").value = green;
  document.getElementById("yellowtally").value = yellow;
  document.getElementById("redtally").value = red;
  addIcon(e.e.x - 10, e.e.y - 80, currentColor);
});
//set icon type
function iconSet() {
  if (document.getElementById("green").checked == true) {
    setColor('green');
  } else if (document.getElementById("yellow").checked == true) {
    setColor('yellow');
  } else if (document.getElementById("red").checked == true) {
    setColor('red');
  }
}

function setColor(color) {
  currentColor = color;
  iconTriangle.setColor(currentColor);
  canvas.renderAll();
}

function getObjectsBy(fn) {
  return canvas.getObjects().filter(fn)
}

function addIcon(x, y, color) {
  var icon = new fabric.Triangle(defaultIcon);
  icon.setColor(color);
  icon.left = x;
  icon.top = y;
  canvas.add(icon);
}
canvas {
  border: 1px solid #ccc;
}

.tally {
  position: absolute;
  width: 50px;
  left: 255px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/1.8.349/pdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.1/fabric.js"></script>

<input checked name="iconType" type="radio" id="green" onclick="iconSet()" />Green &emsp;
<input class="tally" disabled id="greentally" type="text" value="0">
<br>
<input name="iconType" type="radio" id="yellow" onclick="iconSet()" /> Yellow &emsp;
<input class="tally" disabled id="yellowtally" type="text" value="0">
<br>
<input name="iconType" type="radio" id="red" onclick="iconSet()" /> red &emsp;
<input class="tally" disabled id="redtally" type="text" value="0">
<br>
<input id="pdf-upload" type="file">

<canvas id="pdfcanvas"></canvas>

【问题讨论】:

  • 您是说您需要每个画布加载一页,但您的 html 中只有一个画布,并且您只加载 pdf 的最后一页。
  • @shkaper 是的,我想以编程方式为 pdf 中的每一页初始化一个织物画布。只是不知道该怎么做。

标签: fabricjs pdfjs


【解决方案1】:

__PDF_DOC.numPages 指 pdf 文件中存在的页数。基于此,您可以从第一页循环到最后一页,以便为每个页面创建画布。

PDFJS.getDocument('file.pdf').then(function(pdf) 
{

 __PDF_DOC       = pdf;
 __TOTAL_PAGES   = __PDF_DOC.numPages;


   for (var i = 1; i <= __TOTAL_PAGES; i++) 
    {
      pdf_doc.getPage((i)).then(function(p)
       {
          //create canvas here    
       }

     }

})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 2017-05-09
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    相关资源
    最近更新 更多