【问题标题】:Is there any trick to rotate text in PDFKit?在 PDFKit 中旋转文本有什么技巧吗?
【发布时间】:2017-05-19 02:19:53
【问题描述】:

我正在使用PDFKit.org 通过 JavaScript 生成 PDF。

文档是不言自明的,但我面临一个未解决的问题,我猜一些 StackOverflow 成员可能已经找到了解决问题的技巧。

我必须在某些时候旋转文本,而文档仅说明如何旋转形状(例如 rect())。

我已经尝试了几件事,但到目前为止都没有工作。

所以我正在寻找一种通过调整代码来旋转它的方法,或者也许你们中的一些人可以向我展示我可能错过的文档的一部分?

【问题讨论】:

  • 看完that part of the examples,我不得不问:为什么rotate不适合你?
  • 实际上,rotate() 有效,但缺少的部分是 save()restore() 函数,这已由 Olivier Lance 回答!所以基本上,在我的第一次尝试中,我旋转了一次文档,我的第二次rotate() 弄乱了 PDF 渲染,现在,由于Save() 我能够旋转回包含文本的元素,而不会弄乱东西向上:)

标签: javascript pdf pdfjs node-pdfkit


【解决方案1】:

您可以使用 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]]);
    }

【讨论】:

    【解决方案2】:

    编写旋转文本的最佳方法是围绕某个点(您希望文本的起点)旋转 pdf,然后编写它并将 pdf 文档旋转回来。 代码示例:

    doc.rotate(angle, { origin: [x,y] });
    doc.text( 'TEST', x, y);
    doc.rotate(angle * (-1), { origin: [x,y] });
    

    这样你就不需要计算新的位置了。

    另外值得知道的是,pdfkit 将我们文本的 x 和 y 作为我们文本“框”的左上角(在我的情况下确实很重要)。

    【讨论】:

      【解决方案3】:

      由于答案中描述的问题或事实,我把头发拉了一点。尝试了很多东西,但文本最终总是走自己的路。

      这是我用来将文本放置在不同方向的小剪辑。 该函数在旋转坐标系中计算新的 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,rotation 的文本数组。 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();
          });
      
      };
      

      首先旋转“世界”,然后将文本放置到与 (t.x,t.y) 相同的位置但在旋转世界中的新 (x,y)。

      【讨论】:

        【解决方案4】:

        没有什么特别的技巧,但正确理解如何在 PDFKit 中应用转换至关重要。

        要了解的主要一点是,您不会旋转文本或形状:您会旋转文档,正如doc.rotate(...).rect(...) 所暗示的那样。

        它可能会帮助您将文档视为具有物理属性的画布。它的特性之一是它的旋转。
        如果您想在一页纸上绘制旋转的文本,您可能会做的是物理旋转页面,然后像往常一样水平书写一些文本,然后将页面旋转回正常状态。
        那么你最终得到的是一个在直页上的旋转文本:

        这正是 PDFKit 的工作方式:您对文档应用转换,在转换后的上下文中绘制您需要绘制的所有内容,然后将文档恢复到之前的状态。

        要实现这一点,您有两种方法:doc.save()doc.restore()

        • 在应用转换之前使用save(),这样之前绘制的所有内容都不会受到影响。
        • 然后您可以变换画布并绘制所需的内容
        • 绘制完所有需要转换的内容后,调用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 度旋转的倍数时很容易处理,但否则你将不得不使用三角函数:)

        为了方便起见,您可以使用旋转的原点来确保您围绕一个对您的下一个绘图有意义的点旋转文档!

        【讨论】:

        • 最好是为此编写一个函数,然后:drawRotatedText (x,y, angle, text);。 (并将其添加到 PDFKit...)
        • 这是一个实现细节,但是是的:)
        • Rad Lexus,这是一个有趣的选项,问题是,我是 PDFKit 的新手,因此,我不确定如何继续。如果您想从中提出要点,请继续:)将不胜感激!
        猜你喜欢
        • 2022-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        相关资源
        最近更新 更多