Custom SVG loader not working in ionic 2

hi there,

i want to use custom SVG loader in my ionic project but it seems doesn’t work. this is link of the svg in codepen.

this is the code:

 var loading = Loading.create({
    spinner: 'hide',
    content: `
     <div class="custom-spinner-container">
    <div class="custom-spinner-box">
    <ion-spinner item-left="" name="crescent" class="sunrise-spinner">
    <!--template bindings={}-->
    <svg viewbox="-200 -150 400 300">
   <defs>
<line id="ray" x1="-5" x2="5"></line>
<clipPath id="cp">
  <rect x="-200" y="-150" width="400" height="150"></rect>
</clipPath>
 </defs>
 <line id="line" x1="-76" x2="76"></line>
 <text text-anchor="middle" y="45">sunrise</text>
 <g id="sun" clip-path="url(#cp)">
<g id="mover">
  <circle id="main" r="50"></circle>
  <g id="eyes">
    <circle r="3" cx="-13"></circle>
    <circle r="3" cx="13"></circle>
  </g>
  <g id="rays">
    <use xlink:href="#ray" transform="rotate(315) translate(70)"></use>
    <use xlink:href="#ray" transform="rotate(270) translate(70)"></use>
    <use xlink:href="#ray" transform="rotate(225) translate(70)"></use>
    <use xlink:href="#ray" transform="rotate(180) translate(70)"></use>
    <use xlink:href="#ray" transform="rotate(135) translate(70)"></use>
    <use xlink:href="#ray" transform="rotate(90) translate(70)"></use>
    <use xlink:href="#ray" transform="rotate(45) translate(70)"></use>
    <use xlink:href="#ray" transform="rotate(0) translate(70)"></use>
     </g>
    </g>
    </g>
   </svg>
    </ion-spinner>
    </div>
    </div>
     
     `,
      });

this is the image from serve :
image

thanks

1 Like

ok, i found the problem…

the problem was, when we want use custom SVG in loader we must write the css of that globally not in page css definition.

result:
image

hi, how did you get rid of the white box in the background ???

image

I used the same code but my SVG string inside my content tag just comes up as an empty space. What is the correct way to get the SVG to render.

1 Like

Did you ever figure it out? I get empty space for my <svg>...</svg> as well in Ionic3.

Yes, I’ve tried that too. Same result. The issue is that the SafeHtml is not a string. My company’s standards are to type everything (enforced by TSLint). The content option of LoadingController.create() takes only a string. I’ve even tried converting the SafeHtml with .toString(), but the results are the same. The rest of the HTML I have surrounding the SVG renders just fine, but the SVG shows up as an error that (in the HTML itself) that the sanitized HTML must be used as innerHtml="sanitizedHtml" (or something of that effect).

I would love to see a real, working example.

this.customSpinner = this.sanitizer.bypassSecurityTrustHtml(html)
this.loadingCtrl.create({spinner: ‘hide’, content: this.customSpinner})

As I have said above, that does not work where the html is an SVG. Also, this.customSpinner is not a string (which is what content requires).

it does cause I have it in two apps.

this.customSpinner = this.sanitizer.bypassSecurityTrustHtml("<div class='customSpinner'>\n\
    <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 1200'>\n\
        <defs>\n\
                <mask id='mask'>\n\
                <path fill='#000' d='M570.2 87.3L163.8 322c-15.6 9-25.2 25.6-25.2 43.6v469.3c0 18 9.6 34.6 25.2 43.6l406.4 234.7c15.6 9 34.7 9 50.3 0l406.4-234.7c15.6-9 25.2-25.6 25.2-43.6V365.6c0-18-9.6-34.6-25.2-43.6L620.5 87.3c-15.5-8.9-34.7-8.9-50.3 0z'/>\n\
                <path fill='#000' d='M787.4 474.6V343.5H394.2v505.6h131V661.8h262.2v-131H525.2v-56.2z'/>\n\
                <path fill='#000' d='M581.4 718h206v131.1h-206z'/>\n\
                <circle fill='#fff' cx='0' cy='1450' r='551.3'/>\n\
            </mask>\n\
        </defs>\n\
            <path id='background' mask='url(#mask)' fill='#F16E18' d='M570.2 87.3L163.8 322c-15.6 9-25.2 25.6-25.2 43.6v469.3c0 18 9.6 34.6 25.2 43.6l406.4 234.7c15.6 9 34.7 9 50.3 0l406.4-234.7c15.6-9 25.2-25.6 25.2-43.6V365.6c0-18-9.6-34.6-25.2-43.6L620.5 87.3c-15.5-8.9-34.7-8.9-50.3 0z'/>\n\
            <path class='letter' mask='url(#mask)' fill='#fff' d='M787.4 474.6V343.5H394.2v505.6h131V661.8h262.2v-131H525.2v-56.2z'/>\n\
            <path class='letter' mask='url(#mask)' fill='#fff' d='M581.4 718h206v131.1h-206z'/>\n\
             <path  id='hexagon-2' stroke='transparent' class='st2' d='M570.1 82.5L163.7 317.2c-15.6 9-25.2 25.6-25.2 43.6v469.3c0 18 9.6 34.6 25.2 43.6l406.4 234.7c15.6 9 34.7 9 50.3 0l406.4-234.7c15.6-9 25.2-25.6 25.2-43.6V360.8c0-18-9.6-34.6-25.2-43.6L620.4 82.5c-15.5-8.9-34.7-8.9-50.3 0z'/>\n\
                <path  id='hexagon-1' stroke='transparent' class='st2' d='M570.1 82.5L163.7 317.2c-15.6 9-25.2 25.6-25.2 43.6v469.3c0 18 9.6 34.6 25.2 43.6l406.4 234.7c15.6 9 34.7 9 50.3 0l406.4-234.7c15.6-9 25.2-25.6 25.2-43.6V360.8c0-18-9.6-34.6-25.2-43.6L620.4 82.5c-15.5-8.9-34.7-8.9-50.3 0z'/>\n\
    </svg>\n\
</div>");

What version of TypeScript, Angular and Ionic are you using? When I try this, I get an error:

TS2345: Argument of type `{content: SafeHtml; cssClass: string; duration: number; showBackdrop: false; spinner: string; }' is not assignable to parameter of type 'LoadingOptions'. Types of property 'content' are incompatible. Type 'SafeHtml' is not assignable to type 'string'.
ionic info

cli packages: 

    @ionic/cli-plugin-proxy : 1.5.6
    @ionic/cli-utils        : 1.19.1
    ionic (Ionic CLI)       : 3.19.1

global packages:

    cordova (Cordova CLI) : 7.1.0

local packages:

    @ionic/app-scripts : 3.1.8
    Cordova Platforms  : ios 4.5.3
    Ionic Framework    : ionic-angular 3.9.2

System:

    Android SDK Tools : 26.1.1
    ios-deploy        : 1.9.2
    ios-sim           : 6.1.2
    Node              : v8.9.3
    npm               : 5.6.0
    OS                : macOS Sierra
    Xcode             : Xcode 9.2 Build version 9C40b

I am also using Angular 5.2.0 and TypeScript 2.7.1

Here is my code snippet:

    const html: string =
`<div class="${componentDefinition}__container">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 62 260">
    <g id="fins">
      <polygon style="fill:#e00" points="0 260 62 260 61.16 253 0.83 253 0 260"/>
      ...
      <polygon style="fill:#e00" points="19.25 98.53 42.75 98.53 41.91 91.53 20.09 91.53 19.25 98.53"/>
    </g>
    <g id="beg_tri" data-name="beg tri">
      <polygon style="fill:#e00" points="45 132 40 80 54 80 45 132"/>
      ...
      <path style="fill:#0003d4" d="M370,244.9" transform="translate(-344 -244.9)"/>
      <polygon style="fill:#fff" points="40 80 39 80 45 132 40 80"/>
    </g>
  </svg>
</div>`;

    const safeHtml: SafeHtml = this.sanitizer.bypassSecurityTrustHtml(html);

    this.spinner = this.loadingController.create({
      content: safeHtml,
      cssClass: componentDefinition,
      duration: durationInMilliseconds,
      showBackdrop: false,
      spinner: 'hide'
    });

Okay, I finally got it. I had to change:

const safeHtml: SafeHtml = this.sanitizer.bypassSecurityTrustHtml(html);

to this:

const safeHtml: any = this.sanitizer.bypassSecurityTrustHtml(html); // Need "any" here to coax the SafeHtml into a string for "content" property