pixijs-html-source
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHTMLSourceElementImageSourceTextureSourceSpriteTextureMeshHTMLSourceElementImageSourceimport 'pixi.js/html-source'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 withbefore relying on it. The API may change between minor releases.canvas.requestPaint
Assumes familiarity with and textures. These are texture sources, not display objects: wrap them in a (or /) to put them on screen. Not available in Web Workers; a worker has no DOM to capture.
pixijs-scene-spriteSpriteTextureMeshHTMLSourceElementImageSourceTextureSourceSpriteTextureMeshHTMLSourceElementImageSourceimport 'pixi.js/html-source'这些源依赖于实验性的HTML-in-Canvas浏览器提案,在PixiJS v8中被标记为EXPERIMENTAL。必须启用浏览器API,否则纹理上传器会在首次渲染时抛出错误;在使用前请通过进行特性检测。该API可能在小版本更新中发生变化。canvas.requestPaint
本文假设你已熟悉 和纹理相关知识。这些是纹理源,而非显示对象:需要将它们包装在 (或 /)中才能显示在屏幕上。Web Workers中无法使用此功能;因为Worker没有可捕获的DOM。
pixijs-scene-spriteSpriteTextureMeshQuick Start
快速开始
ts
import "pixi.js/html-source";
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: (display the texture), (map onto geometry, ), (the opposite: overlay HTML above the canvas, outside the GPU pipeline), (texture sources vs the loader/cache), (no DOM in Web Workers).
pixijs-scene-spritepixijs-scene-meshPerspectiveMeshpixijs-scene-dom-containerpixijs-assetspixijs-environmentsts
import "pixi.js/html-source";
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);
// 元素必须是Pixi画布的直接子元素。
const form = document.createElement("form");
form.innerHTML = '<input value="still editable" />';
app.canvas.appendChild(form);
// 将实时表单渲染为精灵。它在浏览器中仍保持交互性。
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);相关技能: (显示纹理)、(映射到几何体,如)、(相反操作:在画布上方叠加HTML,脱离GPU管线)、(纹理源与加载器/缓存的对比)、(Web Workers中无DOM)。
pixijs-scene-spritepixijs-scene-meshPerspectiveMeshpixijs-scene-dom-containerpixijs-assetspixijs-environmentsConstructor options
构造函数选项
Both sources extend , so all (, , , , etc.) are valid. is required on each.
TextureSourceTextureSourceOptionsresolutionscaleModeaddressModelabelresourceHTMLSourceOptions| Option | Type | Default | Description |
|---|---|---|---|
| | — | Required. The live DOM element to render. Must be a direct child of the owning canvas, or the constructor throws. |
| | — | The canvas that owns the element's layout subtree. Inferred from |
| | | Set the |
| | | Listen for the canvas |
| | | Request one initial paint after construction. Set |
ElementImageSourceOptions| Option | Type | Default | Description |
|---|---|---|---|
| | — | Required. A snapshot from |
| | | Call |
两个源都继承自 ,因此所有 (、、、等)均有效。每个源都必须指定参数。
TextureSourceTextureSourceOptionsresolutionscaleModeaddressModelabelresourceHTMLSourceOptions| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| | — | 必填项。要渲染的实时DOM元素。必须是所属画布的直接子元素,否则构造函数会抛出错误。 |
| | — | 拥有元素布局子树的画布。当元素是画布的直接子元素时,会从 |
| | | 在所属画布上设置 |
| | | 监听画布的 |
| | | 构造完成后请求一次初始绘制。如果需要连续动画,请设置为 |
ElementImageSourceOptions| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| | — | 必填项。来自 |
| | | 当源被销毁时调用 |
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-sourceextensions.add(...)HTMLSourceElementImageSource'html'pixi.js/html-sourcepixi.jsImporting a named export from also triggers the side effect, so a bare is only needed when you don't import anything else from that path.
pixi.js/html-sourceimport 'pixi.js/html-source'ts
import "pixi.js/html-source";
import { HTMLSource, ElementImageSource } from "pixi.js/html-source";pixi.js/html-sourceextensions.add(...)HTMLSourceElementImageSource'html'pixi.js/html-sourcepixi.js从导入命名导出也会触发副作用,因此只有当你不从该路径导入其他内容时,才需要单独导入。
pixi.js/html-sourceimport 'pixi.js/html-source'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 to for the typed and members. returns when the browser lacks the API; the texture uploader throws on first render when it is disabled.
app.canvasHTMLSourceCanvasrequestPaintcaptureElementImagesource.requestPaint()falseHTML-in-Canvas API受浏览器标志限制。在使用前请先进行特性检测:
ts
import type { HTMLSourceCanvas } from "pixi.js/html-source";
const canvas = app.canvas as HTMLSourceCanvas;
if (canvas.requestPaint) {
// HTML-in-Canvas可用。
}将转换为类型,以获取带类型的和成员。当浏览器不支持该API时,会返回;如果API被禁用,纹理上传器会在首次渲染时抛出错误。
app.canvasHTMLSourceCanvasrequestPaintcaptureElementImagesource.requestPaint()falseLive element with HTMLSource
使用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 ; the source infers the owning canvas from (or pass ). With the defaults, it sets on the canvas, listens for the canvas event, and requests one initial paint. is until that first paint lands, then . / report the element's real-pixel size (/).
<canvas>resource.parentElementcanvaslayoutsubtreepaintsource.isReadyfalsetrueresourceWidthresourceHeightoffsetWidthoffsetHeightts
const form = document.createElement("form");
app.canvas.appendChild(form); // 画布的直接子元素
const source = new HTMLSource({ resource: form });
const sprite = Sprite.from(source);元素必须是渲染器的直接子元素;源会从推断所属画布(或者手动传入参数)。默认情况下,它会在画布上设置,监听画布的事件,并请求一次初始绘制。在首次绘制完成前为,之后变为。/会返回元素的实际像素尺寸(/)。
<canvas>resource.parentElementcanvaslayoutsubtreepaintsource.isReadyfalsetrueresourceWidthresourceHeightoffsetWidthoffsetHeightContinuous animation with requestPaint
使用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 and call in your own ticker to drive repaints on your schedule.
autoRequestPaint: falsesource.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(); // 本帧重新快照DOM
});浏览器仅会按需重绘画布子元素。对于内容每一帧都变化的元素,请设置,并在自己的ticker中调用来按你的计划驱动重绘。
autoRequestPaint: falsesource.requestPaint()Immutable snapshot with ElementImageSource
使用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()ElementImagepaintsnapshot.close()autoClose: truedestroy()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()ElementImagepaintsnapshot.close()autoClose: truedestroy()Using the source on a sprite, texture, or mesh
在精灵、纹理或网格上使用源
Both sources are normal s. Wrap them with / , frame or slice them into sub-textures, or map them onto a mesh:
TextureSourceSprite.from(source)Texture.from(source)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) /* ... */ });两个源都是标准的。可以用 / 包装它们,将其裁剪为子纹理,或者映射到网格上:
TextureSourceSprite.from(source)Texture.from(source)ts
import { Rectangle, Texture } from "pixi.js";
// 渲染元素的64x64切片。
const chunk = new Texture({
source,
frame: new Rectangle(0, 0, 64, 64),
});
// 映射到几何体上(如透视扭曲)。
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 passed to / resolves to these sources at the lowest texture-source priority (), 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 (, ) or non-HTML elements such as SVG.
ElementImageTexture.fromSprite.from-10autoUpdateautoClosets
// 仅作为最后手段,解析为HTMLSource(元素)或ElementImageSource(快照)。
const sprite = Sprite.from(elementAlreadyInTheCanvas);传递给/的通用HTML元素或会以最低的纹理源优先级()解析为这些源,因此它们仅会处理其他内置源无法处理的资源。图片、视频和画布元素会被刻意排除;它们有专门的、更快的源。当你需要自定义选项(、)或处理SVG等非HTML元素时,请显式构造源。
Texture.fromSprite.fromElementImage-10autoUpdateautoCloseCommon Mistakes
常见错误
[HIGH] Not importing pixi.js/html-source
[高风险] 未导入pixi.js/html-source
Wrong:
ts
import { HTMLSource } from "pixi.js/html-source";
// ...but never importing the side effect, in a build that tree-shakes it awayCorrect:
ts
import "pixi.js/html-source";
import { HTMLSource } from "pixi.js/html-source";The uploaders are registered by the side-effect import. Without it, the source has no uploader and the texture never renders.
'html'错误写法:
ts
import { HTMLSource } from "pixi.js/html-source";
// ...但从未导入副作用模块,且构建时被摇树优化移除正确写法:
ts
import "pixi.js/html-source";
import { HTMLSource } from "pixi.js/html-source";'html'[HIGH] Assuming the browser API is enabled
[高风险] 假设浏览器API已启用
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.
}HTML-in-Canvas提案尚未默认启用。如果API被禁用,上传器会在首次渲染时抛出错误。请先进行特性检测:
ts
const canvas = app.canvas as HTMLSourceCanvas;
if (!canvas.requestPaint) {
// 回退到静态图片、DOMContainer叠加层或提示信息。
}[MEDIUM] Element not a direct child of the canvas
[中风险] 元素不是画布的直接子元素
ts
document.body.appendChild(form); // wrong parent
const source = new HTMLSource({ resource: form }); // throwsHTMLSourceapp.canvas.appendChild(form)canvasts
document.body.appendChild(form); // 错误的父元素
const source = new HTMLSource({ resource: form }); // 抛出错误HTMLSourceapp.canvas.appendChild(form)canvas[MEDIUM] Expecting a live element to update without requestPaint
[中风险] 期望实时元素在未调用requestPaint的情况下自动更新
A non-animating element updates automatically on browser events (). Content that changes every frame will not re-upload unless something triggers a paint; drive it with each frame (with ).
paintautoUpdate: truesource.requestPaint()autoRequestPaint: false非动画元素会在浏览器事件中自动更新()。内容每一帧都变化的元素不会自动重新上传,除非有触发绘制的操作;请在每一帧调用(配合)来驱动更新。
paintautoUpdate: truesource.requestPaint()autoRequestPaint: false[MEDIUM] Closing an ElementImage still in use
[中风险] 关闭仍在使用的ElementImage
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-freeOnly set when the source owns the snapshot exclusively. For a shared snapshot, leave off and call once, after the last source is destroyed.
autoClose: trueautoClosesnapshot.close()ts
const source = new ElementImageSource({ resource: snapshot, autoClose: true });
const other = new ElementImageSource({ resource: snapshot }); // 共享快照
source.destroy(); // 关闭快照 —— `other`现在会出现使用已释放资源的问题只有当源独占快照时,才设置。对于共享快照,请保持为,并在最后一个源销毁后调用。
autoClose: trueautoClosefalsesnapshot.close()Cleanup
清理
ts
source.destroy();HTMLSource.destroy()paintElementImageSource.destroy()autoClosesnapshot.close()ts
source.destroy();HTMLSource.destroy()paintautoCloseElementImageSource.destroy()snapshot.close()