К основному содержанию
скилл CX Codex

pixijs-html-source — скилл для Claude Code: HTML в текстуру PixiJS

Учит агента превращать живой DOM-элемент или его снимок в текстуру PixiJS v8 через экспериментальный HTML-in-Canvas.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add pixijs/pixijs-skills --skill pixijs-html-source -a claude-code
Открыть на GitHub

Что делает pixijs-html-source

Скилл описывает два класса из pixi.js/html-source: HTMLSource зеркалит пиксели живого элемента на GPU, а сам элемент остаётся редактируемым и кликабельным в браузере, ElementImageSource оборачивает неизменяемый снимок из captureElementImage(), который не перерисовывается. Оба — источники текстуры, а не объекты сцены: чтобы что-то появилось на экране, их оборачивают в Sprite, Texture или Mesh.

Внутри разобраны импорт pixi.js/html-source с регистрацией расширений и аплоадеров для WebGL и WebGPU, проверка поддержки через canvas.requestPaint, опции конструктора (autoLayout, autoUpdate, autoRequestPaint, autoClose), статический HTMLSource.defaultOptions, автоопределение через Texture.from с приоритетом -10 и очистка через destroy.

Главное ограничение: всё это опирается на экспериментальное предложение HTML-in-Canvas, и API может меняться между минорными релизами. Без включённого флага браузера аплоадер падает на первом рендере, поэтому проверяйте canvas.requestPaint заранее. Ещё элемент обязан быть прямым дочерним узлом канваса Pixi, иначе конструктор бросит исключение, а в Web Worker это не работает вообще — там нет DOM.

Какие задачи решает

  • вывести живую HTML-форму поверх сцены PixiJS и сохранить ввод
  • заморозить DOM-элемент в текстуру и натянуть её на Mesh
  • проверить поддержку HTML-in-Canvas до первого рендера
  • настроить перерисовку текстуры под анимацию вручную
  • корректно освободить снимок и источник после удаления спрайта

Примеры запросов агенту

  • Покажи, как вывести живой HTML-элемент как текстуру через HTMLSource
  • Сделай снимок элемента через captureElementImage и оберни в ElementImageSource
  • Проверь canvas.requestPaint и объясни, что делать, если API недоступно

Как установить pixijs-html-source

1Через Skills CLI (Vercel)

npx skills add pixijs/pixijs-skills --skill pixijs-html-source -a claude-code

2Вручную: положить файлы

~/.claude/skills/pixijs-html-source/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/pixijs-html-source/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о pixijs-html-source

Как установить pixijs-html-source в Claude?

Выполните npx skills add pixijs/pixijs-skills --skill pixijs-html-source -a claude-code. Скилл окажется в ~/.claude/skills/pixijs-html-source/SKILL.md.

Что делает pixijs-html-source?

Показывает агенту, как рендерить DOM-элементы в текстуры PixiJS v8: живой элемент через HTMLSource или неизменяемый снимок через ElementImageSource.

Почему текстура не появляется?

Скорее всего, браузер не поддерживает HTML-in-Canvas: без флага аплоадер бросает ошибку на первом рендере. Проверьте canvas.requestPaint и убедитесь, что элемент — прямой дочерний узел канваса.

Исходный текст

SKILL.md · MIT
---
name: pixijs-html-source
description: "Use this skill when rendering live HTML/DOM elements (or frozen snapshots of them) as PixiJS v8 textures via the EXPERIMENTAL HTML-in-Canvas browser APIs. Covers the pixi.js/html-source import, feature detection with canvas.requestPaint, HTMLSource for a live, repainting, still-interactive element (autoLayout/autoUpdate/autoRequestPaint, requestPaint, isReady, HTMLSource.defaultOptions, the direct-child-of-canvas + layoutsubtree requirement), ElementImageSource for an immutable captureElementImage() snapshot (autoClose, ready immediately), using the source on a Sprite/Texture/Mesh, fallback-only auto-detection via Texture.from at priority -10, uploader error messages, and destroy/cleanup. Triggers on: HTMLSource, ElementImageSource, ElementImage, HTML in canvas, render DOM to texture, render HTML to texture, texElementImage2D, copyElementImageToTexture, HTMLSourceOptions, ElementImageSourceOptions, HTMLSourceCanvas."
license: MIT
---

`HTMLSource` and `ElementImageSource` turn a DOM element into a `TextureSource` you can use anywhere a normal texture works: on a `Sprite`, as a `Texture` frame, or mapped onto a `Mesh`. `HTMLSource` mirrors a live element's pixels into the GPU (the element stays editable and clickable in the browser); `ElementImageSource` wraps an immutable snapshot that never repaints. Both live in `pixi.js/html-source`; importing from that path registers their extensions.

> These sources rely on the experimental HTML-in-Canvas browser proposal and are marked EXPERIMENTAL in PixiJS v8. The browser API must be enabled or the texture uploader throws on first render; feature-detect with `canvas.requestPaint` before relying on it. The API may change between minor releases.

Assumes familiarity with `pixijs-scene-sprite` and textures. These are texture *sources*, not display objects: wrap them in a `Sprite` (or `Texture`/`Mesh`) to put them on screen. Not available in Web Workers; a worker has no DOM to capture.

## Quick Start

```ts
import { Application, Sprite } from "pixi.js";
import { HTMLSource } from "pixi.js/html-source";

const app = new Application();
await app.init({ resizeTo: window });
document.body.appendChild(app.canvas);

// The element must be a direct child of the Pixi canvas.
const form = document.createElement("form");
form.innerHTML = '<input value="still editable" />';
app.canvas.appendChild(form);

// Render the live form as a sprite. It stays interactive in the browser.
const source = new HTMLSource({ resource: form });
const sprite = Sprite.from(source);

sprite.anchor.set(0.5);
sprite.position.set(app.screen.width / 2, app.screen.height / 2);
app.stage.addChild(sprite);
```

**Related skills:** `pixijs-scene-sprite` (display the texture), `pixijs-scene-mesh` (map onto geometry, `PerspectiveMesh`), `pixijs-scene-dom-container` (the opposite: overlay HTML *above* the canvas, outside the GPU pipeline), `pixijs-assets` (texture sources vs the loader/cache), `pixijs-environments` (no DOM in Web Workers).

## Constructor options

Both sources extend `TextureSource`, so all `TextureSourceOptions` (`resolution`, `scaleMode`, `addressMode`, `label`, etc.) are valid. `resource` is required on each.

`HTMLSourceOptions` (live element):

| Option             | Type               | Default | Description                                                                                                                                              |
| ------------------ | ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `resource`         | `Element`          | —       | Required. The live DOM element to render. Must be a direct child of the owning canvas, or the constructor throws.                                         |
| `canvas`           | `HTMLSourceCanvas` | —       | The canvas that owns the element's layout subtree. Inferred from `resource.parentElement` when the element is a direct canvas child; pass it when inference is not possible. |
| `autoLayout`       | `boolean`          | `true`  | Set the `layoutsubtree` attribute on the owning canvas. The browser only lays out and paints canvas children when it is present. Set `false` if you write `<canvas layoutsubtree>` yourself. |
| `autoUpdate`       | `boolean`          | `true`  | Listen for the canvas `paint` event and re-upload when the element repaints. Set `false` for a static, captured-once texture.                             |
| `autoRequestPaint` | `boolean`          | `true`  | Request one initial paint after construction. Set `false` and call `source.requestPaint()` yourself each frame for continuous animation.                  |

`ElementImageSourceOptions` (immutable snapshot):

| Option       | Type           | Default | Description                                                                                                                            |
| ------------ | -------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `resource`   | `ElementImage` | —       | Required. A snapshot from `canvas.captureElementImage(element)`.                                                                        |
| `autoClose`  | `boolean`      | `false` | Call `snapshot.close()` when the source is destroyed. Leave `false` when the snapshot is shared with other sources, or you risk a use-after-free. |

Change the defaults for every `HTMLSource` through the static `HTMLSource.defaultOptions` object, for example `HTMLSource.defaultOptions.autoUpdate = false`.

## Core Patterns

### Setup and the side-effect import

```ts
import "pixi.js/html-source";
import { HTMLSource, ElementImageSource } from "pixi.js/html-source";
```

`pixi.js/html-source` calls `extensions.add(...)` to register `HTMLSource`, `ElementImageSource`, and their WebGL/WebGPU uploaders. Without it, the renderer has no `'html'` uploader and these sources never render. The classes are exported from `pixi.js/html-source`, not `pixi.js`.

Importing a named export from `pixi.js/html-source` also triggers the side effect, so a bare `import 'pixi.js/html-source'` is only needed when you don't import anything else from that path.

### Feature detection and browser support

The HTML-in-Canvas API is gated behind a browser flag. Feature-detect before relying on it:

```ts
import type { HTMLSourceCanvas } from "pixi.js/html-source";

const canvas = app.canvas as HTMLSourceCanvas;

if (canvas.requestPaint) {
  // HTML-in-Canvas is available.
}
```

Cast `app.canvas` to `HTMLSourceCanvas` for the typed `requestPaint` and `captureElementImage` members. `source.requestPaint()` returns `false` when the browser lacks the API; the texture uploader throws on first render when it is disabled.

When the API is missing the first upload throws `[HTMLSource] WebGLRenderingContext.texElementImage2D is not available...` on WebGL or `[HTMLSource] GPUQueue.copyElementImageToTexture is not available...` on WebGPU.

### Live element with HTMLSource

```ts
const form = document.createElement("form");
app.canvas.appendChild(form); // direct child of the canvas

const source = new HTMLSource({ resource: form });
const sprite = Sprite.from(source);
```

The element must be a direct child of the renderer's `<canvas>`; the source infers the owning canvas from `resource.parentElement` (or pass `canvas`). With the defaults, it sets `layoutsubtree` on the canvas, listens for the canvas `paint` event, and requests one initial paint. `source.isReady` is `false` until that first paint lands, then `true`. It is `true` immediately when `autoUpdate` is `false`. `resourceWidth`/`resourceHeight` report the element's real-pixel size (`offsetWidth`/`offsetHeight`).

### Continuous animation with requestPaint

```ts
const source = new HTMLSource({ resource: clock, autoRequestPaint: false });
const sprite = Sprite.from(source);

app.ticker.add(() => {
  clock.textContent = new Date().toLocaleTimeString();
  source.requestPaint(); // re-snapshot the DOM this frame
});
```

The browser only repaints canvas children on demand. For an element whose content changes every frame, set `autoRequestPaint: false` and call `source.requestPaint()` in your own ticker to drive repaints on your schedule.

### Immutable snapshot with ElementImageSource

```ts
import { ElementImageSource } from "pixi.js/html-source";
import type { HTMLSourceCanvas } from "pixi.js/html-source";

const canvas = app.canvas as HTMLSourceCanvas;
const snapshot = canvas.captureElementImage!(element);

const source = new ElementImageSource({ resource: snapshot, autoClose: true });
const sprite = Sprite.from(source);
```

`captureElementImage()` freezes an element's current pixels into an immutable `ElementImage`. There is no owning canvas, no `paint` listener, and no repaint lifecycle, so the source is ready the moment it is constructed. Reach for it when you need a frozen copy that outlives its element or is transferred around (transitions, "shatter" or trail effects). Release the snapshot with `snapshot.close()` when done, or pass `autoClose: true` to let the source close it on `destroy()`.

### Using the source on a sprite, texture, or mesh

Both sources are normal `TextureSource`s. Wrap them with `Sprite.from(source)` / `Texture.from(source)`, frame or slice them into sub-textures, or map them onto a mesh:

```ts
import { Rectangle, Texture } from "pixi.js";

// A 64x64 slice of the rendered element.
const chunk = new Texture({
  source,
  frame: new Rectangle(0, 0, 64, 64),
});

// Mapped onto geometry (e.g. a perspective warp).
const mesh = new PerspectiveMesh({ texture: Texture.from(source) /* ... */ });
```

### Auto-detection and priority

```ts
// Resolves to an HTMLSource (element) or ElementImageSource (snapshot) only as a last resort.
const sprite = Sprite.from(elementAlreadyInTheCanvas);
```

A generic HTML element or an `ElementImage` passed to `Texture.from`/`Sprite.from` resolves to these sources at the lowest texture-source priority (`-10`), so they only claim a resource no other built-in source handles. Image, video, and canvas elements are deliberately rejected; they have dedicated, faster sources. Construct the source explicitly when you need options (`autoUpdate`, `autoClose`) or non-HTML elements such as SVG.

## Common Mistakes

### [HIGH] Importing from pixi.js instead of pixi.js/html-source

Wrong:

```ts
import { HTMLSource } from "pixi.js"; // not exported from the core entry
```

Correct:

```ts
import { HTMLSource } from "pixi.js/html-source";
```

`HTMLSource`, `ElementImageSource`, and the `'html'` uploaders live only in `pixi.js/html-source`. Importing anything from that path registers the extensions; the module is marked side-effectful, so bundlers keep the registration even when you only import a class.

### [HIGH] Assuming the browser API is enabled

The HTML-in-Canvas proposal is not shipped by default. If the API is disabled, the uploader throws on first render. Feature-detect first:

```ts
const canvas = app.canvas as HTMLSourceCanvas;
if (!canvas.requestPaint) {
  // Fall back to a static image, DOMContainer overlay, or a message.
}
```

### [MEDIUM] Element not a direct child of the canvas

```ts
document.body.appendChild(form); // wrong parent
const source = new HTMLSource({ resource: form }); // throws
```

`HTMLSource` requires the element to be a direct child of the owning canvas (`app.canvas.appendChild(form)`) and throws otherwise. Append the element to the canvas before constructing the source, or pass the `canvas` option.

### [MEDIUM] Expecting a live element to update without requestPaint

A non-animating element updates automatically on browser `paint` events (`autoUpdate: true`). Content that changes every frame will not re-upload unless something triggers a paint; drive it with `source.requestPaint()` each frame (with `autoRequestPaint: false`).

### [MEDIUM] Closing an ElementImage still in use

```ts
const source = new ElementImageSource({ resource: snapshot, autoClose: true });
const other = new ElementImageSource({ resource: snapshot }); // shares the snapshot

source.destroy(); // closes the snapshot — `other` is now a use-after-free
```

Only set `autoClose: true` when the source owns the snapshot exclusively. For a shared snapshot, leave `autoClose` off and call `snapshot.close()` once, after the last source is destroyed.

## Cleanup

```ts
source.destroy();
```

`HTMLSource.destroy()` detaches the canvas `paint` listener and nulls its canvas reference. `ElementImageSource.destroy()` closes the snapshot when `autoClose` was set; otherwise call `snapshot.close()` yourself to release the memory.

## API Reference

- [HTMLSource](https://pixijs.download/release/docs/rendering.HTMLSource.html.md)
- [HTMLSourceOptions](https://pixijs.download/release/docs/rendering.HTMLSourceOptions.html.md)
- [ElementImageSource](https://pixijs.download/release/docs/rendering.ElementImageSource.html.md)
- [ElementImageSourceOptions](https://pixijs.download/release/docs/rendering.ElementImageSourceOptions.html.md)
- [HTMLSourceCanvas](https://pixijs.download/release/docs/rendering.HTMLSourceCanvas.html.md)
- [ElementImage](https://pixijs.download/release/docs/rendering.ElementImage.html.md)

© pixijs · MIT · pixijs/pixijs-skills

Похожие скиллы

Всё по теме «Фронтенд и UI» →
pixijs-2d freshtechbro Скилл обучает агента создавать 2D-графику на PixiJS с WebGL и WebGPU: анимировать спрайты, выводить частицы и рисовать векторные фигуры на холсте. CX Codex +1 2 500установок html-diagram plannotator Генерирует автономные интерактивные HTML-диаграммы без сторонних сервисов и сборки. Пригодится, когда нужно визуализировать топологию, состояния, таймлайн или архитектуру проекта. CX Codex +1 4 100установок pixijs-rendering gamedev-skills Скилл для сборки слоя рендера на PixiJS v8: асинхронный Application, загрузка текстур, сцена на Container, тикер и события указателя. CX Codex +1 5 400установок threejs-textures CloudAI-X Скилл помогает настраивать загрузку изображений, цветовые пространства и типы текстур в Three.js r186. Пригодится при сборке материалов для WebGL или WebGPU. CX Codex +1 12 600установок threejs-loaders calesthio Скилл для работы с Three.js: загружает GLTF-модели, текстуры, HDR-среды и управляет прогрессом загрузки через LoadingManager. Пригодится, если в проекте нужно добавить 3D-сцены или работать с моделями из Blender. CX Codex +1 1 000установок globe-particles MengTo Создаёт трёхмерную визуализацию сферы и орбитального кольца из светящихся частиц на WebGL и Three.js. Пригодится для космических тем и витрин данных. CX Codex +1 1 400установок

Из того же набора25

pixijs-scene-dom-container Подсказывает агенту, как накладывать HTML-элементы на canvas PixiJS v8 через DOMContainer и DOMPipe. Пригодится, когда нужны поля ввода, iframe или видео поверх сцены. CX Codex +1 5 700установок pixijs-blend-modes Скилл подсказывает агенту, как смешивать объекты PixiJS v8 через blendMode: стандартные режимы, продвинутые и порядок для батчинга. CX Codex +1 5 700установок pixijs-color Скилл по классу Color в PixiJS v8. Помогает переводить форматы цвета, настраивать tint и альфу, а также оптимизировать вызовы в циклах рендера через Color.shared и буферы. CX Codex +1 5 700установок pixijs-create Скилл ведёт агента через создание нового проекта PixiJS v8 или подключение библиотеки к уже существующему: шаблоны, пакетные менеджеры, настройка TypeScript. CX Codex +1 5 700установок pixijs-custom-rendering Помогает писать кастомные шейдеры, юниформы, фильтры и батчеры в PixiJS v8 — на GLSL и WGSL, под WebGL и WebGPU. CX Codex +1 5 700установок pixijs-scene-gif Обучает агента загружать и воспроизводить анимации GIF в PixiJS v8 через GifSprite и GifSource. Пригодится при переносе гифок на сцену без ручной нарезки на спрайты. CX Codex +1 5 600установок pixijs-accessibility Скилл настраивает поддержку скринридеров и навигацию с клавиатуры в PixiJS v8 через оверлей shadow DOM. CX Codex +1 5 500установок pixijs-migration-v8 Скилл проводит код PixiJS с v7 на v8 и ищет типичные поломки после обновления. Нужен при замене устаревших API и импортов. CX Codex +1 5 300установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой