You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决jsPDF中addImage与addText旋转后位置偏移问题?

解决jsPDF旋转图像/文本时的位置偏移问题

jsPDF里旋转图像或文本时出现位置偏移,核心原因是它的旋转操作基于当前坐标系原点(默认是文档左上角),旋转后元素的位置计算会因为坐标系旋转而偏离预期。以下是具体的修正方法:

旋转图像的处理步骤

用坐标系平移+状态保存的方式,让图像旋转后精准落在目标位置:

const doc = new jsPDF();
const imgElement = document.getElementById('target-img');
// 目标位置的坐标与图像尺寸
const targetX = 100;
const targetY = 100;
const imgWidth = 50;
const imgHeight = 50;
const rotateAngle = 45;

// 保存当前坐标系状态,避免影响后续绘制
doc.save();
// 将坐标系原点平移到图像的中心位置
doc.translate(targetX + imgWidth/2, targetY + imgHeight/2);
// 旋转坐标系
doc.rotate(rotateAngle, { origin: 'center' });
// 以新原点为中心绘制图像,左上角坐标设为负的半宽半高
doc.addImage(imgElement, 'PNG', -imgWidth/2, -imgHeight/2, imgWidth, imgHeight);
// 恢复之前的坐标系状态
doc.restore();

这种方法通过把原点移到图像中心,旋转后绘制时让图像中心对齐原目标点,彻底避免偏移。

旋转文本的处理步骤

文本旋转的偏移问题同样用坐标系平移解决,或者结合文本对齐属性精准控制:

方法一:坐标系平移法

const doc = new jsPDF();
const textContent = '旋转测试文本';
const targetX = 100;
const targetY = 100;
const rotateAngle = 45;

doc.save();
// 平移原点到文本的锚点位置(这里是文本中心)
doc.translate(targetX, targetY);
// 旋转坐标系
doc.rotate(rotateAngle);
// 以新原点为中心绘制文本,设置对齐方式
doc.text(textContent, 0, 0, { align: 'center', baseline: 'middle' });
doc.restore();

方法二:坐标修正法

如果不想改变坐标系,可以用三角函数计算旋转后的偏移量,直接调整文本起始坐标:

const doc = new jsPDF();
const textContent = '旋转测试文本';
const targetX = 100;
const targetY = 100;
const rotateAngle = 45;

const angleRad = rotateAngle * Math.PI / 180;
const textWidth = doc.getTextWidth(textContent);
// 计算修正后的坐标,让文本中心落在目标点
const correctedX = targetX - (textWidth * Math.cos(angleRad)) / 2;
const correctedY = targetY + (textWidth * Math.sin(angleRad)) / 2;

doc.text(textContent, correctedX, correctedY, { angle: rotateAngle });

关键注意事项

  • 每次旋转操作前后务必用save()和restore()包裹,防止坐标系状态混乱影响后续内容绘制
  • 优先选择坐标系平移的方式,比手动计算偏移量更直观、不易出错
  • 对于文本,配合align和baseline属性可以更灵活地控制旋转后的锚点位置

内容的提问来源于stack exchange,提问作者Deimos Dreik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 21:32:33