代碼功能概述 3D交互式卡片 支持3D旋轉和縮放手勢
物理反饋動畫效果
粒子背景裝飾
- 智能數據分析 影響力指數可視化
技能雷達圖
社交活躍度統計
- 多模態分享 動態二維碼生成
NFC觸碰分享
多平台集成
- 動效設計 流暢的頁面切換動畫
粒子系統背景
觸覺反饋集成
- 實用功能 一鍵複製聯繫方式
實時在線狀態
完整代碼
// pages/SmartProfileCard.ets
import router from '@ohos.router';
import { QRCode } from '@ohos/qrcode';
import prompt from '@ohos.prompt';
import vibrator from '@ohos.vibrator';
@Entry
@Component
struct SmartProfileCard {
// 核心狀態
@State userProfile: SmartProfile = new SmartProfile();
@State currentView: 'profile' | 'analytics' | 'share' = 'profile';
@State qrCodeData: string = '';
@State isPulseAnimation: boolean = false;
@State socialInteractionStats: InteractionStats = new InteractionStats();
// 動畫相關狀態
@State cardRotation: number = 0;
@State cardScale: number = 1;
@State particlePosition: Array<{x: number, y: number, size: number, opacity: number}> = [];
aboutToAppear() {
this.loadProfileData();
this.generateQRCode();
this.startParticleAnimation();
}
build() {
Column({ space: 0 }) {
// 沉浸式狀態欄
this.BuildStatusBar()
// 3D卡片式主內容
this.BuildMainCard()
// 底部操作欄
this.BuildBottomNavigation()
}
.width('100%')
.height('100%')
.backgroundGradient({
angle: 135,
colors: [['#667eea', '#764ba2'], ['#f093fb', '#f5576c']]
})
}
@Builder BuildStatusBar() {
Row({ space: 10 }) {
Button('←')
.onClick(() => {
router.back();
})
.backgroundColor('#FFFFFF40')
.fontColor('#FFFFFF')
.fontSize(20)
.borderRadius(20)
.width(40)
.height(40)
.backdropBlur(10)
Text('數字名片')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.layoutWeight(1)
Button('🔄')
.onClick(() => {
this.refreshProfile();
})
.backgroundColor('#FFFFFF40')
.fontColor('#FFFFFF')
.fontSize(20)
.borderRadius(20)
.width(40)
.height(40)
.backdropBlur(10)
}
.width('100%')
.padding({ left: 15, right: 15, top: 50, bottom: 15 })
}
@Builder BuildMainCard() {
Stack() {
// 背景裝飾粒子
ForEach(this.particlePosition, (particle: any) => {
Circle()
.width(particle.size)
.height(particle.size)
.fill('#FFFFFF')
.opacity(particle.opacity)
.position({ x: particle.x, y: particle.y })
})
// 3D卡片容器
Stack()
.width('90%')
.height('65%')
.backgroundColor('#FFFFFF')
.borderRadius(30)
.shadow({ radius: 40, color: '#00000040', offsetX: 0, offsetY: 20 })
.rotate({ x: 0, y: this.cardRotation, z: 0 })
.scale({ x: this.cardScale, y: this.cardScale })
.gesture(
PanGesture({ distance: 3 })
.onActionStart(() => {
this.cardScale = 0.98;
})
.onActionUpdate((event: GestureEvent) => {
this.cardRotation = event.offsetX * 0.1;
})
.onActionEnd(() => {
this.cardScale = 1;
animateTo({
duration: 500,
curve: Curve.EaseOut
}, () => {
this.cardRotation = 0;
});
})
)
.overlay(
this.BuildCardContent()
)
}
.width('100%')
.height('70%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
@Builder BuildCardContent() {
Column({ space: 0 }) {
// 頂部身份區域
this.BuildIdentitySection()
// 動態內容區域
if (this.currentView === 'profile') {
this.BuildProfileView()
} else if (this.currentView === 'analytics') {
this.BuildAnalyticsView()
} else {
this.BuildShareView()
}
}
.width('100%')
.height('100%')
.clip(true)
}
@Builder BuildIdentitySection() {
Column({ space: 15 }) {
// 頭像和驗證徽章
Stack() {
Image(this.userProfile.avatarUrl)
.width(80)
.height(80)
.borderRadius(40)
.border({ width: 3, color: '#FFFFFF' })
.shadow({ radius: 10, color: '#667eea', offsetX: 0, offsetY: 5 })
if (this.userProfile.isVerified) {
Circle()
.width(24)
.height(24)
.fill('#4CD964')
.position({ x: 60, y: 60 })
.overlay(
Text('✓')
.fontSize(14)
.fontColor('#FFFFFF')
.fontWeight(FontWeight.Bold)
)
}
}
// 姓名和頭銜
Column({ space: 5 }) {
Text(this.userProfile.name)
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
Text(this.userProfile.title)
.fontSize(14)
.fontColor('#667eea')
.fontWeight(FontWeight.Medium)
}
// 公司和位置
Row({ space: 15 }) {
LabeledIcon('🏢', this.userProfile.company)
LabeledIcon('📍', this.userProfile.location)
}
// 在線狀態
Row({ space: 8 }) {
Circle()
.width(10)
.height(10)
.fill(this.userProfile.isOnline ? '#4CD964' : '#FF3B30')
Text(this.userProfile.isOnline ? '在線' : '離線')
.fontSize(12)
.fontColor('#666666')
}
.padding({ left: 10, right: 10, top: 5, bottom: 5 })
.backgroundColor('#F5F5F7')
.borderRadius(12)
}
.width('100%')
.padding(25)
.backgroundGradient({
angle: 90,
colors: [['#FFFFFF', '#F8FAFF'], ['#F0F4FF', '#E6EDFF']]
})
}
@Builder BuildProfileView() {
Scroll() {
Column({ space: 20 }) {
// 技能標籤雲
this.BuildSkillCloud()
// 聯繫方式卡片
this.BuildContactCards()
// 社交活躍度
this.BuildSocialActivity()
// 最近成就
this.BuildRecentAchievements()
}
.width('100%')
.padding(20)
}
.width('100%')
.layoutWeight(1)
}
@Builder BuildSkillCloud() {
Column({ space: 10 }) {
Text('核心技能')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
.alignSelf(ItemAlign.Start)
Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }) {
ForEach(this.userProfile.skills, (skill: SkillItem) => {
Text(skill.name)
.fontSize(12 + skill.level * 2)
.fontColor(this.getSkillColor(skill.level))
.fontWeight(FontWeight.Medium)
.padding({ left: 12, right: 12, top: 6, bottom: 6 })
.backgroundColor(this.getSkillBgColor(skill.level))
.borderRadius(20)
.margin({ right: 8, bottom: 8 })
.onClick(() => {
this.showSkillDetail(skill);
})
})
}
}
.width('100%')
}
@Builder BuildContactCards() {
Column({ space: 15 }) {
Text('聯繫方式')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
.alignSelf(ItemAlign.Start)
Grid() {
GridItem() {
ContactCard('📧', '郵箱', this.userProfile.email, '#FF6B6B')
}
GridItem() {
ContactCard('📱', '電話', this.userProfile.phone, '#4ECDC4')
}
GridItem() {
ContactCard('🌐', '網站', this.userProfile.website, '#45B7D1')
}
GridItem() {
ContactCard('💼', '領英', this.userProfile.linkedin, '#0077B5')
}
}
.columnsTemplate('1fr 1fr')
.rowsTemplate('1fr 1fr')
.columnsGap(12)
.rowsGap(12)
.width('100%')
}
}
@Builder BuildSocialActivity() {
Column({ space: 15 }) {
Row({ space: 10 }) {
Text('📊')
.fontSize(18)
Text('社交活躍度')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
.layoutWeight(1)
Text('本週')
.fontSize(12)
.fontColor('#666666')
}
Row({ space: 20 }) {
ActivityStat('互動', this.socialInteractionStats.interactions, '#96CEB4')
ActivityStat('分享', this.socialInteractionStats.shares, '#FFEAA7')
ActivityStat('關注', this.socialInteractionStats.followers, '#D291BC')
}
}
.width('100%')
.padding(20)
.backgroundColor('#FFFFFF')
.borderRadius(20)
.shadow({ radius: 10, color: '#00000010', offsetX: 0, offsetY: 5 })
}
@Builder BuildAnalyticsView() {
Scroll() {
Column({ space: 25 }) {
// 影響力指數
this.BuildInfluenceScore()
// 技能成長曲線
this.BuildSkillGrowth()
// 人脈網絡
this.BuildNetworkMap()
// 活躍時間分佈
this.BuildActivityHeatmap()
}
.width('100%')
.padding(20)
}
.width('100%')
.layoutWeight(1)
}
@Builder BuildInfluenceScore() {
Column({ space: 15 }) {
Text('數字影響力')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
.alignSelf(ItemAlign.Start)
Stack() {
// 背景圓環
Circle()
.width(200)
.height(200)
.fill(Color.Transparent)
.strokeWidth(15)
.stroke('#F0F0F0')
// 進度圓環
Circle()
.width(200)
.height(200)
.fill(Color.Transparent)
.strokeWidth(15)
.stroke('#667eea')
.strokeDashArray([Math.PI * 100])
.strokeDashOffset(Math.PI * 100 * (1 - this.userProfile.influenceScore / 100))
.strokeLineCap(LineCapStyle.Round)
// 分數顯示
Column({ space: 5 }) {
Text(this.userProfile.influenceScore.toString())
.fontSize(48)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
Text('影響力指數')
.fontSize(14)
.fontColor('#666666')
}
}
.width(200)
.height(200)
// 影響力維度
Row({ space: 15 }) {
InfluenceDimension('專業度', this.userProfile.expertiseScore, '#4CD964')
InfluenceDimension('活躍度', this.userProfile.activityScore, '#FF9500')
InfluenceDimension('傳播力', this.userProfile.reachScore, '#007AFF')
}
}
.width('100%')
.padding(25)
.backgroundColor('#FFFFFF')
.borderRadius(25)
.shadow({ radius: 15, color: '#00000010', offsetX: 0, offsetY: 8 })
}
@Builder BuildShareView() {
Column({ space: 30 }) {
Text('分享名片')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor('#1A1A1A')
// 二維碼區域
Stack() {
// 二維碼背景
Column({ space: 20 }) {
if (this.qrCodeData) {
// 實際開發中需要使用QRCode組件
// 這裏使用模擬的二維碼樣式
Grid() {
ForEach(Array.from({ length: 25 }), (_, row: number) => {
ForEach(Array.from({ length: 25 }), (_, col: number) => {
GridItem() {
Rect()
.width(8)
.height(8)
.fill((row + col) % 3 === 0 ? '#000000' : '#FFFFFF')
.margin(1)
}
})
})
}
.columnsTemplate('1fr '.repeat(25))
.rowsTemplate('1fr '.repeat(25))
.columnsGap(0)
.rowsGap(0)
.width(200)
.height(200)
.backgroundColor('#FFFFFF')
.padding(20)
.borderRadius(10)
}
Text('掃描添加聯繫人')
.fontSize(14)
.fontColor('#666666')
}
.padding(30)
.backgroundColor('#FFFFFF')
.borderRadius(25)
.shadow({ radius: 20, color: '#00000020', offsetX: 0, offsetY: 10 })
}
// 分享按鈕
Column({ space: 15 }) {
Text('分享到')
.fontSize(16)
.fontColor('#666666')
Row({ space: 20 }) {
ShareButton('微信', '#07C160', '💬')
ShareButton('名片夾', '#007AFF', '📇')
ShareButton('郵件', '#FF9500', '📧')
ShareButton('更多', '#8E8E93', '⋯')
}
}
// NFC觸碰分享提示
Row({ space: 10 }) {
Text('📱')
.fontSize(20)
Column({ space: 5 }) {
Text('NFC觸碰分享')
.fontSize(14)
.fontColor('#1A1A1A')
.fontWeight(FontWeight.Medium)
Text('將手機背面靠近其他設備')
.fontSize(12)
.fontColor('#666666')
}
}
.padding(15)
.backgroundColor('#F0F4FF')
.borderRadius(15)
.onClick(() => {
this.simulateNFCShare();
})
}
.width('100%')
.padding(30)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
@Builder BuildBottomNavigation() {
Row({ space: 0 }) {
NavButton('👤', '名片', this.currentView === 'profile', () => {
this.currentView = 'profile';
this.animateCardTransition();
})
NavButton('📈', '分析', this.currentView === 'analytics', () => {
this.currentView = 'analytics';
this.animateCardTransition();
})
// 中央的分享按鈕
Button('')
.onClick(() => {
this.currentView = 'share';
this.animateCardTransition();
})
.backgroundColor('#667eea')
.width(60)
.height(60)
.borderRadius(30)
.shadow({ radius: 15, color: '#667eea80', offsetX: 0, offsetY: 5 })
.overlay(
Text(this.currentView === 'share' ? '✓' : '↗')
.fontSize(24)
.fontColor('#FFFFFF')
)
.margin({ bottom: 10 })
NavButton('⭐', '收藏', false, () => {
this.toggleBookmark();
})
NavButton('⚙️', '設置', false, () => {
router.pushUrl({ url: 'pages/SettingsPage' });
})
}
.width('100%')
.padding({ left: 20, right: 20, bottom: 30 })
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('#FFFFFF')
.backdropBlur(20)
.borderRadius({ topLeft: 25, topRight: 25 })
.shadow({ radius: 30, color: '#00000020', offsetX: 0, offsetY: -10 })
}
// 組件構建函數
@Builder
LabeledIcon(icon: string, text: string) {
Row({ space: 5 }) {
Text(icon)
.fontSize(14)
Text(text)
.fontSize(12)
.fontColor('#666666')
.maxLines(1)
}
}
@Builder
ContactCard(icon: string, label: string, value: string, color: string) {
Column({ space: 10 }) {
Row({ space: 10 }) {
Text(icon)
.fontSize(20)
Text(label)
.fontSize(14)
.fontColor('#1A1A1A')
.fontWeight(FontWeight.Medium)
.layoutWeight(1)
}
Text(value)
.fontSize(12)
.fontColor('#666666')
.maxLines(1)
}
.width('100%')
.padding(15)
.backgroundColor('#FFFFFF')
.borderRadius(15)
.border({ width: 2, color: color + '20' })
.onClick(() => {
this.copyToClipboard(value);
})
}
@Builder
ActivityStat(label: string, value: number, color: string) {
Column({ space: 5 }) {
Text(value.toString())
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor(color)
Text(label)
.fontSize(12)
.fontColor('#666666')
}
.layoutWeight(1)
}
@Builder
InfluenceDimension(label: string, score: number, color: string) {
Column({ space: 8 }) {
Row({ space: 5 }) {
Circle()
.width(8)
.height(8)
.fill(color)
Text(label)
.fontSize(12)
.fontColor('#666666')
.layoutWeight(1)
}
Stack() {
Rect()
.width('100%')
.height(6)
.fill('#F0F0F0')
.borderRadius(3)
Rect()
.width(`${score}%`)
.height(6)
.fill(color)
.borderRadius(3)
}
.width('100%')
.height(6)
}
.layoutWeight(1)
.padding(10)
.backgroundColor('#FFFFFF')
.borderRadius(10)
.border({ width: 1, color: '#F0F0F0' })
}
@Builder
ShareButton(label: string, color: string, icon: string) {
Column({ space: 5 }) {
Button(icon)
.onClick(() => {
this.shareToPlatform(label);
})
.backgroundColor(color + '20')
.fontColor(color)
.fontSize(24)
.borderRadius(20)
.width(60)
.height(60)
Text(label)
.fontSize(12)
.fontColor('#666666')
}
}
@Builder
NavButton(icon: string, label: string, isActive: boolean, onClick: () => void) {
Column({ space: 5 }) {
Button(icon)
.onClick(onClick)
.backgroundColor(isActive ? '#667eea20' : 'transparent')
.fontColor(isActive ? '#667eea' : '#8E8E93')
.fontSize(24)
.borderRadius(20)
.width(50)
.height(50)
Text(label)
.fontSize(10)
.fontColor(isActive ? '#667eea' : '#8E8E93')
}
}
// 私有方法
private loadProfileData(): void {
// 從API或本地存儲加載數據
this.userProfile = {
name: '張創新',
title: '全棧工程師 | 產品設計師',
avatarUrl: $r('app.media.avatar'),
company: '創新科技',
location: '深圳',
email: 'chuangxin@example.com',
phone: '+86 138 0013 8000',
website: 'chuangxin.tech',
linkedin: 'linkedin.com/in/chuangxin',
isVerified: true,
isOnline: true,
skills: [
{ name: 'ArkTS', level: 5 },
{ name: 'HarmonyOS', level: 5 },
{ name: 'UI/UX設計', level: 4 },
{ name: '產品策劃', level: 4 },
{ name: '項目管理', level: 3 },
{ name: '團隊協作', level: 5 }
],
influenceScore: 82,
expertiseScore: 88,
activityScore: 76,
reachScore: 72
};
this.socialInteractionStats = {
interactions: 248,
shares: 56,
followers: 1243
};
}
private generateQRCode(): void {
// 生成包含個人信息的二維碼數據
const profileData = {
name: this.userProfile.name,
title: this.userProfile.title,
contact: this.userProfile.email,
timestamp: Date.now()
};
this.qrCodeData = JSON.stringify(profileData);
}
private startParticleAnimation(): void {
// 創建隨機粒子效果
this.particlePosition = Array.from({ length: 15 }, () => ({
x: Math.random() * 100,
y: Math.random() * 100,
size: Math.random() * 20 + 5,
opacity: Math.random() * 0.3 + 0.1
}));
// 啓動粒子動畫
setInterval(() => {
this.particlePosition = this.particlePosition.map(particle => ({
...particle,
x: (particle.x + 0.5) % 100,
y: (particle.y + 0.3) % 100,
opacity: Math.sin(Date.now() / 1000 + particle.x) * 0.2 + 0.2
}));
}, 100);
}
private animateCardTransition(): void {
// 卡片切換動畫
animateTo({
duration: 300,
curve: Curve.EaseInOut
}, () => {
this.cardScale = 0.95;
});
setTimeout(() => {
animateTo({
duration: 300,
curve: Curve.EaseInOut
}, () => {
this.cardScale = 1;
});
}, 150);
// 觸覺反饋
vibrator.startVibration({ type: 'light' });
}
private refreshProfile(): void {
this.isPulseAnimation = true;
prompt.showToast({ message: '名片已更新', duration: 1500 });
setTimeout(() => {
this.isPulseAnimation = false;
}, 1000);
}
private getSkillColor(level: number): string {
const colors = ['#FF6B6B', '#FFA726', '#42A5F5', '#66BB6A', '#5C6BC0'];
return colors[level - 1] || colors[0];
}
private getSkillBgColor(level: number): string {
const colors = ['#FFEBEE', '#FFF3E0', '#E3F2FD', '#E8F5E9', '#E8EAF6'];
return colors[level - 1] || colors[0];
}
private showSkillDetail(skill: SkillItem): void {
prompt.showDialog({
title: skill.name,
message: `熟練程度:${'★'.repeat(skill.level)}${'☆'.repeat(5 - skill.level)}\n\n相關項目:${skill.projects || '暫無'}`,
buttons: [{ text: '確定' }]
});
}
private copyToClipboard(text: string): void {
prompt.showToast({ message: '已複製到剪貼板', duration: 1000 });
// 實際項目中需要調用剪貼板API
}
private shareToPlatform(platform: string): void {
prompt.showToast({ message: `分享到${platform}`, duration: 1500 });
this.socialInteractionStats.shares++;
}
private simulateNFCShare(): void {
prompt.showToast({ message: '正在通過NFC分享...', duration: 2000 });
vibrator.startVibration({ type: 'medium' });
}
private toggleBookmark(): void {
prompt.showToast({ message: '已添加到收藏夾', duration: 1500 });
}
}
// 數據模型
class SmartProfile {
name: string = '';
title: string = '';
avatarUrl: string = '';
company: string = '';
location: string = '';
email: string = '';
phone: string = '';
website: string = '';
linkedin: string = '';
isVerified: boolean = false;
isOnline: boolean = false;
skills: SkillItem[] = [];
influenceScore: number = 0;
expertiseScore: number = 0;
activityScore: number = 0;
reachScore: number = 0;
}
class SkillItem {
name: string = '';
level: number = 1; // 1-5
projects?: string = '';
}
class InteractionStats {
interactions: number = 0;
shares: number = 0;
followers: number = 0;
}
// 樣式擴展
@Extend(Text) function skillTextStyle(level: number) {
.fontSize(12 + level * 2)
.fontColor(['#FF6B6B', '#FFA726', '#42A5F5', '#66BB6A', '#5C6BC0'][level - 1])
.fontWeight(level >= 4 ? FontWeight.Bold : FontWeight.Medium)
}
想入門鴻蒙開發又怕花冤枉錢?別錯過!現在能免費系統學 -- 從 ArkTS 面向對象核心的類和對象、繼承多態,到吃透鴻蒙開發關鍵技能,還能衝刺鴻蒙基礎 +高級開發者證書,更驚喜的是考證成功還送好禮!快加入我的鴻蒙班,一起從入門到精通,班級鏈接:點擊https://developer.huawei.com/consumer/cn/training/classDetail/b7365031334e4353a9a0fd6785bb0791?type=1?ha_source=hmosclass&ha_sourceId=89000248免費進入