View.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. import * as THREE from "../../libs/three.js/build/three.module.js";
  2. import {transitions, easing, lerp} from '../utils/transitions.js'
  3. import Common from '../utils/Common'
  4. export class View{
  5. constructor () {
  6. this.position = new THREE.Vector3(0, 0, 0);
  7. this.yaw = 0//Math.PI / 4; // = 4dkk lon + 90
  8. this._pitch = 0//-Math.PI / 4; //上下旋转 = 4dkk lat
  9. this.radius = 1;
  10. this.maxPitch = Math.PI / 2;
  11. this.minPitch = -Math.PI / 2;
  12. this.zoom = 1
  13. }
  14. applyToCamera(camera){//add
  15. camera.position.copy(this.position);
  16. camera.rotation.order = "ZXY";
  17. camera.rotation.x = Math.PI / 2 + this.pitch;
  18. camera.rotation.z = this.yaw;
  19. camera.updateMatrix();
  20. camera.updateMatrixWorld();
  21. camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
  22. }
  23. copy(a){
  24. Common.CopyClassObject(this, a)
  25. }
  26. clone () {
  27. /* let c = new View();
  28. c.yaw = this.yaw;
  29. c._pitch = this.pitch;
  30. c.radius = this.radius;
  31. c.maxPitch = this.maxPitch;
  32. c.minPitch = this.minPitch;
  33. return c; */
  34. return Common.CloneClassObject(this)
  35. }
  36. get pitch () {
  37. return this._pitch;
  38. }
  39. set pitch (angle) {
  40. this._pitch = Math.max(Math.min(angle, this.maxPitch), this.minPitch);
  41. }
  42. get direction () {
  43. let dir = new THREE.Vector3(0, 1, 0);
  44. dir.applyAxisAngle(new THREE.Vector3(1, 0, 0), this.pitch);
  45. dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  46. return dir;
  47. }
  48. set direction (dir) {
  49. //if(dir.x === dir.y){
  50. if(dir.x === 0 && dir.y === 0){
  51. this.pitch = Math.PI / 2 * Math.sign(dir.z);
  52. }else{
  53. let yaw = Math.atan2(dir.y, dir.x) - Math.PI / 2;
  54. let pitch = Math.atan2(dir.z, Math.sqrt(dir.x * dir.x + dir.y * dir.y));
  55. this.yaw = yaw;
  56. this.pitch = pitch;
  57. }
  58. }
  59. lookAt(t){
  60. let V;
  61. if(arguments.length === 1){
  62. V = new THREE.Vector3().subVectors(t, this.position);
  63. }else if(arguments.length === 3){
  64. V = new THREE.Vector3().subVectors(new THREE.Vector3(...arguments), this.position);
  65. }
  66. let radius = V.length();
  67. let dir = V.normalize();
  68. this.radius = radius;
  69. this.direction = dir;
  70. }
  71. getPivot () {
  72. return new THREE.Vector3().addVectors(this.position, this.direction.multiplyScalar(this.radius));
  73. }
  74. getSide () {
  75. let side = new THREE.Vector3(1, 0, 0);
  76. side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  77. return side;
  78. }
  79. pan (x, y) {
  80. let dir = new THREE.Vector3(0, 1, 0);
  81. dir.applyAxisAngle(new THREE.Vector3(1, 0, 0), this.pitch);
  82. dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  83. // let side = new THREE.Vector3(1, 0, 0);
  84. // side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  85. let side = this.getSide();
  86. let up = side.clone().cross(dir);
  87. let pan = side.multiplyScalar(x).add(up.multiplyScalar(y));
  88. this.position = this.position.add(pan);
  89. // this.target = this.target.add(pan);
  90. }
  91. translate (x, y, z) {
  92. let dir = new THREE.Vector3(0, 1, 0);
  93. dir.applyAxisAngle(new THREE.Vector3(1, 0, 0), this.pitch);
  94. dir.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  95. let side = new THREE.Vector3(1, 0, 0);
  96. side.applyAxisAngle(new THREE.Vector3(0, 0, 1), this.yaw);
  97. let up = side.clone().cross(dir);
  98. let t = side.multiplyScalar(x)
  99. .add(dir.multiplyScalar(y))
  100. .add(up.multiplyScalar(z));
  101. this.position = this.position.add(t);
  102. this.restrictPos()
  103. }
  104. translateWorld (x, y, z) {
  105. this.position.x += x;
  106. this.position.y += y;
  107. this.position.z += z;
  108. this.restrictPos()
  109. }
  110. /* setView(position, target, duration = 0, callback = null, onUpdate = null, Easing=''){
  111. let endPosition = null;
  112. if(position instanceof Array){
  113. endPosition = new THREE.Vector3(...position);
  114. }else if(position.x != null){
  115. endPosition = position.clone();
  116. }
  117. let endTarget = null;
  118. if(target instanceof Array){
  119. endTarget = new THREE.Vector3(...target);
  120. }else if(target.x != null){
  121. endTarget = target.clone();
  122. }
  123. const startPosition = this.position.clone();
  124. const startTarget = this.getPivot();
  125. //const endPosition = position.clone();
  126. //const endTarget = target.clone();
  127. let easing = Easing ? TWEEN.Easing.Quartic[Easing] : TWEEN.Easing.Quartic.Out ;
  128. if(duration === 0){
  129. this.position.copy(endPosition);
  130. this.lookAt(endTarget);
  131. }else{
  132. let value = {x: 0};
  133. let tween = new TWEEN.Tween(value).to({x: 1}, duration);
  134. tween.easing(easing);
  135. //this.tweens.push(tween);
  136. tween.onUpdate(() => {
  137. let t = value.x;
  138. //console.log(t);
  139. const pos = new THREE.Vector3(
  140. (1 - t) * startPosition.x + t * endPosition.x,
  141. (1 - t) * startPosition.y + t * endPosition.y,
  142. (1 - t) * startPosition.z + t * endPosition.z,
  143. );
  144. const target = new THREE.Vector3(
  145. (1 - t) * startTarget.x + t * endTarget.x,
  146. (1 - t) * startTarget.y + t * endTarget.y,
  147. (1 - t) * startTarget.z + t * endTarget.z,
  148. );
  149. this.position.copy(pos);
  150. this.lookAt(target);
  151. onUpdate && onUpdate(t)//add
  152. });
  153. tween.start();
  154. tween.onComplete(() => {
  155. if(callback){
  156. callback();
  157. }
  158. });
  159. }
  160. } */
  161. setView(position, target, duration = 0, callback = null, onUpdate = null, Easing=''){
  162. //待改成quater渐变
  163. let endPosition = null;
  164. /* if(position instanceof Array){
  165. endPosition = new THREE.Vector3(...position);
  166. }else */if(position.x != null){
  167. endPosition = new THREE.Vector3().copy(position)
  168. }
  169. let endTarget = null;
  170. /* if(target instanceof Array){
  171. endTarget = new THREE.Vector3(...target);
  172. }else */if(target && target.x != null){
  173. endTarget = new THREE.Vector3().copy(target)
  174. }
  175. const startPosition = this.position.clone();
  176. const startTarget = this.getPivot();
  177. if(duration === 0){
  178. this.position.copy(endPosition);
  179. this.restrictPos()
  180. endTarget && this.lookAt(endTarget);
  181. onUpdate && onUpdate(1)
  182. callback && callback()
  183. }else{
  184. transitions.start(lerp.vector(this.position, endPosition, (pos, progress)=>{
  185. let t = progress
  186. //console.log(t);
  187. if(endTarget){
  188. const target = new THREE.Vector3(
  189. (1 - t) * startTarget.x + t * endTarget.x,
  190. (1 - t) * startTarget.y + t * endTarget.y,
  191. (1 - t) * startTarget.z + t * endTarget.z,
  192. );
  193. this.lookAt(target);
  194. }
  195. this.restrictPos()
  196. onUpdate && onUpdate(t)//add
  197. }), duration, callback, 0, Easing ? easing[Easing] : easing.easeInOutQuad );
  198. }
  199. }
  200. restrictPos(){//add
  201. if(this.limitBound){
  202. this.position.clamp(this.limitBound.min, this.limitBound.max)
  203. }
  204. }
  205. setCubeView(dir) {
  206. switch(dir) {
  207. case "Front":
  208. this.yaw = 0;
  209. this.pitch = 0;
  210. break;
  211. case "Back":
  212. this.yaw = Math.PI;
  213. this.pitch = 0;
  214. break;
  215. case "Left":
  216. this.yaw = -Math.PI / 2;
  217. this.pitch = 0;
  218. break;
  219. case "Right":
  220. this.yaw = Math.PI / 2;
  221. this.pitch = 0;
  222. break;
  223. case "Top":
  224. this.yaw = 0;
  225. this.pitch = -Math.PI / 2;
  226. break;
  227. case "Bottom":
  228. this.yaw = -Math.PI;
  229. this.pitch = Math.PI / 2;
  230. break;
  231. }
  232. }
  233. };