Signatur
Beschreibung
SVGFEDisplacementMapElement ist die JavaScript-Schnittstelle zum Filterprimitiv <feDisplacementMap>. Das Primitiv verschiebt die Pixel der Eingabe in anhand der Farbwerte der Eingabe in2 (der sogenannten Verschiebungskarte). Welche Farbkanäle die horizontale und die vertikale Verschiebung steuern, legen xChannelSelector und yChannelSelector fest. Wie stark verschoben wird, bestimmt scale.
Typische Einsatzgebiete sind Verzerrungen wie Wasser, Hitzeflimmern, Glas oder „Glitch“-Effekte. Meist wird das Primitiv mit <feTurbulence> kombiniert, das die Verschiebungskarte als Rauschen erzeugt. Über das Interface kannst du diese Werte zur Laufzeit lesen und ändern, zum Beispiel für Animationen oder interaktive Effekte.
Alle Eigenschaften sind animierbare Objekte (SVGAnimatedString, SVGAnimatedNumber, SVGAnimatedEnumeration). Geschrieben wird über .baseVal. Der aktuell wirksame Wert, der auch SMIL-Animationen berücksichtigt, steht in .animVal. Außerdem erbt das Interface von SVGFilterPrimitiveStandardAttributes die Eigenschaften x, y, width, height und result.
Für die Kanäle gibt es diese Konstanten: SVG_CHANNEL_UNKNOWN (0), SVG_CHANNEL_R (1), SVG_CHANNEL_G (2), SVG_CHANNEL_B (3) und SVG_CHANNEL_A (4).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $in1 | SVGAnimatedString | Schreibgeschützt. Entspricht dem Attribut in, also dem Bild, das verschoben wird. |
|
| $in2 | SVGAnimatedString | Schreibgeschützt. Entspricht dem Attribut in2, also der Verschiebungskarte. |
|
| $scale | SVGAnimatedNumber | 0 | Schreibgeschützt. Entspricht dem Attribut scale und legt die Stärke der Verschiebung fest. Der Wert wird über scale.baseVal gesetzt. |
| $xChannelSelector | SVGAnimatedEnumeration | 4 (SVG_CHANNEL_A) | Schreibgeschützt. Der Farbkanal der Verschiebungskarte, der die Verschiebung in x-Richtung steuert. |
| $yChannelSelector | SVGAnimatedEnumeration | 4 (SVG_CHANNEL_A) | Schreibgeschützt. Der Farbkanal der Verschiebungskarte, der die Verschiebung in y-Richtung steuert. |
Rückgabewert
document.createElementNS('http://www.w3.org/2000/svg', 'feDisplacementMap') oder über eine DOM-Abfrage.Beispiele
Verzerrungsfilter per JavaScript erzeugen
const SVG_NS = 'http://www.w3.org/2000/svg';
const svg = document.createElementNS(SVG_NS, 'svg');
svg.setAttribute('width', '300');
svg.setAttribute('height', '150');
const filter = document.createElementNS(SVG_NS, 'filter');
filter.id = 'wobble';
// Rauschen als Verschiebungskarte erzeugen
const turbulence = document.createElementNS(SVG_NS, 'feTurbulence');
turbulence.setAttribute('type', 'turbulence');
turbulence.setAttribute('baseFrequency', '0.02');
turbulence.setAttribute('result', 'noise');
const displace = document.createElementNS(SVG_NS, 'feDisplacementMap');
displace.setAttribute('in', 'SourceGraphic');
displace.setAttribute('in2', 'noise');
displace.setAttribute('scale', '20');
displace.setAttribute('xChannelSelector', 'R');
displace.setAttribute('yChannelSelector', 'G');
filter.append(turbulence, displace);
const text = document.createElementNS(SVG_NS, 'text');
text.setAttribute('x', '20');
text.setAttribute('y', '90');
text.setAttribute('font-size', '48');
text.setAttribute('filter', 'url(#wobble)');
text.textContent = 'Wasser';
svg.append(filter, text);
document.body.append(svg);
console.log(displace instanceof SVGFEDisplacementMapElement);
console.log(displace.scale.baseVal);
Eigenschaften auslesen und Kanäle ändern
const displace = document.querySelector('feDisplacementMap');
console.log(displace.in1.baseVal);
console.log(displace.in2.baseVal);
console.log(displace.xChannelSelector.baseVal === SVGFEDisplacementMapElement.SVG_CHANNEL_R);
// Vertikale Verschiebung künftig über den Blau-Kanal steuern
displace.yChannelSelector.baseVal = SVGFEDisplacementMapElement.SVG_CHANNEL_B;
console.log(displace.getAttribute('yChannelSelector'));
Verzerrung beim Überfahren mit der Maus animieren
const displace = document.querySelector('#wobble feDisplacementMap');
const target = document.querySelector('svg text');
let frameId = null;
const animateTo = (goal) => {
cancelAnimationFrame(frameId);
const step = () => {
const current = displace.scale.baseVal;
const next = current + (goal - current) * 0.15;
displace.scale.baseVal = next;
if (Math.abs(goal - next) > 0.1) {
frameId = requestAnimationFrame(step);
} else {
displace.scale.baseVal = goal;
}
};
frameId = requestAnimationFrame(step);
};
target.addEventListener('mouseenter', () => animateTo(60));
target.addEventListener('mouseleave', () => animateTo(0));