1

I am developing an application with Angular where I am using inline SVG to render an image along with borders made of custom frames. The app is working fine in Firefox, Chrome and Edge but no image is rendering in Safari. Following is the rendered code

<svg _ngcontent-c19="" width="279.44444444444446px" height="186.36203246294988px" viewBox="0 0 279.44444444444446 186.36203246294988">
  <defs _ngcontent-c19="">
    <clipPath _ngcontent-c19="" id="frame-hr">
      <polygon _ngcontent-c19="" points="0,0 279.44444444444446,0 279.44444444444446,0 0,0"></polygon>
    </clipPath>
    <clipPath _ngcontent-c19="" id="frame-vr">
      <polygon _ngcontent-c19="" points="0,0 186.36203246294988,0 186.36203246294988,0 0,0"></polygon>
    </clipPath>
  </defs>
  <g _ngcontent-c19="" transform="translate(0 0)">
    <!---->
    <g _ngcontent-c19="" transform="translate(0 0)">
      <!--MAIN IMAGE NOT RENDERING-->
      <image _ngcontent-c19="" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA=" x="0" y="0" width="279.44444444444446" height="186.36203246294988">
      </image>
    </g>
  </g>
  <image _ngcontent-c19="" clip-path="url(#frame-hr)" preserveAspectRatio="none" x="0" y="0" href="" height="0" width="279.44444444444446"></image>
  <image _ngcontent-c19="" clip-path="url(#frame-vr)" preserveAspectRatio="none" x="0" y="0" href="" height="0" width="186.36203246294988" transform="rotate(90) translate(0 -279.44444444444446)"></image>
  <image _ngcontent-c19="" clip-path="url(#frame-hr)" preserveAspectRatio="none" x="0" y="0" href="" height="0" width="279.44444444444446" transform="rotate(180) translate(-279.44444444444446 -186.36203246294988)"></image>
  <image _ngcontent-c19="" clip-path="url(#frame-vr)" preserveAspectRatio="none" x="0" y="0" href="" height="0" width="186.36203246294988" transform="rotate(-90) translate(-186.36203246294988)"></image>
</svg>

A lot of the attributes are filled dynamically based on user input and the base64 image is truncated for viewing ease. Following is the Angular code

<svg [attr.width]="getTotalWidth+'px'" [attr.height]="getTotalHeight+'px'" [attr.viewBox]="'0 0 '+getTotalWidth+' '+getTotalHeight">
      <svg:defs>
        <svg:clipPath id="frame-hr">
          <svg:polygon [attr.points]="'0,0 '+(product.setSize(width)+2*product.frame.width*ratio)+',0 '+(product.setSize(width)+product.frame.width*ratio)+','+product.frame.width*ratio+' '+product.frame.width*ratio+','+product.frame.width*ratio"
          />
        </svg:clipPath>
        <svg:clipPath id="frame-vr">
          <svg:polygon [attr.points]="'0,0 '+(product.setSize(height)+2*product.frame.width*ratio)+',0 '+(product.setSize(height)+product.frame.width*ratio)+','+product.frame.width*ratio+' '+product.frame.width*ratio+','+product.frame.width*ratio"
          />
        </svg:clipPath>
      </svg:defs>
      <g [attr.transform]="'translate('+(product.frame.width*ratio)+' '+(product.frame.width*ratio)+')'">
        <!-- Outer mount -->
        <svg:rect x="0" y="0" *ngIf="product.outerMount.isValid()" [attr.width]="product.setSize(width)" [attr.height]="product.setSize(height)"
          [attr.fill]="product.outerMount.colour.value"></svg:rect>
        <!-- Inner mount -->
        <g [attr.transform]="'translate('+(product.outerMount.width*ratio)+' '+(product.outerMount.width*ratio)+')'">
          <svg:rect x="0" y="0" *ngIf="product.innerMount.isValid()" [attr.width]="product.setSize(width)-2*product.outerMount.width*ratio"
            [attr.height]="product.setSize(height)-2*product.outerMount.width*ratio" [attr.fill]="product.innerMount.colour.value"></svg:rect>
          <!-- Image -->
          <svg:image [attr.href]="product.finalImage" [attr.x]="product.innerMount.width*ratio" [attr.y]="product.innerMount.width*ratio"
            [attr.width]="product.setSize(width)-2*(product.outerMount.width+product.innerMount.width)*ratio" [attr.height]="product.setSize(height)-2*(product.outerMount.width+product.innerMount.width)*ratio"></svg:image>
        </g>
      </g>
      <!-- Frame top -->
      <svg:image [attr.href]="product.frame.edgeUrl" x="0" y="0" [attr.height]="product.frame.width*ratio" [attr.width]="product.setSize(width)+2*product.frame.width*ratio"
        clip-path="url(#frame-hr)" preserveAspectRatio="none">
      </svg:image>
      <!-- Frame right -->
      <svg:image [attr.href]="product.frame.edgeUrl" x="0" y="0" [attr.height]="product.frame.width*ratio" [attr.width]="product.setSize(height)+2*product.frame.width*ratio"
        clip-path="url(#frame-vr)" [attr.transform]="'rotate(90) translate(0 -'+(product.setSize(width)+product.frame.width*ratio*2)+')'"
        preserveAspectRatio="none">
      </svg:image>

      <!-- Frame bottom -->
      <svg:image [attr.href]="product.frame.edgeUrl" x="0" y="0" [attr.height]="product.frame.width*ratio" [attr.width]="product.setSize(width)+2*product.frame.width*ratio"
        clip-path="url(#frame-hr)" [attr.transform]="'rotate(180) translate(-'+(product.setSize(width)+product.frame.width*ratio*2)+' -'+(product.setSize(height)+product.frame.width*ratio*2)+')'"
        preserveAspectRatio="none">
      </svg:image>

      <!-- Frame left -->
      <svg:image [attr.href]="product.frame.edgeUrl" x="0" y="0" [attr.height]="product.frame.width*ratio" [attr.width]="product.setSize(height)+2*product.frame.width*ratio"
        clip-path="url(#frame-vr)" [attr.transform]="'rotate(-90) translate(-'+(product.setSize(height)+product.frame.width*ratio*2)+')'"
        preserveAspectRatio="none">
      </svg:image>

    </svg>
Vikrant Yadav
  • 303
  • 3
  • 18

1 Answers1

3

The problem is with clip-path="url(#frame-hr)" and clip-path="url(#frame-vr)". This is a relative path of id which is not supported in Safari. As Safari needs complete path use "url("+ window.location.href + "#frame-hr)" instead.

Your final code should look like below:

<!-- Frame top -->
<svg:image ... clip-path="url("+ window.location.href + "#frame-hr)" ... ></svg:image>
<!-- Frame right -->
<svg:image ... clip-path="url("+ window.location.href + "#frame-hv)" ... ></svg:image>
<!-- Frame bottom -->
<svg:image ... clip-path="url("+ window.location.href + "#frame-hr)" ... ></svg:image>
<!-- Frame left -->
<svg:image ... clip-path="url("+ window.location.href + "#frame-vr)" ... ></svg:image>
Plochie
  • 3,944
  • 1
  • 17
  • 33
  • Hi Paresh, thanks for the reply. I will keep this in mind but at the moment the tag not rendering image is the one which is inside the (before the 4 images tags in end) and it does not have any clip-path attribute. I have attached the angular code also now. – Vikrant Yadav Mar 12 '19 at 05:22
  • Although this was not the exact issue in the question but it did helped, so thanks. – Vikrant Yadav Mar 13 '19 at 07:39