代码功能概述

3D交互式卡片

  • 支持3D旋转和缩放手势

  • 物理反馈动画效果

  • 粒子背景装饰

2. 智能数据分析

  • 影响力指数可视化

  • 技能雷达图

  • 社交活跃度统计

3. 多模态分享

  • 动态二维码生成

  • NFC触碰分享

  • 多平台集成

4. 动效设计

  • 流畅的页面切换动画

  • 粒子系统背景

  • 触觉反馈集成

5. 实用功能

  • 一键复制联系方式

  • 实时在线状态

  • 技能详情查看

完整代码

// 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免费进入

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐