Home > Mobile >  Angular 14: Dynamic SVG Component renders elements but isn't visible on screen
Angular 14: Dynamic SVG Component renders elements but isn't visible on screen

Time:08-19

I'm working on an app that parses SVG and saves it as a JSON object which can be dynamically rendered with a custom component I created. Even though everything works and I can see all the elements in the inspector, nothing shows up on the screen for some reason. I originally created this back in angular 9 and it worked back then however as I'm recreating it in Angular 14 things aren't working like they did.

Back when I created it we had to add svg: to the beginning of our elements and my custom component had to be <svg:g my-component> in order to work. I remember there was an update that eliminated the need for the svg: part but now I'm wondering if there's some new trick we need to do now with the latest version of Angular.

As of right now the way I have my svg templates set up looks like this.

svg-builder template

<svg xmlns="http://www.w3.org/2000/svg">

<style type="text/css" *ngIf="GlobalStyling !== ''" [innerHtml]="insertStyles()"></style>

  <defs>
      <symbol #symbolShell [attr.id]="SvgData.graphicId" [attr.viewBox]="GraphicViewBox">

          <svg-component *ngFor="let item of SvgData.elements" [ElementData]="item"></svg-component>

      </symbol>
  </defs>
  

  <svg preserveAspectRatio="xMidYMid meet">
      <use [attr.xlink:href]="SymbolLink" />
  </svg>

</svg>

svg-component template

<svg>

  <g *ngIf="TemplateType === 'single element'" [innerHtml]="insertElement()"></g>

  <g #graphicContainer *ngIf="TemplateType == 'group element'">

      <svg-component *ngFor="let item of ElementData.subElements" [ElementData]="item"></svg-component>

  </g>

  <linearGradient #graphicContainer *ngIf="TemplateType === 'linear gradient'">

      <svg-component *ngFor="let item of ElementData.subElements" [ElementData]="item"></svg-component>

  </linearGradient>

  <radialGradient #graphicContainer *ngIf="TemplateType === 'radial gradient'">

      <svg-component *ngFor="let item of ElementData.subElements" [ElementData]="item"></svg-component>

  </radialGradient>

  <symbol #graphicContainer *ngIf="TemplateType === 'linear gradient'">

      <svg-component *ngFor="let item of ElementData.subElements" [ElementData]="item"></svg-component>

  </symbol>

</svg>

In order to experiment with it for yourself you can go here and fill out the form with the following content.

1. Go to the demo.svg file located in the svg-builder folder and paste the code into the svg input. (I originally pasted the code here but it exceeded the 30k character limit)

2. Add anything you want to the title and graphic id inputs.

3. For the viewbox settings enter x=0 y=0 width=144 height=144

4. In the Global Styling input paste this code

.st0{fill:#0038A8;}
.st1{fill:#141414;}

5. Scroll down and click the submit button

6. Scroll beneath the JSON that pops up and click the Build SVG button

Once you do this and look in the elements tab of the inspector you'll see that everything renders in the browser, it just doesn't show up on the screen. I've tried tinkering with some of the older ways we had to use to get it to render that I mentioned above and nothing seems to work. Does anybody know why this is happening and what we need to do?

CodePudding user response:

ok after some digging around I found a solution that works. In the svg-component I need to define the selector like this

@Component({
  selector: 'svg:g[svg-component]',
  ...
})

When I use the component in my template I have to do <svg:g svg-component>...</svg:g> and everything works as expected.

  • Related