在 PDFKit 中旋转文本有什么技巧吗?
Is there any trick to rotate text in PDFKit?
我正在使用 PDFKit.org 通过 JavaScript 生成 PDF。
该文档是不言自明的,但我面临一个未解决的问题,我想一些 Whosebug 成员可能已经找到了解决问题的技巧。
有时我必须旋转文本,文档只解释了如何旋转形状(如 rect()
)。
我已经尝试了几种方法,但是 none 目前为止它们都有效。
所以我正在寻找一种通过调整代码来旋转它的方法,或者你们中的一些人可以向我展示我可能错过的文档的一部分吗?
没有什么特别的技巧,但正确理解 PDFKit 中的转换应用方式至关重要。
要了解的主要事情是您不旋转文本或形状:您旋转文档,正如 doc.rotate(...).rect(...)
所暗示的那样。
它可能会帮助您将文档视为具有物理属性的 canvas。它的特性之一是旋转。
如果您想在纸页上绘制旋转的文本,您可能会做的是实际旋转您的页面,然后像往常一样水平书写一些文本,然后将页面旋转回其正常状态。
然后,您最终得到的是垂直页面上的旋转文本:
这正是 PDFKit 的工作方式:您对文档应用转换,在转换后的上下文中绘制您需要绘制的所有内容,然后将文档设置回其先前的状态。
要实现这一点,您有两种方法:doc.save()
和 doc.restore()
。
- 在应用变换之前使用
save()
,这样之前绘制的所有内容都不会受到影响。
- 然后您可以变换您的 canvas 并绘制您需要的东西
- 绘制完需要转换的所有内容后,调用
restore()
将文档恢复到初始状态。它基本上会回滚在最近的 save()
调用之后执行的所有转换(即旋转、缩放、平移)。
要(有点)重现上面的图表,您会这样做:
doc.text('text', ...)
doc.save()
doc.rotate(90).text('rotated text', ...)
doc.restore()
最后要了解的是您的文档的坐标系会受到转换的影响:
因此,如果 text
绘制在坐标 (0, 0)
处,则 rotated text
绘制在类似 (0, documentHeight / 2 - offset)
.
的位置
使用 90 度旋转的倍数时很容易处理,但否则你将不得不玩三角函数:)
为方便起见,您可以尝试旋转原点,以确保您围绕对下一张图有意义的点旋转文档!
我对答案中描述的那个问题或事实有点紧张。尝试了很多东西,但文本最终总是按照自己的方式行事。
这是我用来以不同方向放置文本的小剪辑。
此函数在旋转坐标系中计算新的 x 和 y。
var doTransform = function (x, y, angle) {
var rads = angle / 180 * Math.PI;
var newX = x * Math.cos(rads) + y * Math.sin(rads);
var newY = y * Math.cos(rads) - x * Math.sin(rads);
return {
x: newX,
y: newY,
rads: rads,
angle: angle
};
};
这一个然后遍历具有 x、y、旋转的文本数组。 Uncerscore 用于循环。
var drawTexts = function (doc, texts) {
_.each(texts, t => {
doc.save();
doc.fontSize(t.size);
var loc = doTransform(t.x, t.y, t.rotation);
doc.rotate(t.rotation);
doc.text(t.text, loc.x, loc.y);
doc.restore();
});
};
首先旋转 'world',然后将文本放置到与 (t.x,t.y) 相同的位置但旋转的新 (x,y)世界.
编写旋转文本的最佳方法是围绕某个点(您想要文本的起点)旋转 pdf,然后写入并旋转 pdf 文档。
代码示例:
doc.rotate(angle, { origin: [x,y] });
doc.text( 'TEST', x, y);
doc.rotate(angle * (-1), { origin: [x,y] });
这样就不需要计算新位置了。
另外值得一提的是,pdfkit 将我们文本的 x 和 y 作为我们文本的左上角 "box"(这对我来说很重要)。
您可以使用 svg。参见 https://pdfmake.github.io/docs/document-definition-object/svgs/
pdfmake 为此使用 svg-to-pdfkit。
transform="rotate...." 似乎在源代码中受支持,请参阅 https://github.com/alafr/SVG-to-PDFKit/blob/master/source.js#L431 :
} else if (func === 'rotate' && nums.length === 3) {
let a = nums[0] * Math.PI / 180;
result = multiplyMatrix(result, [1, 0, 0, 1, nums[1], nums[2]], [Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0], [1, 0, 0, 1, -nums[1], -nums[2]]);
}
我正在使用 PDFKit.org 通过 JavaScript 生成 PDF。
该文档是不言自明的,但我面临一个未解决的问题,我想一些 Whosebug 成员可能已经找到了解决问题的技巧。
有时我必须旋转文本,文档只解释了如何旋转形状(如 rect()
)。
我已经尝试了几种方法,但是 none 目前为止它们都有效。
所以我正在寻找一种通过调整代码来旋转它的方法,或者你们中的一些人可以向我展示我可能错过的文档的一部分吗?
没有什么特别的技巧,但正确理解 PDFKit 中的转换应用方式至关重要。
要了解的主要事情是您不旋转文本或形状:您旋转文档,正如 doc.rotate(...).rect(...)
所暗示的那样。
它可能会帮助您将文档视为具有物理属性的 canvas。它的特性之一是旋转。
如果您想在纸页上绘制旋转的文本,您可能会做的是实际旋转您的页面,然后像往常一样水平书写一些文本,然后将页面旋转回其正常状态。
然后,您最终得到的是垂直页面上的旋转文本:
这正是 PDFKit 的工作方式:您对文档应用转换,在转换后的上下文中绘制您需要绘制的所有内容,然后将文档设置回其先前的状态。
要实现这一点,您有两种方法:doc.save()
和 doc.restore()
。
- 在应用变换之前使用
save()
,这样之前绘制的所有内容都不会受到影响。 - 然后您可以变换您的 canvas 并绘制您需要的东西
- 绘制完需要转换的所有内容后,调用
restore()
将文档恢复到初始状态。它基本上会回滚在最近的save()
调用之后执行的所有转换(即旋转、缩放、平移)。
要(有点)重现上面的图表,您会这样做:
doc.text('text', ...)
doc.save()
doc.rotate(90).text('rotated text', ...)
doc.restore()
最后要了解的是您的文档的坐标系会受到转换的影响:
因此,如果 text
绘制在坐标 (0, 0)
处,则 rotated text
绘制在类似 (0, documentHeight / 2 - offset)
.
的位置
使用 90 度旋转的倍数时很容易处理,但否则你将不得不玩三角函数:)
为方便起见,您可以尝试旋转原点,以确保您围绕对下一张图有意义的点旋转文档!
我对答案中描述的那个问题或事实有点紧张。尝试了很多东西,但文本最终总是按照自己的方式行事。
这是我用来以不同方向放置文本的小剪辑。 此函数在旋转坐标系中计算新的 x 和 y。
var doTransform = function (x, y, angle) {
var rads = angle / 180 * Math.PI;
var newX = x * Math.cos(rads) + y * Math.sin(rads);
var newY = y * Math.cos(rads) - x * Math.sin(rads);
return {
x: newX,
y: newY,
rads: rads,
angle: angle
};
};
这一个然后遍历具有 x、y、旋转的文本数组。 Uncerscore 用于循环。
var drawTexts = function (doc, texts) {
_.each(texts, t => {
doc.save();
doc.fontSize(t.size);
var loc = doTransform(t.x, t.y, t.rotation);
doc.rotate(t.rotation);
doc.text(t.text, loc.x, loc.y);
doc.restore();
});
};
首先旋转 'world',然后将文本放置到与 (t.x,t.y) 相同的位置但旋转的新 (x,y)世界.
编写旋转文本的最佳方法是围绕某个点(您想要文本的起点)旋转 pdf,然后写入并旋转 pdf 文档。 代码示例:
doc.rotate(angle, { origin: [x,y] });
doc.text( 'TEST', x, y);
doc.rotate(angle * (-1), { origin: [x,y] });
这样就不需要计算新位置了。
另外值得一提的是,pdfkit 将我们文本的 x 和 y 作为我们文本的左上角 "box"(这对我来说很重要)。
您可以使用 svg。参见 https://pdfmake.github.io/docs/document-definition-object/svgs/
pdfmake 为此使用 svg-to-pdfkit。
transform="rotate...." 似乎在源代码中受支持,请参阅 https://github.com/alafr/SVG-to-PDFKit/blob/master/source.js#L431 :
} else if (func === 'rotate' && nums.length === 3) {
let a = nums[0] * Math.PI / 180;
result = multiplyMatrix(result, [1, 0, 0, 1, nums[1], nums[2]], [Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0], [1, 0, 0, 1, -nums[1], -nums[2]]);
}