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 授權釋出。