Skip to content

几何变换 (HasTransforms)

HasTransforms trait 提供几何变换功能,用于改变后续绘图操作的渲染方式。变换作用于当前变换矩阵(Current Transformation Matrix, CTM),且必须包裹在 startTransform() / stopTransform() 配对中,以隔离其影响范围。

所有方法都返回 static,因此每个调用都可以链式串接。

速查表

方法效果
startTransform()保存图形状态(推入 CTM)
stopTransform()还原图形状态(弹出 CTM)
rotate()绕一个点旋转
scale()水平与垂直缩放
translate()移动坐标原点
skew()沿 X 轴与 Y 轴倾斜
mirrorH()水平镜射
mirrorV()垂直镜射
mirrorP()绕一个点镜射
mirrorL()绕任意直线镜射

基本示例

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->addPage()
    ->setFont('Helvetica', '', 12)

    // 旋转文字
    ->startTransform()
    ->rotate(45, 105, 60)
    ->text(100, 55, 'Rotated 45°')
    ->stopTransform()

    // 缩放矩形
    ->startTransform()
    ->scale(150, 150, 50, 150)
    ->rect(40, 140, 20, 20, 'DF')
    ->stopTransform()

    // 镜射文字
    ->startTransform()
    ->mirrorH(105)
    ->text(100, 200, 'Mirrored')
    ->stopTransform();

WARNING

变换必须包在 startTransform() / stopTransform() 配对中。忘记调用 stopTransform() 会导致图形状态被永久修改,影响所有后续的绘图操作。

startTransform / stopTransform

php
$pdf->startTransform();  // 推入当前的图形状态
// ... 包含变换的绘图操作 ...
$pdf->stopTransform();   // 弹出并还原先前的状态

这些调用可以嵌套使用。每次 startTransform() 都会将一个新状态推入栈。

rotate()

php
$pdf->rotate(float $angle, float $x = '', float $y = '');

将后续内容绕 (x, y) 点逆时针旋转 $angle 度。如果省略 x 和 y,则使用当前位置。

php
$pdf->startTransform()
    ->rotate(30, 105, 148)
    ->setFont('Helvetica', 'B', 16)
    ->text(90, 140, '旋转 30 度')
    ->stopTransform();

scale()

php
$pdf->scale(float $sx, float $sy, float $x = '', float $y = '');

以 (x, y) 为基准点,水平缩放 $sx 百分比、垂直缩放 $sy 百分比。100 表示不变,200 表示放大两倍。

php
$pdf->startTransform()
    ->scale(200, 200, 50, 80)       // 放大至 200%
    ->setFillColor(200, 220, 255)
    ->rect(40, 70, 20, 20, 'DF')
    ->stopTransform();

translate()

php
$pdf->translate(float $tx, float $ty);

将坐标原点水平移动 $tx、垂直移动 $ty。在变换停止之前,所有后续坐标都会偏移此量。

php
$pdf->startTransform()
    ->translate(50, 50)
    ->rect(0, 0, 30, 20, 'DF')     // 实际位置为 (50, 50)
    ->stopTransform();

skew()

php
$pdf->skew(float $angleX, float $angleY, float $x = '', float $y = '');

应用倾斜变换。$angleX 沿 X 轴倾斜,$angleY 沿 Y 轴倾斜,单位为度数。

php
$pdf->startTransform()
    ->skew(15, 0, 100, 100)
    ->rect(80, 80, 40, 30, 'DF')
    ->stopTransform();

镜射方法

php
$pdf->mirrorH(float $x = '');                              // 沿 x 处的垂直轴水平镜射
$pdf->mirrorV(float $y = '');                              // 沿 y 处的水平轴垂直镜射
$pdf->mirrorP(float $x = '', float $y = '');               // 绕一个点镜射
$pdf->mirrorL(float $angle, float $x = '', float $y = ''); // 绕通过 (x, y) 的任意直线镜射
php
// 水平镜射示例
$pdf->startTransform()
    ->mirrorH(105)
    ->setFont('Helvetica', '', 14)
    ->text(80, 50, '水平翻转的文字')
    ->stopTransform();

// 沿任意直线镜射
$pdf->startTransform()
    ->mirrorL(45, 105, 148)
    ->rect(80, 130, 40, 30, 'DF')
    ->stopTransform();

组合变换

在同一个区块中可以堆叠多个变换,它们会按照调用顺序依次应用。

php
$pdf->startTransform()
    ->translate(20, 20)
    ->rotate(30)
    ->scale(120, 120)
    ->rect(10, 10, 40, 20, 'DF')
    ->stopTransform();

TIP

变换的顺序很重要。先平移再旋转,与先旋转再平移,会产生截然不同的结果。一般来说,建议的顺序是:平移 → 旋转 → 缩放。

CTM 矩阵

对于进阶使用场景,可以直接访问底层的当前变换矩阵。六元素矩阵 [a, b, c, d, e, f] 对应标准的 PDF 变换矩阵,当便利方法不够用时,能提供对仿射变换的完全控制。

| a  b  0 |
| c  d  0 |     坐标变换公式:
| e  f  1 |     x' = a*x + c*y + e
                y' = b*x + d*y + f

各元素的对应关系如下:

元素功能
a, d水平与垂直缩放
b, c旋转与倾斜
e, f水平与垂直平移

以 LGPL-3.0-or-later 许可证发布。