内联 SVG 图像未在 Safari 中呈现

Inline SVG image not rendering in Safari

我正在使用 Angular 开发一个应用程序,我在其中使用内联 SVG 渲染图像以及由自定义框架制成的边框。该应用程序在 Firefox、Chrome 和 Edge 中运行良好,但在 Safari 中没有图像呈现。以下是渲染代码

<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>

许多属性是根据用户输入动态填充的,并且为了便于查看而截断了 base64 图像。以下是Angular代码

<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>

问题出在 clip-path="url(#frame-hr)"clip-path="url(#frame-vr)" 上。这是 id 的相对路径,Safari 不支持该路径。由于 Safari 需要完整路径,因此请改用 "url("+ window.location.href + "#frame-hr)"

您的最终代码应如下所示:

<!-- 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>