[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7CSSG2FZDNREG7NJN2C0RMF":3,"skill-same:01M7CSSG2FZDNREG7NJN2C0RMF":52},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":27,"repositoryHtmlUrl":28,"repositoryHomepageUrl":6,"ownerHtmlUrl":29,"ownerBlogUrl":6,"ownerDescription":30,"updatedAt":31,"install":32,"resources":45},"01M7CSSG2FZDNREG7NJN2C0RMF","pixijs-html-source",null,"Use this skill when rendering live HTML\u002FDOM elements (or frozen snapshots of them) as PixiJS v8 textures via the EXPERIMENTAL HTML-in-Canvas browser APIs. Covers the pixi.js\u002Fhtml-source side-effect import, feature-detection with canvas.requestPaint, HTMLSource for a live, repainting element kept interactive in the browser (autoLayout\u002FautoUpdate\u002FautoRequestPaint, requestPaint, isReady, the direct-child-of-canvas + layoutsubtree requirement), ElementImageSource for an immutable captureElementImage() snapshot (autoClose, ready immediately), using the source on a Sprite\u002FTexture\u002FMesh, fallback-only auto-detection via Texture.from at priority -10, and destroy\u002Fcleanup. Triggers on: HTMLSource, ElementImageSource, pixi.js\u002Fhtml-source, requestPaint, captureElementImage, ElementImage, layoutsubtree, autoRequestPaint, autoUpdate, autoClose, HTML in canvas, render DOM to texture, HTMLSourceOptions, ElementImageSourceOptions, HTMLSourceCanvas, experimental.","om-scogo\u002Fskillsh-scraper","om-scogo","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F160466840?v=4","01M79AWB6DFVCQ7RK70CS34B96","Om Achrekar","01M79AWB6ZM9SKR8KDH1WSSM22",0,"MIT","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fpixijs-pixijs-skills\u002Fpixijs-html-source\u002FSkill.md",[],[],"2026-11-15 14:19:17",false,"---\nname: pixijs-html-source\ndescription: \"Use this skill when rendering live HTML\u002FDOM elements (or frozen snapshots of them) as PixiJS v8 textures via the EXPERIMENTAL HTML-in-Canvas browser APIs. Covers the pixi.js\u002Fhtml-source side-effect import, feature-detection with canvas.requestPaint, HTMLSource for a live, repainting element kept interactive in the browser (autoLayout\u002FautoUpdate\u002FautoRequestPaint, requestPaint, isReady, the direct-child-of-canvas + layoutsubtree requirement), ElementImageSource for an immutable captureElementImage() snapshot (autoClose, ready immediately), using the source on a Sprite\u002FTexture\u002FMesh, fallback-only auto-detection via Texture.from at priority -10, and destroy\u002Fcleanup. Triggers on: HTMLSource, ElementImageSource, pixi.js\u002Fhtml-source, requestPaint, captureElementImage, ElementImage, layoutsubtree, autoRequestPaint, autoUpdate, autoClose, HTML in canvas, render DOM to texture, HTMLSourceOptions, ElementImageSourceOptions, HTMLSourceCanvas, experimental.\"\nlicense: MIT\n---\n\n`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 require a side-effect `import 'pixi.js\u002Fhtml-source'` to register their extensions.\n\n> 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.\n\nAssumes familiarity with `pixijs-scene-sprite` and textures. These are texture *sources*, not display objects: wrap them in a `Sprite` (or `Texture`\u002F`Mesh`) to put them on screen. Not available in Web Workers; a worker has no DOM to capture.\n\n## Quick Start\n\n```ts\nimport \"pixi.js\u002Fhtml-source\";\nimport { Application, Sprite } from \"pixi.js\";\nimport { HTMLSource } from \"pixi.js\u002Fhtml-source\";\n\nconst app = new Application();\nawait app.init({ resizeTo: window });\ndocument.body.appendChild(app.canvas);\n\n\u002F\u002F The element must be a direct child of the Pixi canvas.\nconst form = document.createElement(\"form\");\nform.innerHTML = '\u003Cinput value=\"still editable\" \u002F>';\napp.canvas.appendChild(form);\n\n\u002F\u002F Render the live form as a sprite. It stays interactive in the browser.\nconst source = new HTMLSource({ resource: form });\nconst sprite = Sprite.from(source);\n\nsprite.anchor.set(0.5);\nsprite.position.set(app.screen.width \u002F 2, app.screen.height \u002F 2);\napp.stage.addChild(sprite);\n```\n\n**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\u002Fcache), `pixijs-environments` (no DOM in Web Workers).\n\n## Constructor options\n\nBoth sources extend `TextureSource`, so all `TextureSourceOptions` (`resolution`, `scaleMode`, `addressMode`, `label`, etc.) are valid. `resource` is required on each.\n\n`HTMLSourceOptions` (live element):\n\n| Option             | Type               | Default | Description                                                                                                                                              |\n| ------------------ | ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `resource`         | `Element`          | —       | Required. The live DOM element to render. Must be a direct child of the owning canvas, or the constructor throws.                                         |\n| `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. |\n| `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 `\u003Ccanvas layoutsubtree>` yourself. |\n| `autoUpdate`       | `boolean`          | `true`  | Listen for the canvas `paint` event and re-upload when the element repaints. Set `false` for a static, captured-once texture.                             |\n| `autoRequestPaint` | `boolean`          | `true`  | Request one initial paint after construction. Set `false` and call `source.requestPaint()` yourself each frame for continuous animation.                  |\n\n`ElementImageSourceOptions` (immutable snapshot):\n\n| Option       | Type           | Default | Description                                                                                                                            |\n| ------------ | -------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |\n| `resource`   | `ElementImage` | —       | Required. A snapshot from `canvas.captureElementImage(element)`.                                                                        |\n| `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. |\n\n## Core Patterns\n\n### Setup and the side-effect import\n\n```ts\nimport \"pixi.js\u002Fhtml-source\";\nimport { HTMLSource, ElementImageSource } from \"pixi.js\u002Fhtml-source\";\n```\n\n`pixi.js\u002Fhtml-source` calls `extensions.add(...)` to register `HTMLSource`, `ElementImageSource`, and their WebGL\u002FWebGPU uploaders. Without it, the renderer has no `'html'` uploader and these sources never render. The classes are exported from `pixi.js\u002Fhtml-source`, not `pixi.js`.\n\nImporting a named export from `pixi.js\u002Fhtml-source` also triggers the side effect, so a bare `import 'pixi.js\u002Fhtml-source'` is only needed when you don't import anything else from that path.\n\n### Feature detection and browser support\n\nThe HTML-in-Canvas API is gated behind a browser flag. Feature-detect before relying on it:\n\n```ts\nimport type { HTMLSourceCanvas } from \"pixi.js\u002Fhtml-source\";\n\nconst canvas = app.canvas as HTMLSourceCanvas;\n\nif (canvas.requestPaint) {\n  \u002F\u002F HTML-in-Canvas is available.\n}\n```\n\nCast `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.\n\n### Live element with HTMLSource\n\n```ts\nconst form = document.createElement(\"form\");\napp.canvas.appendChild(form); \u002F\u002F direct child of the canvas\n\nconst source = new HTMLSource({ resource: form });\nconst sprite = Sprite.from(source);\n```\n\nThe element must be a direct child of the renderer's `\u003Ccanvas>`; 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`. `resourceWidth`\u002F`resourceHeight` report the element's real-pixel size (`offsetWidth`\u002F`offsetHeight`).\n\n### Continuous animation with requestPaint\n\n```ts\nconst source = new HTMLSource({ resource: clock, autoRequestPaint: false });\nconst sprite = Sprite.from(source);\n\napp.ticker.add(() => {\n  clock.textContent = new Date().toLocaleTimeString();\n  source.requestPaint(); \u002F\u002F re-snapshot the DOM this frame\n});\n```\n\nThe 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.\n\n### Immutable snapshot with ElementImageSource\n\n```ts\nimport { ElementImageSource } from \"pixi.js\u002Fhtml-source\";\nimport type { HTMLSourceCanvas } from \"pixi.js\u002Fhtml-source\";\n\nconst canvas = app.canvas as HTMLSourceCanvas;\nconst snapshot = canvas.captureElementImage!(element);\n\nconst source = new ElementImageSource({ resource: snapshot, autoClose: true });\nconst sprite = Sprite.from(source);\n```\n\n`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()`.\n\n### Using the source on a sprite, texture, or mesh\n\nBoth sources are normal `TextureSource`s. Wrap them with `Sprite.from(source)` \u002F `Texture.from(source)`, frame or slice them into sub-textures, or map them onto a mesh:\n\n```ts\nimport { Rectangle, Texture } from \"pixi.js\";\n\n\u002F\u002F A 64x64 slice of the rendered element.\nconst chunk = new Texture({\n  source,\n  frame: new Rectangle(0, 0, 64, 64),\n});\n\n\u002F\u002F Mapped onto geometry (e.g. a perspective warp).\nconst mesh = new PerspectiveMesh({ texture: Texture.from(source) \u002F* ... *\u002F });\n```\n\n### Auto-detection and priority\n\n```ts\n\u002F\u002F Resolves to an HTMLSource (element) or ElementImageSource (snapshot) only as a last resort.\nconst sprite = Sprite.from(elementAlreadyInTheCanvas);\n```\n\nA generic HTML element or an `ElementImage` passed to `Texture.from`\u002F`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.\n\n## Common Mistakes\n\n### [HIGH] Not importing pixi.js\u002Fhtml-source\n\nWrong:\n\n```ts\nimport { HTMLSource } from \"pixi.js\u002Fhtml-source\";\n\u002F\u002F ...but never importing the side effect, in a build that tree-shakes it away\n```\n\nCorrect:\n\n```ts\nimport \"pixi.js\u002Fhtml-source\";\nimport { HTMLSource } from \"pixi.js\u002Fhtml-source\";\n```\n\nThe `'html'` uploaders are registered by the side-effect import. Without it, the source has no uploader and the texture never renders.\n\n### [HIGH] Assuming the browser API is enabled\n\nThe HTML-in-Canvas proposal is not shipped by default. If the API is disabled, the uploader throws on first render. Feature-detect first:\n\n```ts\nconst canvas = app.canvas as HTMLSourceCanvas;\nif (!canvas.requestPaint) {\n  \u002F\u002F Fall back to a static image, DOMContainer overlay, or a message.\n}\n```\n\n### [MEDIUM] Element not a direct child of the canvas\n\n```ts\ndocument.body.appendChild(form); \u002F\u002F wrong parent\nconst source = new HTMLSource({ resource: form }); \u002F\u002F throws\n```\n\n`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.\n\n### [MEDIUM] Expecting a live element to update without requestPaint\n\nA 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`).\n\n### [MEDIUM] Closing an ElementImage still in use\n\n```ts\nconst source = new ElementImageSource({ resource: snapshot, autoClose: true });\nconst other = new ElementImageSource({ resource: snapshot }); \u002F\u002F shares the snapshot\n\nsource.destroy(); \u002F\u002F closes the snapshot — `other` is now a use-after-free\n```\n\nOnly 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.\n\n## Cleanup\n\n```ts\nsource.destroy();\n```\n\n`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.\n\n## API Reference\n\n- [HTMLSource](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.HTMLSource.html.md)\n- [HTMLSourceOptions](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.HTMLSourceOptions.html.md)\n- [ElementImageSource](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.ElementImageSource.html.md)\n- [ElementImageSourceOptions](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.ElementImageSourceOptions.html.md)\n- [HTMLSourceCanvas](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.HTMLSourceCanvas.html.md)\n- [ElementImage](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.ElementImage.html.md)\n","`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 require a side-effect `import 'pixi.js\u002Fhtml-source'` to register their extensions.\n\n> 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.\n\nAssumes familiarity with `pixijs-scene-sprite` and textures. These are texture *sources*, not display objects: wrap them in a `Sprite` (or `Texture`\u002F`Mesh`) to put them on screen. Not available in Web Workers; a worker has no DOM to capture.\n\n## Quick Start\n\n```ts\nimport \"pixi.js\u002Fhtml-source\";\nimport { Application, Sprite } from \"pixi.js\";\nimport { HTMLSource } from \"pixi.js\u002Fhtml-source\";\n\nconst app = new Application();\nawait app.init({ resizeTo: window });\ndocument.body.appendChild(app.canvas);\n\n\u002F\u002F The element must be a direct child of the Pixi canvas.\nconst form = document.createElement(\"form\");\nform.innerHTML = '\u003Cinput value=\"still editable\" \u002F>';\napp.canvas.appendChild(form);\n\n\u002F\u002F Render the live form as a sprite. It stays interactive in the browser.\nconst source = new HTMLSource({ resource: form });\nconst sprite = Sprite.from(source);\n\nsprite.anchor.set(0.5);\nsprite.position.set(app.screen.width \u002F 2, app.screen.height \u002F 2);\napp.stage.addChild(sprite);\n```\n\n**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\u002Fcache), `pixijs-environments` (no DOM in Web Workers).\n\n## Constructor options\n\nBoth sources extend `TextureSource`, so all `TextureSourceOptions` (`resolution`, `scaleMode`, `addressMode`, `label`, etc.) are valid. `resource` is required on each.\n\n`HTMLSourceOptions` (live element):\n\n| Option             | Type               | Default | Description                                                                                                                                              |\n| ------------------ | ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `resource`         | `Element`          | —       | Required. The live DOM element to render. Must be a direct child of the owning canvas, or the constructor throws.                                         |\n| `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. |\n| `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 `\u003Ccanvas layoutsubtree>` yourself. |\n| `autoUpdate`       | `boolean`          | `true`  | Listen for the canvas `paint` event and re-upload when the element repaints. Set `false` for a static, captured-once texture.                             |\n| `autoRequestPaint` | `boolean`          | `true`  | Request one initial paint after construction. Set `false` and call `source.requestPaint()` yourself each frame for continuous animation.                  |\n\n`ElementImageSourceOptions` (immutable snapshot):\n\n| Option       | Type           | Default | Description                                                                                                                            |\n| ------------ | -------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |\n| `resource`   | `ElementImage` | —       | Required. A snapshot from `canvas.captureElementImage(element)`.                                                                        |\n| `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. |\n\n## Core Patterns\n\n### Setup and the side-effect import\n\n```ts\nimport \"pixi.js\u002Fhtml-source\";\nimport { HTMLSource, ElementImageSource } from \"pixi.js\u002Fhtml-source\";\n```\n\n`pixi.js\u002Fhtml-source` calls `extensions.add(...)` to register `HTMLSource`, `ElementImageSource`, and their WebGL\u002FWebGPU uploaders. Without it, the renderer has no `'html'` uploader and these sources never render. The classes are exported from `pixi.js\u002Fhtml-source`, not `pixi.js`.\n\nImporting a named export from `pixi.js\u002Fhtml-source` also triggers the side effect, so a bare `import 'pixi.js\u002Fhtml-source'` is only needed when you don't import anything else from that path.\n\n### Feature detection and browser support\n\nThe HTML-in-Canvas API is gated behind a browser flag. Feature-detect before relying on it:\n\n```ts\nimport type { HTMLSourceCanvas } from \"pixi.js\u002Fhtml-source\";\n\nconst canvas = app.canvas as HTMLSourceCanvas;\n\nif (canvas.requestPaint) {\n  \u002F\u002F HTML-in-Canvas is available.\n}\n```\n\nCast `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.\n\n### Live element with HTMLSource\n\n```ts\nconst form = document.createElement(\"form\");\napp.canvas.appendChild(form); \u002F\u002F direct child of the canvas\n\nconst source = new HTMLSource({ resource: form });\nconst sprite = Sprite.from(source);\n```\n\nThe element must be a direct child of the renderer's `\u003Ccanvas>`; 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`. `resourceWidth`\u002F`resourceHeight` report the element's real-pixel size (`offsetWidth`\u002F`offsetHeight`).\n\n### Continuous animation with requestPaint\n\n```ts\nconst source = new HTMLSource({ resource: clock, autoRequestPaint: false });\nconst sprite = Sprite.from(source);\n\napp.ticker.add(() => {\n  clock.textContent = new Date().toLocaleTimeString();\n  source.requestPaint(); \u002F\u002F re-snapshot the DOM this frame\n});\n```\n\nThe 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.\n\n### Immutable snapshot with ElementImageSource\n\n```ts\nimport { ElementImageSource } from \"pixi.js\u002Fhtml-source\";\nimport type { HTMLSourceCanvas } from \"pixi.js\u002Fhtml-source\";\n\nconst canvas = app.canvas as HTMLSourceCanvas;\nconst snapshot = canvas.captureElementImage!(element);\n\nconst source = new ElementImageSource({ resource: snapshot, autoClose: true });\nconst sprite = Sprite.from(source);\n```\n\n`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()`.\n\n### Using the source on a sprite, texture, or mesh\n\nBoth sources are normal `TextureSource`s. Wrap them with `Sprite.from(source)` \u002F `Texture.from(source)`, frame or slice them into sub-textures, or map them onto a mesh:\n\n```ts\nimport { Rectangle, Texture } from \"pixi.js\";\n\n\u002F\u002F A 64x64 slice of the rendered element.\nconst chunk = new Texture({\n  source,\n  frame: new Rectangle(0, 0, 64, 64),\n});\n\n\u002F\u002F Mapped onto geometry (e.g. a perspective warp).\nconst mesh = new PerspectiveMesh({ texture: Texture.from(source) \u002F* ... *\u002F });\n```\n\n### Auto-detection and priority\n\n```ts\n\u002F\u002F Resolves to an HTMLSource (element) or ElementImageSource (snapshot) only as a last resort.\nconst sprite = Sprite.from(elementAlreadyInTheCanvas);\n```\n\nA generic HTML element or an `ElementImage` passed to `Texture.from`\u002F`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.\n\n## Common Mistakes\n\n### [HIGH] Not importing pixi.js\u002Fhtml-source\n\nWrong:\n\n```ts\nimport { HTMLSource } from \"pixi.js\u002Fhtml-source\";\n\u002F\u002F ...but never importing the side effect, in a build that tree-shakes it away\n```\n\nCorrect:\n\n```ts\nimport \"pixi.js\u002Fhtml-source\";\nimport { HTMLSource } from \"pixi.js\u002Fhtml-source\";\n```\n\nThe `'html'` uploaders are registered by the side-effect import. Without it, the source has no uploader and the texture never renders.\n\n### [HIGH] Assuming the browser API is enabled\n\nThe HTML-in-Canvas proposal is not shipped by default. If the API is disabled, the uploader throws on first render. Feature-detect first:\n\n```ts\nconst canvas = app.canvas as HTMLSourceCanvas;\nif (!canvas.requestPaint) {\n  \u002F\u002F Fall back to a static image, DOMContainer overlay, or a message.\n}\n```\n\n### [MEDIUM] Element not a direct child of the canvas\n\n```ts\ndocument.body.appendChild(form); \u002F\u002F wrong parent\nconst source = new HTMLSource({ resource: form }); \u002F\u002F throws\n```\n\n`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.\n\n### [MEDIUM] Expecting a live element to update without requestPaint\n\nA 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`).\n\n### [MEDIUM] Closing an ElementImage still in use\n\n```ts\nconst source = new ElementImageSource({ resource: snapshot, autoClose: true });\nconst other = new ElementImageSource({ resource: snapshot }); \u002F\u002F shares the snapshot\n\nsource.destroy(); \u002F\u002F closes the snapshot — `other` is now a use-after-free\n```\n\nOnly 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.\n\n## Cleanup\n\n```ts\nsource.destroy();\n```\n\n`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.\n\n## API Reference\n\n- [HTMLSource](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.HTMLSource.html.md)\n- [HTMLSourceOptions](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.HTMLSourceOptions.html.md)\n- [ElementImageSource](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.ElementImageSource.html.md)\n- [ElementImageSourceOptions](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.ElementImageSourceOptions.html.md)\n- [HTMLSourceCanvas](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.HTMLSourceCanvas.html.md)\n- [ElementImage](https:\u002F\u002Fpixijs.download\u002Frelease\u002Fdocs\u002Frendering.ElementImage.html.md)\n",{"name":5,"license":15,"description":7},"main","8859218955d9504cd18b59e7892100718039d3b4","data\u002Fskills\u002Fpixijs-pixijs-skills\u002Fpixijs-html-source",1,"https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper","https:\u002F\u002Fgithub.com\u002Fom-scogo","SDE-1 @ Scogo ","2026-07-18 12:22:46",{"source":8,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add om-scogo\u002Fskillsh-scraper --skill pixijs-html-source",{"tool":38,"command":39},"bunx","bunx skills add om-scogo\u002Fskillsh-scraper --skill pixijs-html-source",{"tool":41,"command":42},"pnpm","pnpm dlx skills add om-scogo\u002Fskillsh-scraper --skill pixijs-html-source","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fpixijs-pixijs-skills\u002Fpixijs-html-source\u002FSkill.md",true,[46],{"path":47,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":50,"sourceHtmlUrl":51},"metadata.json","REFERENCE","参考文档",457,"https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fpixijs-pixijs-skills\u002Fpixijs-html-source\u002Fmetadata.json",[53,60,65,72,77,84],{"skillNo":54,"name":55,"nameZh":6,"description":56,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":57,"categories":58,"keywords":59,"publishedAt":19},"01M7D6MC9FAAEV4CMNYX8W7JTG","arxiv-search","Search arXiv physics, math, and computer science preprints using natural language queries. Powered by Valyu semantic search.","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fyorkeccak-scientific-skills\u002Farxiv-search\u002Fskills\u002Farxiv-search\u002FSKILL.md",[],[],{"skillNo":61,"name":55,"nameZh":6,"description":56,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":62,"categories":63,"keywords":64,"publishedAt":19},"01M7D6M85CKKN87TA98VCQV4H7","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fyorkeccak-scientific-skills\u002Farxiv-search\u002FSkill.md",[],[],{"skillNo":66,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":71,"publishedAt":19},"01M7D4ZTCS4DR3CE4JY06X84T2","working-with-legacy-code","Safely change and test untested codebases using Feathers' \"Working Effectively with Legacy Code\". Use when the user mentions \"legacy code\", \"no tests\", \"untested codebase\", \"how do I test this\", \"seams\", \"characterization tests\", \"golden master\", \"sprout method\", \"afraid to change this code\", \"monster method\", \"dependency breaking\", or \"inherited a messy codebase\". Also trigger when changing code without tests safely, getting a class under test when constructors, statics, or singletons block it, adding features to tangled modules, or planning incremental test coverage for an old codebase. Covers the legacy-code change algorithm, seams, characterization tests, sprout\u002Fwrap, and dependency-breaking techniques. For refactoring code that already has tests, see refactoring-patterns. For day-to-day code quality, see clean-code.","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fwondelai-skills\u002Fworking-with-legacy-code\u002Fworking-with-legacy-code\u002FSKILL.md",[],[],{"skillNo":73,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":19},"01M7D4ZHZKJD2RSNGAF63V14P4","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fwondelai-skills\u002Fworking-with-legacy-code\u002FSkill.md",[],[],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":19},"01M7D4ZB4CJBFW5JE67CPH2QRV","web-typography","Select, pair, and implement typefaces for web projects. Use when the user mentions \"font pairing\", \"which typeface\", \"line height\", \"responsive typography\", \"web font loading\", \"type hierarchy\", \"variable fonts\", \"FOUT\u002FFOIT\", \"typographic scale\", or \"the text is hard to read\". Also trigger when choosing between system fonts and web fonts, optimizing font-loading performance, or designing readable long-form content. Covers readability evaluation, CSS implementation, and performance optimization. For overall UI design systems, see refactoring-ui. For dramatic typographic experiences, see top-design.","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fwondelai-skills\u002Fweb-typography\u002Fweb-typography\u002FSKILL.md",[],[],{"skillNo":85,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":19},"01M7D4Z4MVYVY3NMJ18BNV6WNA","https:\u002F\u002Fgithub.com\u002Fom-scogo\u002Fskillsh-scraper\u002Fblob\u002Fmain\u002Fdata\u002Fskills\u002Fwondelai-skills\u002Fweb-typography\u002FSkill.md",[],[]]