feat: 线性渐变字体+默认语言为中文

This commit is contained in:
jinyaqiu 2025-08-06 11:17:52 +08:00
parent c85242f398
commit 1f35ce1c4a
7 changed files with 113 additions and 8 deletions

View File

@ -1,6 +1,6 @@
import MemberBgSvg from '@/assets/icons/svg/memberBg.svg'; import MemberBgSvg from '@/assets/icons/svg/memberBg.svg';
import ProSecondTextSvg from '@/assets/icons/svg/proSecondText.svg';
import ProTextSvg from '@/assets/icons/svg/proText.svg'; import ProTextSvg from '@/assets/icons/svg/proText.svg';
import GradientText from '@/components/textLinear';
import { ThemedText } from '@/components/ThemedText'; import { ThemedText } from '@/components/ThemedText';
import { useRouter } from 'expo-router'; import { useRouter } from 'expo-router';
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@ -31,12 +31,20 @@ const MemberCard = ({ pro }: { pro: string }) => {
{/* 会员标识 */} {/* 会员标识 */}
<View style={[styles.memberContainer, { left: width * 0.25, top: width * 0.1, opacity: 1 }]}> <View style={[styles.memberContainer, { left: width * 0.25, top: width * 0.1, opacity: 1 }]}>
<MemberBgSvg /> <MemberBgSvg />
<ThemedText style={{ fontSize: 12, color: "#2D3D60", position: "absolute", left: 0, top: 0, bottom: 0, right: 0, textAlign: "center", textAlignVertical: "center" }}>{"成为会员"}</ThemedText> <ThemedText style={{ fontSize: 12, color: "#2D3D60", position: "absolute", left: 0, top: 0, bottom: 0, right: 0, textAlign: "center", textAlignVertical: "center" }}>{t("personal:member.goPremium")}</ThemedText>
</View> </View>
{/* 解锁更多魔法 */} {/* 解锁更多魔法 */}
<View style={{ position: "absolute", bottom: width * 0.07, left: width * 0.1 }}> <View style={{ position: "absolute", bottom: width * 0.02, left: -width * 0.01, opacity: pro === "pro" ? 1 : 0.5, width: width * 0.1, flexWrap: "wrap" }}>
{/* <ThemedText style={{ fontSize: 11, color: "red" }}>{"解锁更多魔法"}</ThemedText> */} <GradientText
<ProSecondTextSvg /> text={t("personal:member.unlock")}
width={width * 0.4}
fontSize={16}
lineHeight={1.5}
color={[
{ offset: "0%", color: "#FF512F" },
{ offset: "100%", color: "#F09819" }
]}
/>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
); );

89
components/textLinear.tsx Normal file
View File

@ -0,0 +1,89 @@
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',
},
});

View File

@ -36,7 +36,7 @@ i18n
defaultNS: 'common', defaultNS: 'common',
// 设置默认语言为中文 // 设置默认语言为中文
lng: 'zh', lng: 'en',
fallbackLng: 'en', fallbackLng: 'en',
debug: process.env.NODE_ENV === 'development', debug: process.env.NODE_ENV === 'development',

View File

@ -125,5 +125,9 @@
"agreement": "I have read and agree to", "agreement": "I have read and agree to",
"membership": "《Membership Agreement》", "membership": "《Membership Agreement》",
"agreementError": "Please read and agree to the agreement" "agreementError": "Please read and agree to the agreement"
},
"member": {
"goPremium": "Go Premium",
"unlock": "Unlock more memory magic"
} }
} }

View File

@ -125,5 +125,9 @@
"agreement": "我已阅读并同意", "agreement": "我已阅读并同意",
"membership": "《会员协议》", "membership": "《会员协议》",
"agreementError": "请先阅读并同意协议" "agreementError": "请先阅读并同意协议"
},
"member": {
"goPremium": "开通会员",
"unlock": "解锁更多记忆魔法"
} }
} }

2
package-lock.json generated
View File

@ -74,7 +74,7 @@
"react-native-render-html": "^6.3.4", "react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "5.4.0", "react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.11.1", "react-native-screens": "~4.11.1",
"react-native-svg": "^15.11.2", "react-native-svg": "15.11.2",
"react-native-toast-message": "^2.3.0", "react-native-toast-message": "^2.3.0",
"react-native-uuid": "^2.0.3", "react-native-uuid": "^2.0.3",
"react-native-view-shot": "4.0.3", "react-native-view-shot": "4.0.3",

View File

@ -80,7 +80,7 @@
"react-native-render-html": "^6.3.4", "react-native-render-html": "^6.3.4",
"react-native-safe-area-context": "5.4.0", "react-native-safe-area-context": "5.4.0",
"react-native-screens": "~4.11.1", "react-native-screens": "~4.11.1",
"react-native-svg": "^15.11.2", "react-native-svg": "15.11.2",
"react-native-toast-message": "^2.3.0", "react-native-toast-message": "^2.3.0",
"react-native-uuid": "^2.0.3", "react-native-uuid": "^2.0.3",
"react-native-view-shot": "4.0.3", "react-native-view-shot": "4.0.3",