reagencyComp.ets 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import { Location } from "../model/AnimationModel"
  2. import image from "@ohos.multimedia.image"
  3. import { BubbleStorage } from "../model/Storage"
  4. import { AppStorageV2 } from "@kit.ArkUI"
  5. @ComponentV2
  6. export struct reagencyComp {
  7. // 训练开始与否
  8. @Param trainStarted: number = 0
  9. bubbleConnect: BubbleStorage = AppStorageV2.connect(BubbleStorage, () => new BubbleStorage())!
  10. // 点击了气泡
  11. @Event bubbleClick: (time: number)=>void
  12. // 气泡的数组
  13. @Local bubbles: Array<Location> = []
  14. @Local h: number = 0
  15. @Local w: number = 0
  16. timeC: number = -1
  17. // 训练开始
  18. @Monitor('trainStarted') startTrain() {
  19. if(this.trainStarted == 1) {
  20. // 这里进行气泡的重新赋值
  21. this.bubbles.forEach(item => {
  22. let time = new Date().getTime() - item.id!
  23. let second = Math.max(this.bubbleConnect.bubbleDisappearTime * 1000 - item.id!, 1)
  24. item.id = time
  25. if(item.timer != -1) clearTimeout(item.timer)
  26. item.timer = setTimeout(() => {
  27. this.deleteBubble(item.id!)
  28. }, second)
  29. })
  30. this.timeC = setInterval(() => {
  31. let location = this.generateBubbleLocation()
  32. this.getUIContext().animateTo({ duration: 300 }, () => {
  33. if(this.bubbles.length == 10) {
  34. this.deleteBubble(this.bubbles[0].id!, false)
  35. }
  36. this.bubbles.push(location)
  37. })
  38. }, this.bubbleConnect.bubbleFrequency * 1000)
  39. } else if (this.trainStarted == 0) {
  40. clearInterval(this.timeC)
  41. // 暂停不只是要暂停定时器,还要暂停气泡的消失
  42. // 1. 将time设置为 当前花费的时间
  43. // 2. 在再次开始时, 将 time 设置为 new Date - time
  44. // 3. 设置的消失时间也要变化
  45. this.bubbles.forEach(item => {
  46. clearTimeout(item.timer)
  47. item.timer = -1
  48. let time = new Date().getTime() - item.id!
  49. item.id = time
  50. })
  51. } else {
  52. // 重置
  53. if(this.timeC != -1) clearInterval(this.timeC)
  54. this.bubbles.forEach(item => {
  55. if(item.timer != -1)
  56. clearTimeout(item.timer)
  57. })
  58. this.bubbles = []
  59. }
  60. }
  61. // 生成气泡位置
  62. generateBubbleLocation(): Location {
  63. // 计算气泡的最大位置范围,避免气泡超出容器边界
  64. const maxX = this.w - 50;
  65. const maxY = this.h - 50;
  66. // 生成随机坐标,确保气泡完全在可视区域内
  67. const x = Math.random() * maxX;
  68. const y = Math.random() * maxY;
  69. // 创建带随机坐标的location实例
  70. let location = new Location(x, y);
  71. // 设置定时器,在指定时间后自动消失
  72. location.timer = setTimeout(() => {
  73. location.timer = -1
  74. this.deleteBubble(location.id!);
  75. }, this.bubbleConnect.bubbleDisappearTime * 1000); // 将秒转换为毫秒
  76. location.id = new Date().getTime()
  77. return location;
  78. }
  79. // 删除气泡
  80. deleteBubble(id: number, isEvent: boolean = false) {
  81. if(this.trainStarted != 1 && isEvent == true) return
  82. let index = this.bubbles.findIndex(item => item.id == id)
  83. let location = this.bubbles[index]
  84. let time = new Date().getTime() - location.id!
  85. clearTimeout(location.timer)
  86. this.getUIContext().animateTo({ duration: 300 }, () => {
  87. this.bubbles.splice(index, 1)
  88. })
  89. if(isEvent) {
  90. this.bubbleClick(time)
  91. }
  92. }
  93. build() {
  94. Column() {
  95. Repeat(this.bubbles)
  96. .each(item => {
  97. Image($r('app.media.icon_bubble'))
  98. .width(50)
  99. .aspectRatio(1)
  100. .position({x: item.item.x, y: item.item.y})
  101. .onClick(() => { this.deleteBubble(item.item.id!, true) })
  102. })
  103. .key(item => `${item.x}-${item.y}`)
  104. }
  105. .width("100%")
  106. .height("100%")
  107. .borderRadius(10)
  108. .backgroundColor(Color.Black)
  109. .onAreaChange((o, n) => {
  110. this.w = n.width as number
  111. this.h = n.height as number
  112. })
  113. }
  114. }