<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=2233467260228916&amp;ev=PageView&amp;noscript=1">

Harvesting SVG's Power with Angular components

Kristoffer Helgesen Kristoffer Helgesen has been working as a frontend consultant in Oslo for 5+ years and helped many projects and customers to modernize or replace their web solutions. He has development experience with all three major frontend frameworks: Angular, Vue, React as well as experience in universal design, speed optimization, design systems and reusability.
02/07/2024 |

A few months back, my current project required that I implement interactive SVGs. I could not find much information about this topic online or a straightforward “how-to guide” on implementing this in Angular. In this article, I will share my experience and the steps I took to create interactive SVGs with Angular!

Check out my sample repository for this blogpost.

What is SVG?

SVG stands for Scalable Vector Graphics and is a web-friendly vector file format that uses XML-based text format to describe how the image should appear. SVG files can be created and edited with any text editor, but it is often created with an editor. SVGs are scalable, meaning they keep the resolution no matter how big the screen is. There are multiple shapes you can use, but in this article, we will primarily use the simple ones. Here you have a guide / list of shapes that can be used: Basic shapes.


Why use an SVG?

In the cases where you have a design that does not lend well to the CSS box model. For instance, we had multiple rectangles connected with a line at strange angles. Depending on the size of the screen, we had to add media queries and based on those we had to rotate the line x amount of degrees and adjust the width to make it fit. As that component grew, we realized “this isn't manageable.” We need a better solution that gives us the flexibility to add new features later more easily.

In the following example snippets, we are going to create an SVG game with a rectangle that you control, that is going to hit another one. But first some “setup”

Prerequisites

  • Extensive knowledge of Frontend development
  • Familiar with Angular
  • Basic knowledge of SVG

Creating an SVG component

Let us kick this off with a “down to earth” example of an SVG with two rectangles.

  
  

<svg viewPort=”0 0 1920 1080”>

    <rect x=”535” y=”955” width=”10” height=”10” fill=”red” />

    <rect x=”800” y=”955” width=”10” height=”10” fill=”black”/>

</svg>

 

In the example code above, we have an SVG that covers the whole screen. Inside that, we have two rectangles, one centered in the middle and one a bit more to the right. To center an element, you take the viewport (width / 2) - (element width / 2) and the same for height. Pretty straight forward.

To make the same in Angular we could create a main component consisting of the SVG tag and one component that contains the rectangular component “svg-player.”

  
  

<svg [attr.viewPort]=”0 0 ” + viewPortWidth + “ ” + viewPortHeight”>

    <g svg-player [color]=”red” [x]=” 535” [y]=” 955” />

    <g svg-player color=”red” [x]=” 800” [y]=” 955” />

</svg>

 

In the example above you can see that we do not use the component directly as you would with any other Angular component, it looks more like a directive! To make this happen, you must modify the selector.

  
  

@Component({

  selector: '[svg-player]',

})  

 

 

This is done so that Angular does not add the <svg-player> tag inside the SVG, thereby hindering the rendering of the SVG!

SVG player component

Inside the SVG player component, you could do several things to make your life easier, the first one is that instead of having the HTML extension on your template file you could switch it out with the .svg extension. Angular has native support for SVG’s, so there should not be any problem.

Another tip is to make the child tag relative to the parent container, thus making placement inside the element a lot easier as you do not need to offset relative to the root SVG, only the current parent. In the example below you can see that we place the rectangle at coordinates zero, but the rectangle will still be placed in the middle of the root SVG.

  
  

<svg:g [attr.transform]="'translate(' + x + ' ' + y + ')'"  xmlns:svg="http://www.w3.org/2000/svg">

    <rect x=”0” y=”0” width="10” height=”10” [attr.fill]=”color” />

</svg:g>

 

A point to make is that to bind to any property of a native SVG element you must add the attr to the attribute like this [attr.fill] = “color”.

The foreignObject tag

Depending on what you want to display, you might meet the need to create complex layouts. In those cases, it's a lot easier to use the foreignObject tag! It allows you to use regular HTML as you normally would!

The foreignObject tag is powerful and works great, and it even resizes the contents!

Inside it you could use HTML and CSS as you normally would to make the layout you want, with colors, flexbox, directives, pipes etc.

Link to documentation: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject

Conclusion

I hope this illustrated how you might create an Angular SVG component and bind to attributes, how to pass variables to children, and how to create a “space” that makes placement inside a container easier with the use of the transform translate property. Additionally, you learned about the use of the foreignObject tag. For more information on SVG, you can refer to the documentation at mozilla. I also recommend reading an article by Katherine Kato over at CSS-TRICKS, which explains how to use CSS to style SVG for cleaner markup.

I have created a repository with some example code for this blopost that you can check out here.

Happy coding!  💚

Related articles

Harnessing the Power of Search Results Through UI/UX
Daniel Sueakham-Silva With a background in applied data...
arrow
Is it possible for AI to detect SQL injections using free models?
Daniel Andersson Senior Information Security Consultant,...
arrow
2 types of testing you are not doing enough of
Kristoffer Helgesen Kristoffer Helgesen has been working as...
arrow