使<svg>的宽度增大以匹配其<text>的长度

时间:2019-10-11 06:03:47

标签: html css svg

我有一个反应成分,它显示了<svg>。有一个<text>属性,该属性会随时间变化。我想使<svg>的宽度增加以显示完整的text。如何使跟随组件的大小动态变化到文本的长度?

const S = {
    Container: styled.div`
        background: red;
        width: '10px';
        height: '10px';
    `
};

export class RectNode extends Component<IRectNodeProps> {
    render() {
        return (
            <S.Container>
                <svg width="auto" height="auto">
                    <rect
                        x="0"
                        y="0"
                        width="100%"
                        height="100%"
                        stroke="red"
                        stroke-width="3px"
                        fill="white"
                    />
                    // more shapes here
                    <text
                        x="50%"
                        y="50%"
                        dominant-baseline="middle"
                        text-anchor="middle"
                    >
                        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
                    </text>
                </svg>
            </S.Container>
        );
    }
}

JS Fiddle:

<svg width="auto" height="auto">
  <rect
        x="0"
        y="0"
        width="100%"
        height="100%"
        stroke="red"
        stroke-width="3px"
        fill="white"
        />
  // more shapes here
  <text
        x="50%"
        y="50%"
        dominant-baseline="middle"
        text-anchor="middle"
        >
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa
  </text>
</svg>

1 个答案:

答案 0 :(得分:1)

渲染后获取文本BBox并通过更改状态设置SVG宽度属性。示例here

class SvgComponent extends React.Component {
    state = {width: 0};

    componentDidMount() {
        this.updateTextSize();
    }

    componentDidUpdate() {
        this.updateTextSize();
    }

    updateTextSize() {
        const box = this.text.getBBox();
        if(this.state.width !== box.width) {
            this.setState({width: box.width});
        }
    }

    render() {
        return (
        <svg width={this.state.width} height="40">
            <text ref={handle => this.text = handle} x="50%" y="25" textAnchor="middle">
                {this.props.text}
            </text>
        </svg>
        );
    }
}