参考示例:import { promptAction } from '@kit.ArkUI' @Entry @Component export struct Page248191 { 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; } }
参考示例: