Blog>
Snippets

SVG Patterns as Angular Directives

Implement custom Angular directives to define reusable SVG patterns, such as gradients or shapes, that can be applied to multiple SVG elements within Angular templates.
import { Directive, ElementRef, Input, Renderer2 } from '@angular/core';

@Directive({
    selector: '[appSvgPattern]'
})
export class SvgPatternDirective {
    @Input() patternId: string;
    @Input() patternUnits: string = 'userSpaceOnUse';
    @Input() width: number = 100;
    @Input() height: number = 100;

    constructor(private el: ElementRef, private renderer: Renderer2) {}

    ngOnInit() {
        // Create pattern element
        const pattern = this.renderer.createElement('pattern', 'svg');
        this.renderer.setAttribute(pattern, 'id', this.patternId);
        this.renderer.setAttribute(pattern, 'patternUnits', this.patternUnits);
        this.renderer.setAttribute(pattern, 'width', this.width.toString());
        this.renderer.setAttribute(pattern, 'height', this.height.toString());

        // Append pattern to host SVG
        const parent = this.renderer.parentNode(this.el.nativeElement);
        this.renderer.appendChild(parent, pattern);

        // Transfer content from directive to pattern
        while (this.el.nativeElement.firstChild) {
            this.renderer.appendChild(pattern, this.el.nativeElement.firstChild);
        }
    }
}
This Angular directive 'appSvgPattern' is used to create reusable SVG patterns. The '@Input' properties allow customization of the pattern, such as 'patternId', 'patternUnits', width and height. In 'ngOnInit', the pattern element is created and appended to the host SVG, and the content of the directive is transferred to this new pattern element.
@Component({
    selector: 'app-root',
    template: `
        <svg width="200" height="200">
            <rect width="100%" height="100%" [attr.fill]="'url(#' + myPatternId + ')'" />
            <g appSvgPattern [patternId]="myPatternId" [width]="10" [height]="10">
                <circle cx="5" cy="5" r="4" fill="blue"></circle>
            </g>
        </svg>
    `
})
export class AppComponent {
    myPatternId = 'reusable-pattern';
}
Here is an Angular component example using the 'appSvgPattern' directive. An SVG rectangle is filled with a pattern having the 'myPatternId'. The 'appSvgPattern' is applied to a 'g' (group) element which defines the actual pattern, in this case a blue circle. The pattern id, width, and height are provided as inputs to the directive.