Start · Sprachen · JavaScript · Referenz · SVGFESpecularLightingElement

SVGFESpecularLightingElement

Schnittstelle

DOM-Schnittstelle für das SVG-Filterelement <code>&lt;feSpecularLighting&gt;</code>, das mit einer Lichtquelle und dem Alphakanal als Höhenkarte Glanzlichter berechnet.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

interface SVGFESpecularLightingElement extends SVGElement

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 (Attribut in).
  • 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

Typ
SVGFESpecularLightingElement
Beschreibung
Instanzen erhält man über 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);
true

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'));
blur 20 60

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;
});