memowake-front/components/textLinear.tsx

89 lines
2.8 KiB
TypeScript

import React from 'react';
import { StyleSheet, View } from 'react-native';
import Svg, { Defs, LinearGradient, Stop, Text as SvgText, TSpan } from 'react-native-svg';
interface GradientTextProps {
text: string;
color?: { offset: string, color: string }[];
fontSize?: number;
fontWeight?: string;
width?: number;
lineHeight?: number;
}
export default function GradientText(props: GradientTextProps) {
const { text, color, fontSize = 48, fontWeight = "700", width = 300, lineHeight = 1.2 } = props;
// Split text into words and create lines that fit within the specified width
const createLines = (text: string, maxWidth: number) => {
const words = text.split(' ');
const lines: string[] = [];
let currentLine = '';
words.forEach(word => {
const testLine = currentLine ? `${currentLine} ${word}` : word;
// Approximate text width (this is a simple estimation)
const testWidth = testLine.length * (fontSize * 0.6);
if (testWidth > maxWidth && currentLine) {
lines.push(currentLine);
currentLine = word;
} else {
currentLine = testLine;
}
});
if (currentLine) {
lines.push(currentLine);
}
return lines;
};
const lines = createLines(text, width - 40); // 40px padding
const lineHeightPx = fontSize * lineHeight;
const totalHeight = lines.length * lineHeightPx;
return (
<View style={[styles.container, { width }]}>
<Svg height={totalHeight} width={width}>
<Defs>
<LinearGradient id="textGradient" x1="0%" y1="0%" x2="100%" y2="0%">
{color?.map((item, index) => (
<Stop key={index} offset={item.offset} stopColor={item.color} />
))}
</LinearGradient>
</Defs>
<SvgText
x="50%"
y={fontSize}
fontFamily="System"
fontSize={fontSize}
fontWeight={fontWeight}
textAnchor="middle"
fill="url(#textGradient)"
>
{lines.map((line, index) => (
<TSpan
key={index}
x="50%"
dy={index === 0 ? 0 : lineHeightPx}
textAnchor="middle"
>
{line}
</TSpan>
))}
</SvgText>
</Svg>
</View>
);
}
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
alignSelf: 'center',
},
});