Перейти к содержимому

Отрисовка градиентов, прозрачность и режимы наложения

Залейте область двухточечным осевым (линейным) или радиальным градиентом. Затем скомпонуйте перекрывающиеся фигуры с постоянной прозрачностью и при необходимости с режимом наложения. Код соответствует examples/25-gradients.php и examples/20-transparency.php.

Градиент — это затенение ISO 32000-2. linearGradient() создаёт затенение Type 2 (осевое), а radialGradient() — затенение Type 3 (радиальное). Прозрачность использует константу прозрачности графического состояния. setAlpha() задаёт значение ca для заливки и значение CA для обводки.

Окно терминала
composer require nextpdf/core:^3

Дополнительные расширения не требуются. API градиентов, прозрачности и режимов наложения стабилен начиная с 1.0.0 и работает в матрице бэкпорта 8.1–8.4.

linearGradient(x, y, w, h, start, end) отрисовывает цветовой переход вдоль оси прямоугольника между двумя точками Color. ISO 32000-2 определяет Coords осевого затенения как [x0 y0 x1 y1]. Если конечные точки совпадают, ничего не отрисовывается. radialGradient(...) создаёт переход между двумя окружностями. Радиальный Coords — это [x0 y0 r0 x1 y1 r1]; оба радиуса должны быть ≥ 0.

setAlpha($alpha, $mode) задаёт постоянную непрозрачность для последующей отрисовки. Первый аргумент — константа прозрачности (ca/CA). Второй аргумент задаёт режим наложения (BM в модели прозрачной визуализации). Сбросьте прозрачность до 1.0, а режим наложения — до Normal, прежде чем рисовать независимое содержимое.

Поверхность API генерируется из PHPDoc. В этом рецепте используются следующие методы:

  • linearGradient(float $x, float $y, float $w, float $h, Color $start, Color $end): static
  • radialGradient(float $x, float $y, float $w, float $h, Color $start, Color $end): static
  • setAlpha(float $alpha, BlendMode $mode = BlendMode::Normal): static
  • Color::rgb(int $r, int $g, int $b), Color::white(), Color::black() задают точки градиента.
  • setFillColor(...) задаёт цвет, к которому затем применяются прозрачность и режим наложения.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
use NextPDF\Graphics\BlendMode;
use NextPDF\Graphics\Color;
$doc = Document::createStandalone();
$doc->addPage();
// Axial gradient: blue -> white across a 190 x 40 box.
$doc->linearGradient(10, 30, 190, 40, Color::rgb(30, 58, 138), Color::white());
// Two overlapping rectangles at 70% opacity with Multiply blend.
$doc->setAlpha(0.7, BlendMode::Multiply);
$doc->setFillColor(220, 38, 38);
$doc->rect(20, 90, 60, 40, 'F');
$doc->setFillColor(37, 99, 235);
$doc->rect(50, 90, 60, 40, 'F');
$doc->setAlpha(1.0, BlendMode::Normal); // reset
$doc->save(getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/gradients.pdf');

Это полный пример, готовый для запуска в тестовой обвязке. Он учитывает NEXTPDF_COOKBOOK_OUTPUT и не добавляет собственной энтропии.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
use NextPDF\Graphics\BlendMode;
use NextPDF\Graphics\Color;
$doc = Document::createStandalone();
$doc->setTitle('Gradients and Transparency');
$doc->addPage();
$doc->setFont('helvetica', 'B', 18);
$doc->cell(0, 12, 'Gradients and Transparency', newLine: true);
$doc->ln(4);
// 1. Axial gradient — blue to white.
$doc->setFont('helvetica', 'B', 12);
$doc->cell(0, 8, '1. Axial gradient', newLine: true);
$doc->ln(2);
$doc->linearGradient(
x: 10, y: $doc->getY(), w: 190, h: 40,
start: Color::rgb(30, 58, 138), end: Color::white(),
);
$doc->ln(44);
// 2. Radial gradient — red centre fading to white.
$doc->setFont('helvetica', 'B', 12);
$doc->cell(0, 8, '2. Radial gradient', newLine: true);
$doc->ln(2);
$doc->radialGradient(
x: 50, y: $doc->getY(), w: 110, h: 55,
start: Color::rgb(220, 38, 38), end: Color::white(),
);
$doc->ln(59);
// 3. Constant alpha + blend mode over a light backdrop.
$doc->setFont('helvetica', 'B', 12);
$doc->cell(0, 8, '3. Alpha 0.7 with Multiply blend', newLine: true);
$doc->ln(2);
$baseY = $doc->getY();
$doc->setAlpha(1.0, BlendMode::Normal);
$doc->setFillColor(245, 245, 245);
$doc->rect(15, $baseY, 90, 40, 'F');
$doc->setAlpha(0.7, BlendMode::Multiply);
$doc->setFillColor(220, 38, 38);
$doc->rect(20, $baseY + 5, 40, 30, 'F');
$doc->setFillColor(37, 99, 235);
$doc->rect(40, $baseY + 5, 40, 30, 'F');
// Always reset compositing state before continuing.
$doc->setAlpha(1.0, BlendMode::Normal);
$doc->setFillColor(255);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: __DIR__ . '/gradients.pdf';
$doc->save($out);
echo "Created gradients.pdf\n";
  • Совпадающие конечные точки градиента ничего не отрисовывают. Прямоугольник нулевого размера, из-за которого w или h схлопывает ось, даёт пустое осевое затенение согласно ISO 32000-2. Убедитесь, что у прямоугольника есть протяжённость.
  • Радиусы должны быть неотрицательными. Передача отрицательного радиуса в radialGradient() недопустима. Два нулевых радиуса ничего не отрисовывают.
  • Прозрачность сохраняется между отрисовками. setAlpha(0.7, …) остаётся в силе для каждой последующей операции отрисовки, пока вы её не сбросите. Восстановите setAlpha(1.0, BlendMode::Normal) после прозрачного блока, иначе последующее содержимое будет выглядеть блёклым.
  • Режиму наложения нужна подложка. Режим наложения, такой как Multiply или Screen, компонует новое содержимое поверх уже нарисованного. На пустой странице эффект не виден, поэтому сначала нарисуйте подложку.
  • Форма массива режимов наложения в PDF 2.0 устарела. NextPDF создаёт одно имя режима наложения — это форма PDF 2.0. Спецификация объявляет устаревшей унаследованную форму массива.

Градиент — это один объект затенения плюс заливка. Прозрачность и режим наложения — это параметры графического состояния. Каждый из них даёт постоянные затраты на одно использование, и оба укладываются в бюджет 2000 мс / 64 МБ. Растеризация не выполняется, поэтому градиенты остаются затенениями, не зависящими от разрешения.

Этот рецепт отрисовывает только ту геометрию и цвета, которые предоставляет ваш код. Он не разбирает входные данные и не обращается к сети. Проверяйте значения цвета и координат перед использованием, если они получены из недоверенных данных.

УтверждениеСпецификацияПунктreference_id (идентификатор ссылки)
ShadingType 2 — осевой, 3 — радиальный.ISO 32000-2§8.7.4.3
Осевой Coords — это [x0 y0 x1 y1]; совпадающие конечные точки ничего не отрисовывают.ISO 32000-2§8.7.4.5.3
Радиальный Coords — это [x0 y0 r0 x1 y1 r1]; радиусы ≥ 0.ISO 32000-2§8.7.4.5.4
CA/ca — это константы прозрачности для stroking/non-stroking.ISO 32000-2§8.4.5
BM — это текущий режим наложения.ISO 32000-2§11.3.5

Профиль воспроизводимости — структурный. /ID трейлера и атомы даты меняются при каждом сохранении. Тестовая обвязка удаляет эти атомы, затем сравнивает нормализованную qpdf структуру. Этот рецепт описывает, как NextPDF формирует эту структуру. Он не делает безоговорочного заявления о соответствии ISO 32000-2.

Неприменимо. Градиенты, прозрачность и режимы наложения — это возможности Core. Для них не требуется уровень Premium.