Signatur
Beschreibung
Die Methode replaceItem() des Interfaces SVGPointList tauscht einen einzelnen Punkt einer Punktliste aus. Solche Listen erhältst du über die Eigenschaft points der Elemente <polygon> und <polyline>. Die Änderung wird sofort in das Attribut points übernommen, und die Form wird neu gezeichnet.
Gebraucht wird die Methode vor allem in interaktiven Grafiken, etwa zum Verschieben einzelner Eckpunkte per Drag & Drop, für Diagramme, die sich live aktualisieren, oder für Editoren. Anders als beim Neusetzen des ganzen points-Strings wird dabei nur ein Eintrag ausgetauscht. Die übrigen Punktobjekte behalten ihre Identität.
Gehört newItem bereits zu einer anderen Liste (oder zu derselben), fügt der Browser laut Spezifikation eine Kopie ein bzw. entfernt den Punkt an seiner alten Stelle, je nach Implementierung. Arbeite deshalb immer mit dem Rückgabewert weiter und nicht mit dem ursprünglich übergebenen Objekt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $newItem Pflicht | SVGPoint | DOMPoint | Der neue Punkt, der eingefügt wird. Am besten erzeugst du ihn mit svgElement.createSVGPoint(). |
|
| $index Pflicht | number | Nullbasierter Index des Punkts, der ersetzt wird. Er muss kleiner als numberOfItems sein. |
Rückgabewert
newItem selbst oder eine Kopie davon.Beispiele
Eckpunkt eines Polygons ersetzen
const svg = document.querySelector('svg');
const polygon = svg.querySelector('polygon'); // points="10,10 90,10 50,80"
const p = svg.createSVGPoint();
p.x = 50;
p.y = 95;
// Dritten Punkt (Index 2) ersetzen
const inserted = polygon.points.replaceItem(p, 2);
console.log(inserted.x, inserted.y);
console.log(polygon.getAttribute('points'));
Eckpunkt per Drag & Drop verschieben
const svg = document.querySelector('svg');
const line = svg.querySelector('polyline');
let dragIndex = -1;
// Bildschirmkoordinaten in SVG-Koordinaten umrechnen
const toSvgPoint = (evt) => {
const pt = svg.createSVGPoint();
pt.x = evt.clientX;
pt.y = evt.clientY;
return pt.matrixTransform(svg.getScreenCTM().inverse());
};
svg.addEventListener('pointerdown', (evt) => {
const pos = toSvgPoint(evt);
const list = line.points;
// Nächstgelegenen Punkt im Umkreis von 8 Einheiten suchen
for (let i = 0; i < list.numberOfItems; i++) {
const q = list.getItem(i);
if (Math.hypot(q.x - pos.x, q.y - pos.y) < 8) {
dragIndex = i;
break;
}
}
});
svg.addEventListener('pointermove', (evt) => {
if (dragIndex < 0) return;
line.points.replaceItem(toSvgPoint(evt), dragIndex);
});
svg.addEventListener('pointerup', () => { dragIndex = -1; });
Ungültigen Index abfangen
const svg = document.querySelector('svg');
const polygon = svg.querySelector('polygon');
const p = svg.createSVGPoint();
try {
polygon.points.replaceItem(p, polygon.points.numberOfItems);
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- IndexSizeError: Der Browser wirft diese
DOMException, wennindexnicht kleiner alsnumberOfItemsist. MitreplaceItem()kannst du keine Punkte am Ende anhängen, dafür gibt esappendItem(). - NoModificationAllowedError: Die Liste
animatedPointsist schreibgeschützt. Ändere immerpoints. - Punkttyp: Chromium-Browser erwarten ein echtes
SVGPoint. Ein mitnew DOMPoint()erzeugtes Objekt führt dort zu einemTypeError. Für browserübergreifenden Code solltest ducreateSVGPoint()verwenden. - Ist
newItemschon Teil einer Liste, wird je nach Browser eine Kopie eingefügt oder der Punkt an der alten Stelle entfernt. Arbeite deshalb mit dem Rückgabewert weiter. - Bei sehr vielen Änderungen pro Frame (z. B. beim Neuberechnen ganzer Kurven) ist es oft schneller, das Attribut
pointseinmal komplett neu zu setzen.