HarmonyOS 滚动式选中交互示例?

具体交互示例:支持读取标签数据&数值;支持自行滚动、拖拽滑动、点击等交互。

阅读 525
1 个回答

参考示例:

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;
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进