代碼功能概述 3D交互式卡片 支持3D旋轉和縮放手勢

物理反饋動畫效果

粒子背景裝飾

  1. 智能數據分析 影響力指數可視化

技能雷達圖

社交活躍度統計

  1. 多模態分享 動態二維碼生成

NFC觸碰分享

多平台集成

  1. 動效設計 流暢的頁面切換動畫

粒子系統背景

觸覺反饋集成

  1. 實用功能 一鍵複製聯繫方式

實時在線狀態

完整代碼

// 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免費進入