gpt4 book ai didi

reactjs - 将svg文本修剪(带省略号)到给定的像素宽度

转载 作者:搜寻专家 更新时间:2023-10-30 21:09:45 25 4
gpt4 key购买 nike

我有一个svg rect和一个使用react创建的svg文本。文本可以是短的,也可以是很长的,我只需要简单地修剪(用省略号)文本,如果它的宽度大于阈值。
我知道这方面有很多问题(比如this one),但我还没能解决这个问题。
这是我的代码:

interface Props extends InterfaceState {
rectWidth: number
spaceBetweenRects: number
}

export class Labels extends React.Component<Props> {
render() {
const { rectWidth, labelRectHeight, spaceBetweenRects } = this.props

const names = ['Cher', 'Madonna', 'Band Names That Are Ridiculously Long', 'U2']
const rectHeight = labelRectHeight
const paddingLeftRight = 0.05 * rectWidth
const plusWidth = rectHeight / 2

return (
<g>
{names.map((name, i) => {
const y = i * labelRectHeight + i * spaceBetweenRects
const maxTextwidth = rectWidth - plusWidth - 3 * paddingLeftRight // this is the maximum length that text can have

return (
<g key={i}>
<React.Fragment>
<rect x={0} y={y} width={rectWidth} height={rectHeight} fill={'#E4E9EB'} />
</React.Fragment>

<text
ref={this.textRef}
x={rectWidth - paddingLeftRight}
y={y + rectHeight / 2}
textAnchor="end"
alignmentBaseline="middle"
>
{name}
</text>
</g>
)
})}
</g>
)
}
}

结果是:
enter image description here
正如你所看到的, Band Names That Are Ridiculously Long太长了,所以我想要像 Band Names That Are Ridiculously...这样的东西。
我试着用一个反应参考:
export class Labels extends React.Component<Props> {
textRef = React.createRef<SVGTextElement>()

/**
* Places textString in textObj and adds an ellipsis (...) if text can't fit in width.
* TODO: type of textObject (RefObject<SVGTextElement> doesn't work)
*/
placeTextWithEllipsis(textObj: any, textString: string, width: number) {
console.log('textObj: ', textObj) // null :()
textObj.textContent = textString
if (textObj.getSubStringLength(0, textString.length) >= width) {
for (let x = textString.length - 3; x > 0; x -= 3) {
if (textObj.getSubStringLength(0, x) <= width) {
textObj.textContent = textString.substring(0, x) + '...'
return
}
}
textObj.textContent = '...' // can't place at all
}
}

render() {
const { rectWidth, labelRectHeight, spaceBetweenRects } = this.props

const names = ['Cher', 'Madonna', 'Band Names That Are Ridiculously Long', 'U2']
const rectHeight = labelRectHeight
const paddingLeftRight = 0.05 * rectWidth
const plusWidth = rectHeight / 2

return (
<g>
{names.map((name, i) => {
const y = i * labelRectHeight + i * spaceBetweenRects
const maxTextwidth = rectWidth - plusWidth - 3 * paddingLeftRight // this is the maximum length that text can have

this.placeTextWithEllipsis(this.textRef, name, maxTextwidth)

return (
<g key={i}>
<React.Fragment>
<rect x={0} y={y} width={rectWidth} height={rectHeight} fill={'#E4E9EB'} />
</React.Fragment>

<text
ref={this.textRef}
x={rectWidth - paddingLeftRight}
y={y + rectHeight / 2}
textAnchor="end"
alignmentBaseline="middle"
>
{name}
</text>
</g>
)
})}
</g>
)
}
}

在这种情况下, textObj为空…
我尝试的最后一种方法是使用 textPath,但在这种情况下,我将只修剪字符串,而不是最后的3个点,所以我不太喜欢它作为解决方案。
如果有人帮助我,我会很高兴,因为我不知道该尝试什么。
谢谢

最佳答案

textObj在呈现方法中为空。
你必须在componentDidMount()中使用它。然后,创建一个ref数组,否则ref将被循环中的每个元素重写。

export class Labels extends React.Component<Props> {
textRefs = new Array(React.createRef<SVGTextElement>())

componentDidMount() {
const { maxTextwidth } = this.props
this.textRefs.forEach((ref, i) => {
placeTextWithEllipsis(
this.textRefs[i].current,
this.textRefs[i].current.innerHTML,
maxTextwidth
)
})
}

render() {
return (
// ...
<text
ref={(this.textRefs[i] = React.createRef<SVGTextElement>())}
x={rectWidth - paddingLeftRight}
y={y + rectHeight / 2}
textAnchor="end"
alignmentBaseline="middle"
>
{...}
</text>
// ...
)
}
}

关于reactjs - 将svg文本修剪(带省略号)到给定的像素宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54897690/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com