如何将画布转换为 PDF

您想将 Konva 阶段保存为 PDF 文件吗?

PDF 是一种复杂的格式。因此,我们需要使用像 jsPDF 这样的外部库。

将画布保存为 PDF 的方法很简单:

  1. 生成画布内容
  2. 将画布导出为图像
  3. 将图像添加到使用 PDF 库创建的 PDF 文档中
  4. 保存 PDF 文件

我还有两个小提示给您:

  1. 通过 高质量导出,您可以在将节点转换为图像时,使用 pixelRatio 属性来提高 PDF 的质量。

  2. 在 PDF 中可以使文本可选择。即使我们将画布作为图像添加到 PDF 中,我们仍然可以手动插入文本。这并不简单,如果您有复杂样式的话可能会比较困难。此外,PDF 中的文本渲染与 Konva 的文本渲染是不同的。但我们可以尽量使其接近。作为演示,我们将在 PDF 文件中绘制“隐藏”文本。文本将放置在图像下方,因此不可见。但它仍然是可选择的。作为“复杂样式”的演示,我将对文本进行模糊处理。

说明:查看画布。然后尝试将其保存为 PDF。

Konva PDF demoview raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva@9.3.18/konva.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js"
integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/"
crossorigin="anonymous"
></script>
<meta charset="utf-8" />
<title>Konva PDF Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
#save {
position: absolute;
top: 5px;
left: 5px;
}
</style>
</head>

<body>
<div id="container"></div>
<button id="save">Save as PDF</button>
<script>
var width = window.innerWidth;
var height = window.innerHeight;

var stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
});

var layer = new Konva.Layer();
stage.add(layer);

var back = new Konva.Rect({
width: stage.width(),
height: stage.height(),
fill: 'rgba(200, 200, 200)',
});
layer.add(back);

var text = new Konva.Text({
text: 'This is the Darth Vader',
x: 15,
y: 40,
rotation: -10,
filters: [Konva.Filters.Blur],
blurRadius: 4,
fontSize: 18,
});
text.cache();
layer.add(text);

var arrow = new Konva.Arrow({
points: [70, 50, 100, 80, 150, 100, 190, 100],
tension: 0.5,
stroke: 'black',
fill: 'black',
});
layer.add(arrow);

// alternative API:
Konva.Image.fromURL(
'https://konvajs.org//assets/darth-vader.jpg',
function (darthNode) {
darthNode.setAttrs({
x: 200,
y: 50,
scaleX: 0.5,
scaleY: 0.5,
});
layer.add(darthNode);
}
);

document.getElementById('save').addEventListener('click', function () {
var pdf = new jsPDF('l', 'px', [stage.width(), stage.height()]);
pdf.setTextColor('#000000');
// first add texts
stage.find('Text').forEach((text) => {
const size = text.fontSize() / 0.75; // convert pixels to points
pdf.setFontSize(size);
pdf.text(text.text(), text.x(), text.y(), {
baseline: 'top',
angle: -text.getAbsoluteRotation(),
});
});

// then put image on top of texts (so texts are not visible)
pdf.addImage(
stage.toDataURL({ pixelRatio: 2 }),
0,
0,
stage.width(),
stage.height()
);

pdf.save('canvas.pdf');
});
</script>
</body>
</html>