Graphics est la feuille de dessin vectoriel du graphe de scène PixiJS v8. L'API v8 suit un modèle shape-then-style : dessinez une forme ou un chemin avec rect, circle, moveTo, etc., puis appliquez fill et/ou stroke. Chaque méthode retourne this pour le chaînage, et les instructions de dessin résident dans un GraphicsContext qui peut être partagé entre instances.
Suppose une familiarité avec pixijs-scene-core-concepts. Graphics est une feuille : n'imbriquez pas d'enfants dedans. Enveloppez plusieurs objets Graphics dans un Container pour les regrouper.
Démarrage rapide
const g = new Graphics();
g.rect(10, 10, 200, 100)
.fill({ color: 0x3498db, alpha: 0.8 })
.stroke({ width: 3, color: 0x2c3e50 });
g.circle(300, 60, 40).fill(0xe74c3c);
g.moveTo(50, 200)
.lineTo(200, 200)
.bezierCurveTo(250, 250, 100, 300, 50, 250)
.closePath()
.fill(0x6c5ce7);
app.stage.addChild(g);
Compétences connexes : pixijs-scene-core-concepts (principes de base du graphe de scène), pixijs-scene-container (regrouper les graphics avec d'autres objets), pixijs-scene-core-concepts/references/masking.md (Graphics comme masque pochoir), pixijs-filters (effets), pixijs-performance (batching, cacheAsTexture).
Options du constructeur
Toutes les options Container (position, scale, tint, label, filters, zIndex, etc.) sont également valides ici — voir skills/pixijs-scene-core-concepts/references/constructor-options.md.
Options spécifiques aux feuilles ajoutées par GraphicsOptions :
| Option | Type | Défaut | Description |
|---|---|---|---|
context |
GraphicsContext |
nouveau GraphicsContext() |
Contexte de dessin partagé. Passer un contexte réutilise sa géométrie tessellée sur plusieurs nœuds Graphics, évitant le travail GPU dupliqué. Si omis, chaque Graphics crée et possède un nouveau contexte. |
roundPixels |
boolean |
false |
Arrondit la x/y finale à l'écran au pixel le plus proche. Produit des lignes plus nettes pour les styles pixel art au prix du mouvement sub-pixel fluide. |
Le constructeur accepte aussi une instance GraphicsContext comme seul argument (new Graphics(ctx)), ce qui est un raccourci pour new Graphics({ context: ctx }).
Modèles fondamentaux
Flux shape-then-fill
const g = new Graphics();
g.rect(10, 10, 200, 100)
.fill({ color: 0x3498db, alpha: 0.8 })
.stroke({ width: 3, color: 0x2c3e50 });
g.circle(150, 200, 40).fill(0xe74c3c);
g.roundRect(300, 10, 150, 80, 12).fill(0x2ecc71);
g.poly([0, 0, 60, 0, 30, 50], true).fill(0x9b59b6);
g.star(400, 200, 5, 40, 20, 0).fill(0xf39c12);
g.ellipse(100, 350, 60, 30).fill(0x1abc9c);
fill() accepte un FillInput : un nombre/chaîne de couleur, { color, alpha, texture, matrix, textureSpace }, un FillGradient, un FillPattern, ou une Texture. Lors du remplissage avec une texture, textureSpace contrôle le mappage des coordonnées :
'local'(par défaut) : la texture est mise à l'échelle pour s'adapter à la boîte englobante de chaque forme (coordonnées normalisées 0-1).'global': la position/l'échelle de la texture sont relatives au système de coordonnées de l'objet Graphics, partagées entre toutes les formes.
FillInput supporte aussi un sous-champ fill imbriqué : un objet d'options FillStyle peut intégrer un FillGradient ou un FillPattern sous sa clé fill, qui applique le dégradé ou le motif aux côtés des modificateurs color, alpha, texture et matrix sur l'objet externe.
stroke() accepte une couleur, un FillGradient, un FillPattern, ou un objet StrokeStyle qui combine toutes les clés FillStyle (color, alpha, texture, matrix, fill, textureSpace) avec les attributs de trait :
| Attribut | Défaut | Notes |
|---|---|---|
width |
1 |
Largeur en pixels du trait. |
cap |
'butt' |
L'un de 'butt', 'round', 'square'. Style de fin pour chemins ouverts. |
join |
'miter' |
L'un de 'miter', 'round', 'bevel'. Style de coin. |
miterLimit |
10 |
Limite l'extension des jointures miter avant de revenir à bevel. |
alignment |
0.5 |
1 = à l'intérieur de la forme, 0.5 = centré, 0 = à l'extérieur. |
pixelLine |
false |
Aligne les lignes 1-pixel à la grille de pixels pour une sortie nette. Graphics uniquement. |
Les traits peuvent utiliser les mêmes dégradés et motifs que les remplissages via fill: gradient ou texture: tex :
const grad = new FillGradient({
end: { x: 1, y: 0 },
colorStops: [
{ offset: 0, color: 0xff0000 },
{ offset: 1, color: 0x0000ff },
],
});
g.rect(0, 0, 200, 100).stroke({
width: 8,
fill: grad,
join: "round",
cap: "round",
});
Both fill() et stroke() peuvent être appelées après la même forme ; appeler stroke() immédiatement après fill() réutilise le même chemin.
Primitives de formes avancées
g.regularPoly(100, 100, 50, 6, 0).fill(0x3498db);
g.roundPoly(250, 100, 50, 5, 10).fill(0xe74c3c);
g.chamferRect(350, 50, 100, 80, 15).fill(0x2ecc71);
g.filletRect(500, 50, 100, 80, 15).fill(0x9b59b6);
g.roundShape(
[
{ x: 50, y: 250, radius: 20 },
{ x: 150, y: 250, radius: 5 },
{ x: 150, y: 350, radius: 10 },
{ x: 50, y: 350, radius: 15 },
],
10,
).fill(0xf39c12);
Trous avec cut()
g.rect(0, 0, 200, 200).fill(0x00ff00).circle(100, 100, 50).cut();
cut() soustrait le chemin actif courant du remplissage ou du trait précédemment dessiné. Règles :
- Le trou doit être complètement à l'intérieur de la forme cible. Les trous qui chevauchent les bords ou se situent en dehors de la forme ne se rendront pas correctement car le rendu triangule avec le trou comme limite intérieure.
cut()regarde en arrière jusqu'aux deux dernières instructions. Quand vousfill()puisstroke()le même chemin, un seulcut()ajoute le trou au trait d'abord ; un secondcut()l'ajoute au remplissage en dessous.- Après
cut(), le chemin actif se réinitialise pour que vous puissiez commencer la forme suivante avecmoveTo,rect, etc. cut()s'applique aussi aux traits —g.rect(...).stroke(...).circle(...).cut()coupe un trou dans le contour du trait.
Percez plusieurs trous avec un seul cut() en dessinant plusieurs formes dans le chemin actif avant de l'appeler. Chaque forme s'accumule dans le même chemin de trou :
const g = new Graphics();
g.rect(350, 350, 150, 150).fill(0x00ff00);
// Dessinez trois cercles dans le chemin actif, puis coupez-les tous en un seul appel
g.circle(375, 375, 25);
g.circle(425, 425, 25);
g.circle(475, 475, 25);
g.cut();
Si vous avez besoin de trous sur des formes remplies séparées, donnez à chaque forme son propre fill() et un cut() correspondant :
g.rect(0, 0, 100, 100).fill(0x3498db);
g.circle(50, 50, 20).cut(); // trou dans le rect
g.rect(120, 0, 100, 100).fill(0xe74c3c);
g.circle(170, 50, 20).cut(); // trou dans le deuxième rect
Appeler cut() sur une forme qui a déjà un trou ajoute au chemin de trou existant plutôt que de le remplacer. Utilisez ceci pour superposer les trous de manière additive.
Chemins et formes complexes
g.moveTo(50, 50)
.lineTo(200, 50)
.bezierCurveTo(250, 100, 250, 150, 200, 200)
.quadraticCurveTo(100, 250, 50, 200)
.closePath()
.fill({ color: 0x6c5ce7, alpha: 0.7 })
.stroke({ width: 2, color: 0xdfe6e9 });
Méthodes de chemin : moveTo, lineTo, bezierCurveTo, quadraticCurveTo, arc, arcTo, arcToSvg, closePath. Appelez beginPath() pour abandonner le chemin courant et en commencer un nouveau.
// arc(cx, cy, radius, startAngle, endAngle, counterclockwise?)
g.moveTo(80, 50)
.arc(50, 50, 30, 0, Math.PI)
.stroke({ width: 4, color: 0x2c3e50 });
// arcTo(x1, y1, x2, y2, radius) — coin arrondi entre deux segments de ligne
g.moveTo(150, 20)
.arcTo(200, 20, 200, 80, 20)
.lineTo(200, 80)
.stroke({ width: 2 });
// arcToSvg(rx, ry, xAxisRotation, largeArcFlag, sweepFlag, x, y) — correspond à la commande SVG `A`
g.moveTo(250, 50).arcToSvg(40, 20, 0, 1, 0, 330, 50).stroke({ width: 2 });
Dégradés et motifs
// Dégradé linéaire
const linear = new FillGradient({
end: { x: 1, y: 0 },
colorStops: [
{ offset: 0, color: 0xff0000 },
{ offset: 1, color: 0x0000ff },
],
});
g.rect(0, 0, 200, 100).fill(linear);
// Dégradé radial — cercle intérieur au centre, cercle extérieur atteint les bords
const radial = new FillGradient({
type: "radial",
center: { x: 100, y: 100 },
innerRadius: 0,
outerCenter: { x: 100, y: 100 },
outerRadius: 100,
colorStops: [
{ offset: 0, color: 0xffffff },
{ offset: 1, color: 0x000000 },
],
});
g.circle(100, 100, 100).fill(radial);
const brick = await Assets.load("brick.png");
const pattern = new FillPattern(brick, "repeat"); // 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'
g.rect(0, 120, 200, 100).fill(pattern);
Le type par défaut de FillGradient est 'linear' avec start {0,0} vers end {0,1}. Définissez type: 'radial' avec center/innerRadius et outerCenter/outerRadius pour les dégradés radiaux. Le deuxième argument de FillPattern sélectionne un mode de répétition et expose setTransform(matrix) pour mettre à l'échelle, faire pivoter ou décaler la texture dans le motif.
Dessiner une texture directement
const tex = await Assets.load("icon.png");
// Dessinez la texture entière à (x, y) avec teinte optionnelle
g.texture(tex, 0xffffff, 20, 20);
// Dessinez une sous-région (dx, dy, dw, dh)
g.texture(tex, 0xff0000, 100, 20, 64, 64);
Graphics.texture(texture, tint?, dx?, dy?, dw?, dh?) est un raccourci pour dessiner un seul rect texturé sans passer par fill(). Utile pour les icônes où vous n'avez pas besoin du cycle de vie complet des sprites.
Partage de GraphicsContext
const ctx = new GraphicsContext().rect(0, 0, 50, 50).fill(0xff0000);
const g1 = new Graphics(ctx);
const g2 = new Graphics(ctx);
g2.x = 100;
Le partage de contexte évite la géométrie GPU en double ; la tessellation coûteuse s'exécute une fois. Vous pouvez aussi assigner un contexte après la construction : g.context = existingContext.
Import et export SVG
Analysez le balisage SVG dans le contexte actif avec svg() :
g.svg(`<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="red"/>
</svg>`);
svg() supporte les chemins, les formes basiques et les styles inline ; les géométries de trous complexes peuvent se rendre inexactement car la triangulation de Pixi est optimisée pour la performance.
Sérialisez un Graphics ou un GraphicsContext en chaîne de document SVG autonome avec graphicsContextToSvg :
import { Graphics, graphicsContextToSvg } from "pixi.js";
const g = new Graphics()
.rect(0, 0, 100, 50)
.fill({ color: 0xff0000 })
.circle(150, 25, 25)
.stroke({ color: 0x0000ff, width: 4 });
const svgString = graphicsContextToSvg(g, 2);
graphicsContextToSvg(source, precision = 2) est une fonction pure qui lit les instructions du contexte et retourne une chaîne <svg> complète avec un viewBox auto-calculé. Passez un Graphics ou un GraphicsContext ; precision contrôle les décimales sur les coordonnées émises. Exporte chaque primitive shape-then-fill (les formes avancées comme regularPoly/filletRect reviennent à un chemin de forme), toutes les méthodes de chemin, les attributs de trait (width, cap, join, miterLimit), fill-opacity/stroke-opacity et FillGradient (linéaire et radial) via un bloc <defs>. Les trous s'effondrent en un seul <path> avec fill-rule="evenodd". FillPattern et les remplissages de texture n'ont pas d'équivalent SVG : les motifs passent au color solide du remplissage, et les instructions texture() sont entièrement ignorées. Le balisage exporté fait des allers-retours via g.svg(...) sans nettoyage, vous pouvez donc exporter, stocker et réimporter plus tard une forme dans une autre Graphics.
Réutiliser un GraphicsPath
const arrow = new GraphicsPath()
.moveTo(0, 0)
.lineTo(40, 0)
.lineTo(40, -10)
.lineTo(60, 10)
.lineTo(40, 30)
.lineTo(40, 20)
.lineTo(0, 20)
.closePath();
g.path(arrow).fill(0x3498db);
g.translateTransform(80, 0).path(arrow).fill(0xe74c3c);
Graphics.path(graphicsPath) (et GraphicsContext.path()) ajoute un GraphicsPath préfabriqué au chemin actif. Construisez une fois, dessinez plusieurs fois.
Transformations au moment du dessin
Graphics a sa propre pile de transformation utilisée pendant le dessin qui est séparée de la transformation Container appliquée à la sortie rendue. Les méthodes de dessin sont renommées pour éviter les conflits avec Container.rotation, Container.scale, Container.position :
| Transformation de dessin | Transformation Container |
|---|---|
g.rotateTransform(angle) |
g.rotation |
g.scaleTransform(x, y?) |
g.scale.set(x, y) |
g.translateTransform(x, y?) |
g.position.set(x, y) |
g.setTransform(matrix) ou setTransform(a,b,c,d,tx,ty) |
g.setFromMatrix(matrix) |
g.transform(matrix) ou transform(a,b,c,d,tx,ty) |
n/a |
g.getTransform() / g.resetTransform() |
n/a |
const g = new Graphics();
g.translateTransform(100, 100)
.rotateTransform(Math.PI / 4)
.rect(-25, -25, 50, 50)
.fill(0x3498db);
// Le carré est pivoté de 45 degrés tel qu'il est ajouté à la géométrie.
// Définir g.rotation plus tard fait pivoter l'ensemble Graphics à l'écran.
La transformation de dessin affecte chaque commande de forme et de chemin suivante ajoutée au contexte. Utilisez save()/restore() pour la limiter.
Sauvegarde/restauration d'état
g.save();
g.translateTransform(100, 100);
g.rotateTransform(Math.PI / 4);
g.rect(0, 0, 50, 50).fill(0xff0000);
g.restore();
save() pousse la transformation de dessin, le style de remplissage et le style de trait sur une pile ; restore() les sort. Graphics expose save/restore directement, reflétant les appels GraphicsContext sous-jacents.
Styles par défaut via setFillStyle / setStrokeStyle
g.setFillStyle({ color: 0x3498db, alpha: 0.8 }).setStrokeStyle({
width: 2,
color: 0x2c3e50,
});
g.rect(0, 0, 100, 100).fill().stroke();
g.circle(150, 50, 40).fill().stroke();
setFillStyle() et setStrokeStyle() configurent le style par défaut utilisé par les appels fill() / stroke() suivants quand aucun argument n'est passé. Lisez ou remplacez le style courant à tout moment via les accesseurs/mutateurs fillStyle et strokeStyle. Remplacez les défauts à l'échelle de la bibliothèque en mutant GraphicsContext.defaultFillStyle et GraphicsContext.defaultStrokeStyle une seule fois au démarrage.
Test d'intersection
const g = new Graphics().star(100, 100, 5, 60, 30).fill(0xf39c12);
g.eventMode = "static";
g.on("pointermove", (e) => {
if (g.containsPoint(g.toLocal(e.global))) {
/* sur l'étoile, pas juste sa bbox */
}
});
Graphics.containsPoint(pointInLocalSpace) exécute un test conscient de la topologie contre chaque forme remplie et tracée dans le contexte, y compris les trous. Convertissez d'abord les coordonnées du pointeur global avec toLocal().
Clonage, effacement et limites
const g = new Graphics().rect(0, 0, 100, 100).fill(0xff0000);
const shallow = g.clone(); // partage le même GraphicsContext
const deep = g.clone(true); // crée un contexte indépendant
console.log(g.bounds.width); // 100 - limites de géométrie avant les transformations
g.clear(); // efface le chemin actif, les instructions et la transformation ; les styles de remplissage/trait persistent
clone()retourne un nouveauGraphicsqui partage le contexte source (pas cher, la géométrie est réutilisée). Les deux objets se mettent à jour ensemble si le contexte change.clone(true)clone aussi le contexte afin que le nouveauGraphicspuisse être édité indépendamment.boundsretourne les limites de géométrie avant la transformationContainer. Utile pour les décisions de disposition.clear()réinitialise le contexte pour que le mêmeGraphicspuisse être réutilisé. Voir Erreurs courantes ci-dessous pour des conseils sur quand effacer par rapport à quand garder une géométrie stable.
Utilitaires GraphicsContext
| Membre | Comportement |
|---|---|
ctx.path(graphicsPath) |
Applique un GraphicsPath préfabriqué au chemin actif. Réutilisez un chemin sur plusieurs contextes ou cadres. |
ctx.beginPath() |
Abandonne le chemin actif courant et en commence un nouveau sans affecter les instructions validées. |
ctx.setFillStyle(style) / ctx.fillStyle |
Définit ou lit le style de remplissage par défaut utilisé par les formes suivantes sans appeler fill(). |
ctx.setStrokeStyle(style) / ctx.strokeStyle |
Définit ou lit le style de trait par défaut utilisé par les formes suivantes sans appeler stroke(). |
ctx.bounds |
Limites de géométrie en cache sur toutes les instructions de remplissage/trait/texture. |
ctx.clear() |
Efface les instructions, le chemin actif et la transformation de dessin. |
ctx.clone() |
Copie profonde incluant les instructions, le chemin actif, la transformation, les styles et la pile. |
ctx.containsPoint(point) |
Test d'intersection conscient de la topologie contre toutes les formes remplies et tracées (y compris les trous). |
ctx.batchMode |
L'un de 'auto', 'batch', 'no-batch' — force ou désactive le batching pour les formes dans ce contexte. |
ctx.customShader |
Assigne un Shader pour remplacer le shader graphics par défaut. |
GraphicsContext.defaultFillStyle |
Secours statique utilisé quand fill() est appelé sans arguments et aucun style de remplissage n'est défini. |
GraphicsContext.defaultStrokeStyle |
Secours statique utilisé quand stroke() est appelé sans arguments et aucun style de trait n'est défini. |
GraphicsContext est un EventEmitter qui émet les événements update, destroy et unload. Abonnez-vous via ctx.on('update' | 'destroy' | 'unload', cb) quand l'outillage ou les pools ont besoin de réagir aux changements du cycle de vie du contexte.
Erreurs courantes
[CRITIQUE] Utilisation de v7 beginFill/drawRect/endFill
Incorrect :
const g = new Graphics().beginFill(0xff0000).drawRect(0, 0, 100, 100).endFill();
Correct :
const g = new Graphics().rect(0, 0, 100, 100).fill(0xff0000);
v8 a remplacé « définir le style, dessiner, terminer » par « dessiner une forme, puis appliquer le style ». beginFill/endFill n'existent pas.
[CRITIQUE] Utilisation d'anciens noms de méthodes de formes
Incorrect :
g.drawCircle(50, 50, 25);
Correct :
g.circle(50, 50, 25);
Toutes les méthodes draw* ont été renommées en v8 : drawRect → rect, drawCircle → circle, drawEllipse → ellipse, drawPolygon → poly, drawRoundedRect → roundRect, drawStar → star.
[CRITIQUE] Utilisation de lineStyle au lieu de stroke
Incorrect :
g.lineStyle(2, 0xffffff);
g.drawRect(0, 0, 100, 100);
Correct :
g.rect(0, 0, 100, 100).stroke({ width: 2, color: 0xffffff });
lineStyle a été supprimé. Utilisez stroke() après avoir dessiné la forme. L'objet d'options de trait accepte width, color, alpha, cap, join, alignment, miterLimit et pixelLine.
[ÉLEVÉE] Utilisation de beginHole/endHole pour les trous
Incorrect :
g.beginFill(0x00ff00)
.drawRect(0, 0, 100, 100)
.beginHole()
.drawCircle(50, 50, 20)
.endHole()
.endFill();
Correct :
g.rect(0, 0, 100, 100).fill(0x00ff00).circle(50, 50, 20).cut();
beginHole/endHole ont été remplacés par cut(). Dessinez la forme extérieure, remplissez-la, puis dessinez la forme du trou et appelez cut().
[ÉLEVÉE] Utilisation de GraphicsGeometry au lieu de GraphicsContext
Incorrect :
const geom = g.geometry;
const clone = new Graphics(geom);
Correct :
const ctx = new GraphicsContext().rect(0, 0, 100, 100).fill(0xff0000);
const g1 = new Graphics(ctx);
const g2 = new Graphics(ctx);
GraphicsGeometry a été remplacé par GraphicsContext en v8. Il n'existe pas de propriété .geometry.
[ÉLEVÉE] Destruction inattendue d'un GraphicsContext partagé
const ctx = new GraphicsContext().rect(0, 0, 50, 50).fill(0xff0000);
const g1 = new Graphics(ctx);
const g2 = new Graphics(ctx);
g1.destroy({ context: true }); // annule aussi la référence de contexte de g2
Détruire un GraphicsContext partagé ne détruit pas les instances de partage mais les casse en annulant leur référence de contexte. Lorsqu'on passe un contexte via le constructeur, destroy() sans arguments préserve le contexte ; utilisez destroy({ context: false }) pour être explicite. Ne détruisez le contexte que lorsque toutes les instances de partage en ont terminé avec. Un contexte auto-possédé (non passé via le constructeur) est toujours détruit par destroy() sans arguments.
[ÉLEVÉE] Effacement et redessin de Graphics chaque cadre
Les Graphics sont conçues pour être stables, pas dynamiques. Appeler clear() et redessiner chaque cadre reconstruit la géométrie GPU à chaque fois. Pour les visuels dynamiques :
- Utilisez
Spriteavec des textures pré-rendues et des changements de transformation. - Utilisez
cacheAsTexture(true)pour les graphics statiques complexes. - Pour les changements de formes en temps réel, envisagez
Meshavec des mises à jour de géométrie personnalisées.
C'est l'opposé du Canvas 2D HTML, où redessiner chaque cadre est normal. PixiJS tesselle les formes en triangles GPU, donc le dessin initial est coûteux mais les rendus suivants sont rapides. Traitez Graphics plus comme des éléments SVG que comme des appels de dessin canvas.
[MOYEN] Ne pas imbriquer d'enfants à l'intérieur d'une Graphics
Graphics définit allowChildren = false. L'ajout d'enfants enregistre un avertissement de dépréciation et sera une erreur dure dans une version future. Enveloppez plusieurs graphics aux côtés d'autres feuilles dans un simple Container :
const group = new Container();
group.addChild(graphics, sprite);