【问题标题】:Angular nested SVG component is invisibleAngular 嵌套的 SVG 组件是不可见的
【发布时间】:2021-10-16 18:15:56
【问题描述】:

我正在使用两个 SVG 组件,如 here 所述。现在我想在另一个组件中使用一个组件。但是当我这样做时,嵌套组件是不可见的。没有错误,使用调试器工具,我可以看到组件在 SVG 内呈现,但宽度和高度均为 0。

如何更改组件的尺寸?

我尝试做这样的事情:<app-text-svg width="200"></app-text-svg> 但它不起作用,因为它没有宽度属性。

我的完整代码:

text-svg.component.ts:

@Component({
  selector: 'app-text-svg',
  templateUrl: './text-svg.component.svg',
  styleUrls: ['text-svg.component.scss']
})
export class TextSvgComponent implements OnInit {
  @Input() text: string;

  constructor() { }

  ngOnInit(): void {}

}
text-svg.component.svg:


<svg width="320" height="160" viewBox="0 0 320 160" xmlns="http://www.w3.org/2000/svg">
  <style>
    .text { font: 26px sans-serif; }
  </style>

  <text x="160" y="80" dominant-baseline="middle" text-anchor="middle" class="text">{{text}}</text>
</svg>
main-svg.component.svg:


<svg width="800" height="600" viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
  <app-text-svg [text]="'test'"></text-svg>
</svg>

stackblitz

这是一个简化的例子。我知道如果这就是我的全部代码,这将没有多大意义:)

【问题讨论】:

    标签: angular svg


    【解决方案1】:

    组件app-text-svg 是一个自定义(非 SVG)Web 组件,很遗憾,这些组件无法在 SVG 中显示,除非通过 foreignObjects(https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject) 的帮助。

    如果您想直接将组件包含为 SVG,您可以使用不同的选择器扩展基本文本节点,然后您的文本组件可以例如看起来像这样:

    @Component({
      selector: 'text[appTextSvg]',
      template: `
        <ng-content></ng-content>
      `,
      styles: [
        `
          :host {
            font: 26px sans-serif;
          }
        `
      ]
    })
    export class TextSvgComponent {
      @HostBinding('attr.x') x = 160;
      @HostBinding('attr.y') y = 80;
      @HostBinding('attr.dominantBaseline') dominantBaseline = 'middle';
      @HostBinding('attr.textAnchor') textAnchor = 'middle';
    }
    

    工作示例:https://stackblitz.com/edit/angular-ivy-ypx3ku?file=src%2Fapp%2Fapp.component.ts

    额外信息:如果您想通过 Input 处理文本,当然也可以这样做,不过 imo 在这里使用 ng-content 更合适。

    【讨论】:

      【解决方案2】:

      为什么要加载 143 Kb 框架,如果您可以使用 9 行 Vanilla JavaScript 来完成:

      <style>
        svg { background:pink; width:130px }
      </style>
      
      <svg-text>Hello</svg-text>
      <svg-text>Web</svg-text>
      <svg-text>Components</svg-text>
      
      <script>
        customElements.define("svg-text", class extends HTMLElement {
          connectedCallback() {
            setTimeout(() => { // wait till innerHTML is parsed
              let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
              svg.innerHTML = `<style>.text { font:21px sans-serif}</style>` + 
              `<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" class="text">`+
              this.innerHTML + `</text>`;
              this.replaceWith(svg);
            })
          }
        })
      </script>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-16
        • 2023-01-04
        • 2017-12-31
        • 1970-01-01
        • 2011-06-24
        • 2018-04-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多