AutoOrbitTool.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * AutoOrbitTool.js
  3. *
  4. * @author realor
  5. */
  6. import { Tool } from './Tool.js'
  7. import { I18N } from '../i18n/I18N.js'
  8. import * as THREE from '../lib/three.module.js'
  9. class AutoOrbitTool extends Tool {
  10. //自动左右旋转
  11. constructor(application, options) {
  12. super(application)
  13. this.name = 'auto_orbit'
  14. this.label = 'tool.auto_orbit.label'
  15. this.help = 'tool.auto_orbit.help'
  16. this.className = 'auto_orbit'
  17. this.setOptions(options)
  18. this.theta = 0.8
  19. this.phi = 0.1
  20. this.radius = 30
  21. this.minPolarAngle = 0 // radians
  22. this.maxPolarAngle = Math.PI // radians
  23. this.minDistance = 0
  24. this.maxDistance = Infinity
  25. // internals
  26. this.vector = new THREE.Vector3()
  27. this.position = new THREE.Vector3()
  28. this.center = new THREE.Vector3()
  29. this.time = 0
  30. this._animate = this.animate.bind(this)
  31. }
  32. activate() {
  33. const application = this.application
  34. var camera = application.camera
  35. var container = application.container
  36. camera.aspect = container.clientWidth / container.clientHeight
  37. camera.updateProjectionMatrix()
  38. var matrix = camera.matrix
  39. var v = new THREE.Vector3()
  40. v.x = matrix.elements[8]
  41. v.y = matrix.elements[9]
  42. v.z = matrix.elements[10]
  43. v.normalize()
  44. this.theta = Math.atan2(v.x, v.y)
  45. this.phi = Math.acos(v.z)
  46. this.center.x = camera.position.x - 10 * v.x
  47. this.center.y = camera.position.y - 10 * v.y
  48. this.center.z = camera.position.z - 10 * v.z
  49. this.radius = 10
  50. application.addEventListener('animation', this._animate)
  51. }
  52. deactivate() {
  53. const application = this.application
  54. application.removeEventListener('animation', this._animate)
  55. }
  56. animate(event) {
  57. const application = this.application
  58. var camera = application.camera
  59. var delta = event.delta
  60. this.time += delta
  61. this.theta += delta * 0.2
  62. this.phi = -0.15 + 0.5 * Math.PI + 0.3 * Math.sin(0.05 * Math.cos(0.01 * this.time) * this.time)
  63. // restrict radius
  64. if (this.radius < this.minDistance) this.radius = this.minDistance
  65. else if (this.radius > this.maxDistance) this.radius = this.maxDistance
  66. // restrict phi to be between desired limits
  67. this.phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.phi))
  68. this.vector.x = Math.sin(this.phi) * Math.sin(this.theta)
  69. this.vector.y = Math.sin(this.phi) * Math.cos(this.theta)
  70. this.vector.z = Math.cos(this.phi)
  71. camera.updateMatrixWorld()
  72. this.position.copy(this.center)
  73. this.vector.setLength(this.radius)
  74. this.position.add(this.vector)
  75. camera.position.copy(this.position)
  76. camera.updateMatrix()
  77. camera.lookAt(this.center)
  78. camera.updateMatrix()
  79. application.notifyObjectsChanged(camera, this)
  80. }
  81. }
  82. export { AutoOrbitTool }