index.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. const STATE = {
  2. NONE: -1,
  3. MOVE: 0,
  4. ZOOM_OR_PAN: 1
  5. }
  6. Component({
  7. behaviors: [require('../../common/share-behavior').default],
  8. properties: {
  9. a: Number,
  10. },
  11. data: {
  12. loaded: false,
  13. arReady: false,
  14. },
  15. lifetimes: {
  16. async attached() {
  17. console.log('data', this.data)
  18. }
  19. },
  20. methods: {
  21. handleReady({detail}) {
  22. const xrScene = this.scene = detail.value;
  23. this.mat = new (wx.getXrFrameSystem().Matrix4)();
  24. console.log('xr-scene', xrScene);
  25. const { width, height } = this.scene
  26. // 旋转缩放相关配置
  27. this.radius = (width + height) / 4
  28. this.rotateSpeed = 5
  29. this.handleTouchStart = (event) => {
  30. this.mouseInfo = { startX: 0, startY: 0, isDown: false, startPointerDistance: 0, state: STATE.NONE }
  31. this.mouseInfo.isDown = true
  32. const touch0 = event.touches[0]
  33. const touch1 = event.touches[1]
  34. if (event.touches.length === 1) {
  35. this.mouseInfo.startX = touch0.pageX
  36. this.mouseInfo.startY = touch0.pageY
  37. this.mouseInfo.state = STATE.MOVE
  38. } else if (event.touches.length === 2) {
  39. const dx = (touch0.pageX - touch1.pageX)
  40. const dy = (touch0.pageY - touch1.pageY)
  41. this.mouseInfo.startPointerDistance = Math.sqrt(dx * dx + dy * dy)
  42. this.mouseInfo.startX = (touch0.pageX + touch1.pageX) / 2
  43. this.mouseInfo.startY = (touch0.pageY + touch1.pageY) / 2
  44. this.mouseInfo.state = STATE.ZOOM_OR_PAN
  45. }
  46. this.scene.event.add('touchmove', this.handleTouchMove.bind(this))
  47. this.scene.event.addOnce('touchend', this.handleTouchEnd.bind(this))
  48. },
  49. this.handleTouchMove = (event) => {
  50. const mouseInfo = this.mouseInfo
  51. if (!mouseInfo.isDown) {
  52. return
  53. }
  54. switch (mouseInfo.state) {
  55. case STATE.MOVE:
  56. if (event.touches.length === 1) {
  57. this.handleRotate(event)
  58. } else if (event.touches.length === 2) {
  59. // 支持单指变双指,兼容双指操作但是两根手指触屏时间不一致的情况
  60. this.scene.event.remove('touchmove', this.handleTouchMove)
  61. this.scene.event.remove('touchend', this.handleTouchEnd)
  62. this.handleTouchStart(event)
  63. }
  64. break
  65. case STATE.ZOOM_OR_PAN:
  66. if (event.touches.length === 1) {
  67. // 感觉双指松掉一指的行为还是不要自动切换成旋转了,实际操作有点奇怪
  68. }
  69. else if (event.touches.length === 2) {
  70. this.handleZoomOrPan(event)
  71. }
  72. break
  73. default:
  74. break
  75. }
  76. }
  77. this.handleTouchEnd = (event) => {
  78. this.mouseInfo.isDown = false
  79. this.mouseInfo.state = STATE.NONE
  80. this.scene.event.remove('touchmove', this.handleTouchMove)
  81. this.scene.event.addOnce('touchstart', this.handleTouchStart)
  82. }
  83. this.handleRotate = (event) => {
  84. const x = event.touches[0].pageX
  85. const y = event.touches[0].pageY
  86. const { startX, startY } = this.mouseInfo
  87. const theta = (x - startX) / this.radius * - this.rotateSpeed
  88. const phi = (y - startY) / this.radius * - this.rotateSpeed
  89. if (Math.abs(theta) < .01 && Math.abs(phi) < .01) {
  90. return
  91. }
  92. this.gltfItemTRS.rotation.x -= phi
  93. this.gltfItemSubTRS.rotation.y -= theta
  94. this.mouseInfo.startX = x
  95. this.mouseInfo.startY = y
  96. }
  97. this.handleZoomOrPan = (event) => {
  98. const touch0 = event.touches[0]
  99. const touch1 = event.touches[1]
  100. const dx = (touch0.pageX - touch1.pageX)
  101. const dy = (touch0.pageY - touch1.pageY)
  102. const distance = Math.sqrt(dx * dx + dy * dy)
  103. let deltaScale = distance - this.mouseInfo.startPointerDistance
  104. this.mouseInfo.startPointerDistance = distance
  105. this.mouseInfo.startX = (touch0.pageX + touch1.pageX) / 2
  106. this.mouseInfo.startY = (touch0.pageY + touch1.pageY) / 2
  107. if (deltaScale < -2) {
  108. deltaScale = -2
  109. } else if (deltaScale > 2) {
  110. deltaScale = 2
  111. }
  112. const s = deltaScale * 0.02 + 1
  113. // 缩小
  114. this.gltfItemTRS.scale.x *= s
  115. this.gltfItemTRS.scale.y *= s
  116. this.gltfItemTRS.scale.z *= s
  117. }
  118. },
  119. handleAssetsProgress: function({detail}) {
  120. console.log('assets progress', detail.value);
  121. },
  122. handleAssetsLoaded: function({detail}) {
  123. console.log('assets loaded', detail.value);
  124. // this.setData({loaded: true});
  125. this.placedFlag = false;
  126. this.scene.event.addOnce('touchstart', this.placeNode.bind(this));
  127. },
  128. handleARReady: function({detail}) {
  129. console.log('arReady', this.scene.ar.arVersion);
  130. },
  131. placeNode(event) {
  132. if (this.placedFlag) {
  133. return;
  134. }
  135. const xrFrameSystem = wx.getXrFrameSystem()
  136. this.placedFlag = true;
  137. this.scene.ar.placeHere('setitem', true)
  138. const anchorTRS = this.scene.getElementById('anchor').getComponent(xrFrameSystem.Transform)
  139. anchorTRS.setData({ visible: false })
  140. anchorTRS.scale.x = 0
  141. anchorTRS.scale.y = 0
  142. anchorTRS.scale.z = 0
  143. wx.setKeepScreenOn({ keepScreenOn: true })
  144. // 获取改动元素
  145. this.gltfItemTRS = this.scene.getElementById('preview-model').getComponent(xrFrameSystem.Transform)
  146. this.gltfItemSubTRS = this.scene.getElementById('preview-model-sub').getComponent(xrFrameSystem.Transform)
  147. // 开启旋转缩放逻辑
  148. this.scene.event.addOnce('touchstart', this.handleTouchStart)
  149. }
  150. }
  151. })