Signatur
Beschreibung
SVGFESpecularLightingElement ist die DOM-Darstellung des Filterprimitivs <feSpecularLighting>. Das Element nimmt den Alphakanal seiner Eingabe als Höhenkarte (Bump-Map) und berechnet daraus nach dem Phong-Beleuchtungsmodell Glanzlichter. Die Lichtquelle wird durch genau ein Kindelement festgelegt: <fePointLight>, <feSpotLight> oder <feDistantLight>. Die Lichtfarbe steuert die CSS-Eigenschaft bzw. das Attribut lighting-color.
Über die Schnittstelle liest und ändert man die Filterparameter per JavaScript, etwa für interaktive Effekte (Glanzlicht folgt der Maus) oder um Filter dynamisch zu erzeugen. Alle Eigenschaften sind animierbare Werte (SVGAnimatedNumber, SVGAnimatedString, SVGAnimatedLength): Mit baseVal setzt man den Grundwert, animVal liefert den aktuell gültigen (ggf. durch SMIL animierten) Wert und ist schreibgeschützt.
Wichtige Eigenschaften:
in1– Eingabe des Filterprimitivs (Attributin).surfaceScale– Höhenfaktor für die Alpha-Höhenkarte.specularConstant– Stärke der spiegelnden Reflexion (ks).specularExponent– Glanzexponent; je größer, desto kleiner und schärfer das Glanzlicht.kernelUnitLengthX/kernelUnitLengthY– Rasterweite für die Normalenberechnung.- Aus
SVGFilterPrimitiveStandardAttributes:x,y,width,height,result.
Da das Ergebnis ein nicht-opakes Bild ist (nur die Glanzlichter), kombiniert man es üblicherweise mit <feComposite operator="arithmetic"> mit der Originalgrafik.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $in1 | SVGAnimatedString | vorheriges Ergebnis bzw. SourceGraphic | Spiegelt das Attribut in wider (schreibgeschützte Referenz, Wert über baseVal änderbar). |
| $surfaceScale | SVGAnimatedNumber | 1 | Spiegelt surfaceScale: Multiplikator für die Höhe der Alpha-Oberfläche. |
| $specularConstant | SVGAnimatedNumber | 1 | Spiegelt specularConstant: Reflexionsstärke, nicht-negativ. |
| $specularExponent | SVGAnimatedNumber | 1 | Spiegelt specularExponent: Glanzexponent, sinnvoller Bereich 1.0–128.0. |
| $kernelUnitLengthX | SVGAnimatedNumber | X-Anteil des Attributs kernelUnitLength. |
|
| $kernelUnitLengthY | SVGAnimatedNumber | Y-Anteil des Attributs kernelUnitLength. |
|
| $x / y / width / height | SVGAnimatedLength | 0% / 0% / 100% / 100% | Teilbereich des Filterprimitivs (aus SVGFilterPrimitiveStandardAttributes). |
| $result | SVGAnimatedString | Name des Ergebnisses, auf das spätere Primitive per in verweisen. |
Rückgabewert
document.createElementNS('http://www.w3.org/2000/svg', 'feSpecularLighting') oder durch Abfrage eines vorhandenen Elements im DOM.Beispiele
Filter mit Glanzlicht dynamisch erzeugen
const SVG_NS = 'http://www.w3.org/2000/svg';
const svg = document.querySelector('svg');
const filter = document.createElementNS(SVG_NS, 'filter');
filter.id = 'glanz';
const blur = document.createElementNS(SVG_NS, 'feGaussianBlur');
blur.setAttribute('in', 'SourceAlpha');
blur.setAttribute('stdDeviation', '4');
blur.setAttribute('result', 'blur');
const spec = document.createElementNS(SVG_NS, 'feSpecularLighting');
spec.setAttribute('in', 'blur');
spec.setAttribute('surfaceScale', '5');
spec.setAttribute('specularConstant', '0.8');
spec.setAttribute('specularExponent', '20');
spec.setAttribute('lighting-color', '#ffffff');
spec.setAttribute('result', 'spec');
const light = document.createElementNS(SVG_NS, 'fePointLight');
light.setAttribute('x', '-50');
light.setAttribute('y', '-100');
light.setAttribute('z', '200');
spec.append(light);
// Glanzlicht auf die Form beschränken und mit Original kombinieren
const clip = document.createElementNS(SVG_NS, 'feComposite');
clip.setAttribute('in', 'spec');
clip.setAttribute('in2', 'SourceAlpha');
clip.setAttribute('operator', 'in');
clip.setAttribute('result', 'specIn');
const merge = document.createElementNS(SVG_NS, 'feComposite');
merge.setAttribute('in', 'SourceGraphic');
merge.setAttribute('in2', 'specIn');
merge.setAttribute('operator', 'arithmetic');
for (const [k, v] of [['k1', 0], ['k2', 1], ['k3', 1], ['k4', 0]]) merge.setAttribute(k, v);
filter.append(blur, spec, clip, merge);
svg.querySelector('defs').append(filter);
svg.querySelector('circle').setAttribute('filter', 'url(#glanz)');
console.log(spec instanceof SVGFESpecularLightingElement);
Filterparameter über die animierten Eigenschaften lesen und setzen
const spec = document.querySelector('feSpecularLighting');
console.log(spec.in1.baseVal); // 'blur'
console.log(spec.specularExponent.baseVal); // 20
// Glanzlicht schärfer und kräftiger machen
spec.specularExponent.baseVal = 60;
spec.specularConstant.baseVal = 1.5;
console.log(spec.getAttribute('specularExponent'));
Glanzlicht folgt dem Mauszeiger
const svg = document.querySelector('svg');
const light = document.querySelector('feSpecularLighting fePointLight');
svg.addEventListener('pointermove', (event) => {
// Bildschirmkoordinaten in SVG-Nutzerkoordinaten umrechnen
const pt = new DOMPoint(event.clientX, event.clientY)
.matrixTransform(svg.getScreenCTM().inverse());
light.x.baseVal = pt.x;
light.y.baseVal = pt.y;
});