HarmonyOS 带有星球点的标签云如何实现

HarmonyOS 带有星球点的标签云如何实现

HarmonyOS
2024-08-09 15:47:32
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
put_get

参考下这个demo:

import { promptAction } from '@kit.ArkUI' 
 
@Entry 
@Component 
export struct Index { 
  radiusValue:number = 100 
  angleX:number = Math.PI / 300 
  angleY:number = Math.PI / 300 
  centerX:number = 170 
  centerY:number = 150 
  timerAn:number = 0 
  speedTimer:number = 0 
  @State positionX: number = 0 
  @State positionY: number = 0 
  viewStartX:number = Math.PI / 300 
  viewStartY:number = Math.PI / 300 
  @State dataItemArray: TagsInfo[] = [ 
    new TagsInfo("12","",12, 1, 10, 10, 1), 
    new TagsInfo("1","",12, 1, 10, 10, 1), 
    new TagsInfo("都","",12, 1, 10, 10, 1), 
    new TagsInfo("1","",12, 1, 10, 10, 1), 
    new TagsInfo("rew","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("17","",12, 1, 10, 10, 1), 
    new TagsInfo("12","",12, 1, 10, 10, 1), 
    new TagsInfo("13","",12, 1, 10, 10, 1), 
    new TagsInfo("14","",12, 1, 10, 10, 1), 
    new TagsInfo("15","",12, 1, 10, 10, 1), 
    new TagsInfo("16","",12, 1, 10, 10, 1), 
  ]; 
  //绕x轴转 
  rotateX(){ 
    let cos = Math.cos(this.angleX); 
    let sin = Math.sin(this.angleX); 
    this.dataItemArray.forEach((item) => { 
      let y = (item.y - this.centerY)* cos - item.z * sin + this.centerY 
      let z = item.z * cos + (item.y - this.centerY) * sin; 
      item.y = y; 
      item.z = z; 
      item.itemAlpha = (item.z + this.radiusValue) / (2 * this.radiusValue) 
    }) 
  } 
  //绕Y轴转 
  rotateY() { 
    let cos = Math.cos(this.angleY); 
    let sin = Math.sin(this.angleY); 
    this.dataItemArray.forEach((item)=> { 
      let x = (item.x - this.centerX) * cos - item.z * sin + this.centerX 
      let z = item.z * cos + (item.x - this.centerX) * sin; 
      item.x = x; 
      item.z = z; 
      item.itemAlpha = (item.z + this.radiusValue) / (2 * this.radiusValue) 
    }) 
  } 
  //随机颜色 
  getRandomColor ():string{ 
    return '#'+(Math.random()*0xffffff<<0).toString(16); 
  } 
  //手势改变旋转方向和速度 
  listener (event:GestureEvent) { 
    let x = -event.offsetX 
    let y = -event.offsetY 
    let changeX = x * 0.0001 > 0 ? Math.min(this.radiusValue * 0.002 , x * 0.001 ) : Math.max(-this.radiusValue * 0.002, x * 0.001); 
    let changeY = y * 0.0001 > 0 ? Math.min(this.radiusValue * 0.002 , y * 0.001) : Math.max(-this.radiusValue * 0.002, y * 0.001); 
    if (changeX != 0 && changeY != 0) { 
      this.angleY = changeX 
      this.angleX = changeY 
    } 
    this.rotateX(); 
    this.rotateY(); 
  } 
  timerAnAction(){ 
    if (this.timerAn) { 
      clearInterval(this.timerAn) 
    }else { 
      this.timerAn = setInterval(() => { 
        this.rotateX(); 
        this.rotateY(); 
      },17) 
    } 
  } 
  aboutToAppear(): void { 
    //改变 每个item的位置 
    for (let i = 0; i < this.dataItemArray.length; i++) { 
      let a:number, b:number; 
      let k = -1 + (2 * (i + 1) - 1) / this.dataItemArray.length; 
      a = Math.acos(k); 
      b = a * Math.sqrt(this.dataItemArray.length * Math.PI); 
      let item = this.dataItemArray[i] 
      item.x = this.radiusValue * Math.sin(a) * Math.cos(b) + this.centerX 
      item.y = this.radiusValue * Math.sin(a) * Math.sin(b) + this.centerY 
      item.z = this.radiusValue * Math.cos(a) 
      item.nameTitle = "测试"+i 
      item.fontSizeCount = 10 
      item.itemColor = this.getRandomColor() 
      item.itemAlpha = (item.z + this.radiusValue) / (2 * this.radiusValue) 
    } 
    //定时器旋转 
    this.timerAnAction() 
  } 
  build() { 
    Row() { 
      Column(){ 
        ForEach(this.dataItemArray, (item:TagsInfo) => { 
          tagView({tagsInfo:item}) 
        }, (item:TagsInfo) => JSON.stringify(item)) 
      } 
      .height(300) 
      .width("100%") 
      .onTouch((event?: TouchEvent)=>{ 
        if(event){ 
          if (event.type === TouchType.Down) { 
            clearInterval(this.timerAn) 
          } 
          if (event.type === TouchType.Up) { 
            this.timerAn = setInterval(() => { 
              this.rotateX(); 
              this.rotateY(); 
            },17) 
          } 
        } 
      }) 
      .gesture( 
        PanGesture().onActionStart((ev)=>{ 
          if (this.speedTimer) { 
            clearInterval(this.speedTimer) 
            this.speedTimer = null 
          } 
        }).onActionEnd((ev)=>{ 
          this.speedTimer = setInterval(()=>{ 
            if (Math.abs(this.angleX) * 0.7 > this.viewStartX || Math.abs(this.angleY) * 0.7 > this.viewStartY) { 
              this.angleX = this.angleX * 0.7 
              this.angleY = this.angleY * 0.7 
            }else { 
              clearInterval(this.speedTimer) 
              this.speedTimer = null 
            } 
          },500) 
          clearInterval(this.timerAn) 
          this.timerAn = setInterval(() => { 
            this.rotateX(); 
            this.rotateY(); 
          },17) 
 
        }).onActionUpdate((ev)=>{ 
          this.listener(ev) 
        }) 
      ) 
    } 
    .height(300) 
    .width("100%") 
  } 
} 
@Component 
export struct tagView { 
  @ObjectLink tagsInfo: TagsInfo 
  build() { 
    Text(this.tagsInfo.nameTitle) 
      .fontSize(this.tagsInfo.fontSizeCount) 
      .fontColor(this.tagsInfo.itemColor) 
      .position({ 
        x:this.tagsInfo.x, 
        y:this.tagsInfo.y, 
      }) 
      .opacity(this.tagsInfo.itemAlpha) 
      .onClick((ev)=>{ 
        promptAction.showToast({message:this.tagsInfo.nameTitle}) 
      }) 
  } 
} 
@Observed 
class TagsInfo { 
  x:number=0; 
  y:number=0; 
  z:number = 0; 
  nameTitle:string = "" 
  fontSizeCount:number = 0 
  itemAlpha:number = 0 
  itemColor:string = "" 
  constructor(title:string,color:string,fontSizeCount:number,alpha:number, x:number, y:number, z:number) { 
    this.nameTitle = title; 
    this.itemColor = color 
    this.fontSizeCount = fontSizeCount 
    this.itemAlpha = alpha 
    this.x = x; 
    this.y = y; 
    this.z = z; 
  } 
}

以及粒子动画链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-particle-animation-0000001862687725

分享
微博
QQ
微信
回复
2024-08-09 18:55:22
相关问题
如何实现标签随文本换行
929浏览 • 1回复 待解决
怎样实现XML标签标签解析?
268浏览 • 1回复 待解决
HarmonyOS ArkTS如何实现跳转功能?
219浏览 • 1回复 待解决
阿里Redis集群实现如何直观理解?
3282浏览 • 1回复 待解决
https请求带有ca证书图片具体实现
1871浏览 • 1回复 待解决
HarmonyOS 如何读取网页中标签数据?
136浏览 • 1回复 待解决
阿里Redis集群实现细节有哪些?
2834浏览 • 1回复 待解决
关于实现图文混排几种方式优劣
367浏览 • 1回复 待解决
基于UI Observer实现UI组件埋
431浏览 • 1回复 待解决
鸿蒙如何访问华为对象存储?
3926浏览 • 1回复 待解决