tpanorama.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. 'use strict';
  2. var _three = require('three');
  3. var t = _interopRequireWildcard(_three);
  4. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  5. var Vector2 = t.Vector2,
  6. PerspectiveCamera = t.PerspectiveCamera,
  7. Vector3 = t.Vector3,
  8. OrthographicCamera = t.OrthographicCamera,
  9. Scene = t.Scene,
  10. SphereGeometry = t.SphereGeometry,
  11. Mesh = t.Mesh,
  12. MeshBasicMaterial = t.MeshBasicMaterial,
  13. Raycaster = t.Raycaster,
  14. ImageUtils = t.ImageUtils,
  15. WebGLRenderer = t.WebGLRenderer,
  16. Texture = t.Texture,
  17. SpriteMaterial = t.SpriteMaterial,
  18. Sprite = t.Sprite,
  19. TextureLoader = t.TextureLoader,
  20. tMath = t.Math;
  21. var _camera, _scene, _renderer;
  22. var _cameraOrtho, _sceneOrtho;
  23. var _fov = 75;
  24. var _pRadius = 1000;
  25. var _raycaster;
  26. var _container;
  27. var _isUserInteracting = false;
  28. var _lon = 0,
  29. _lat = 0;
  30. var _onPointerDownLon = 0,
  31. _onPointerDownLat = 0;
  32. var _onPointerDownPointerX = 0,
  33. _onPointerDownPointerY = 0;
  34. var _mouse = new Vector2();
  35. var _clickableObjects = [];
  36. var _sprites = [];
  37. var _lables = [];
  38. var _count1 = 1;
  39. var options = {
  40. container: 'panoramaConianer', //容器
  41. url: 'resources/img/panorama/pano-7.jpg', //全景图路径
  42. lables: [], //标记 {position:{lon:114,lat:38},logoUrl:'lableLogo.png',text:'我是一个标记'}
  43. widthSegments: 60, //水平切段数
  44. heightSegments: 40, //垂直切段数(值小粗糙速度快,值大精细速度慢)
  45. pRadius: 1000, //全景球的半径,推荐使用默认值
  46. minFocalLength: 1, //镜头最a小拉近距离
  47. maxFocalLength: 100, //镜头最大拉近距离
  48. showlable: 'show' // show,click
  49. };
  50. function tpanorama(opt) {
  51. this.render(opt);
  52. }
  53. tpanorama.prototype = {
  54. constructor: undefined,
  55. def: {},
  56. render: function render(opt) {
  57. var _this = this;
  58. this.def = extend(options, opt, true);
  59. document.getElementById(this.def.container).innerHTML = '';
  60. _lables = [];
  61. initContainer(this.def.container);
  62. initCamera();
  63. initRaycaster();
  64. makePanorama(this.def.pRadius, this.def.widthSegments, this.def.heightSegments, this.def.url);
  65. initRenderer();
  66. initLable(this.def.lables, this.def.showlable);
  67. _container.addEventListener('mousedown', onDocumentMouseDown, false);
  68. _container.addEventListener('mousemove', onDocumentMouseMove, false);
  69. _container.addEventListener('mouseup', onDocumentMouseUp, false);
  70. _container.addEventListener('mousewheel', function (e) {
  71. onDocumentMouseWheel(e, _this.def.minFocalLength, _this.def.maxFocalLength);
  72. }, false);
  73. _container.addEventListener('DOMMouseScroll', function (e) {
  74. onDocumentMouseWheel(e, _this.def.minFocalLength, _this.def.maxFocalLength);
  75. }, false);
  76. _container.addEventListener('click', onDocumentMouseClick, false);
  77. global.addEventListener('resize', onWindowResize, false);
  78. animate();
  79. }
  80. };
  81. function extend(o, n, override) {
  82. for (var key in n) {
  83. if (n.hasOwnProperty(key) && (!o.hasOwnProperty(key) || override)) {
  84. o[key] = n[key];
  85. }
  86. }
  87. return o;
  88. }
  89. function isEmpty(str) {
  90. if (str == undefined || str == null || str == "" || typeof str == 'undefined') {
  91. return true;
  92. }
  93. }
  94. function initContainer(c) {
  95. _container = document.getElementById(c);
  96. }
  97. function initCamera() {
  98. _camera = new PerspectiveCamera(_fov, window.innerWidth / window.innerHeight, 1, 1100);
  99. _camera.target = new Vector3(0, 0, 0);
  100. _cameraOrtho = new OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, 1, 10);
  101. _cameraOrtho.position.z = 10;
  102. _scene = new Scene();
  103. _sceneOrtho = new Scene();
  104. }
  105. function initRaycaster() {
  106. _raycaster = new Raycaster();
  107. }
  108. function makePanorama(pRadius, widthSegments, heightSegments, u) {
  109. var mesh = new Mesh(new SphereGeometry(pRadius, widthSegments, heightSegments), new MeshBasicMaterial({ map: ImageUtils.loadTexture(u) }));
  110. mesh.scale.x = -1;
  111. _scene.add(mesh);
  112. }
  113. function initRenderer() {
  114. _renderer = new WebGLRenderer();
  115. _renderer.setSize(window.innerWidth, window.innerHeight);
  116. _renderer.autoClear = false;
  117. _container.appendChild(_renderer.domElement);
  118. }
  119. function onDocumentMouseDown(event) {
  120. event.preventDefault();
  121. _isUserInteracting = true;
  122. _onPointerDownPointerX = event.clientX;
  123. _onPointerDownPointerY = event.clientY;
  124. _onPointerDownLon = _lon;
  125. _onPointerDownLat = _lat;
  126. }
  127. function onDocumentMouseMove(event) {
  128. if (_isUserInteracting) {
  129. _lon = (_onPointerDownPointerX - event.clientX) * 0.1 + _onPointerDownLon;
  130. _lat = (event.clientY - _onPointerDownPointerY) * 0.1 + _onPointerDownLat;
  131. }
  132. }
  133. function onDocumentMouseUp() {
  134. _isUserInteracting = false;
  135. }
  136. function onDocumentMouseClick(event) {
  137. _mouse.x = event.clientX / window.innerWidth * 2 - 1;
  138. _mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  139. _raycaster.setFromCamera(_mouse, _cameraOrtho);
  140. var intersects = _raycaster.intersectObjects(_clickableObjects);
  141. intersects.forEach(function (element) {
  142. alert("Intersection: " + element.object.name);
  143. });
  144. }
  145. function onDocumentMouseWheel(ev, minFocalLength, maxFocalLength) {
  146. var ev = ev || window.event;
  147. var down = true;
  148. var m = _camera.getFocalLength();
  149. down = ev.wheelDelta ? ev.wheelDelta < 0 : ev.detail > 0;
  150. if (down) {
  151. if (m > minFocalLength) {
  152. m -= m * 0.05;
  153. _camera.setFocalLength(m);
  154. }
  155. } else {
  156. if (m < maxFocalLength) {
  157. m += m * 0.05;
  158. _camera.setFocalLength(m);
  159. }
  160. }
  161. if (ev.preventDefault) {
  162. ev.preventDefault();
  163. }
  164. return false;
  165. }
  166. function onWindowResize() {
  167. _camera.aspect = window.innerWidth / window.innerHeight;
  168. _camera.projectionMatrix.makePerspective(_fov, _camera.aspect, 1, 1100);
  169. _camera.updateProjectionMatrix();
  170. _cameraOrtho.left = -window.innerWidth / 2;
  171. _cameraOrtho.right = window.innerWidth / 2;
  172. _cameraOrtho.top = window.innerHeight / 2;
  173. _cameraOrtho.bottom = -window.innerHeight / 2;
  174. _cameraOrtho.updateProjectionMatrix();
  175. _renderer.setSize(window.innerWidth, window.innerHeight);
  176. }
  177. function initLable(lables, showlable) {
  178. if (showlable == 'show') {
  179. for (var i = 0; i < lables.length; i++) {
  180. _lables.push(createLableSprite(_sceneOrtho, lables[i].text, lables[i].position));
  181. }
  182. } else if (showlable == 'click') {
  183. for (var i = 0; i < lables.length; i++) {
  184. _sprites.push(createSprite(lables[i].position, lables[i].logoUrl, lables[i].text));
  185. }
  186. }
  187. }
  188. function createLableSprite(scene, name, position) {
  189. var canvas1 = document.createElement('canvas');
  190. var context1 = canvas1.getContext('2d');
  191. var metrics = context1.measureText(name);
  192. var width = metrics.width * 1.5;
  193. context1.font = "10px 宋体";
  194. context1.fillStyle = "rgba(0,0,0,0.95)"; // white border
  195. context1.fillRect(0, 0, width + 8, 20 + 8);
  196. context1.fillStyle = "rgba(0,0,0,0.2)"; // black filler
  197. context1.fillRect(2, 2, width + 4, 20 + 4);
  198. context1.fillStyle = "rgba(255,255,255,0.95)"; // text color
  199. context1.fillText(name, 4, 20);
  200. var texture1 = new Texture(canvas1);
  201. texture1.needsUpdate = true;
  202. var spriteMaterial = new SpriteMaterial({ map: texture1 });
  203. var sprite1 = new Sprite(spriteMaterial);
  204. sprite1.scale.set(1.0, 1.0, 1.0);
  205. sprite1.position.set(0, 0, 0);
  206. sprite1.name = name;
  207. var lable = {
  208. name: name,
  209. pos: position,
  210. canvas: canvas1,
  211. context: context1,
  212. texture: texture1,
  213. sprite: sprite1
  214. };
  215. _sceneOrtho.add(lable.sprite);
  216. return lable;
  217. }
  218. function createSprite(position, url, name) {
  219. var textureLoader = new TextureLoader();
  220. var ballMaterial = new SpriteMaterial({
  221. map: textureLoader.load(url)
  222. });
  223. var sp1 = {
  224. pos: position,
  225. name: name,
  226. sprite: new Sprite(ballMaterial)
  227. };
  228. sp1.sprite.scale.set(32, 32, 1.0);
  229. sp1.sprite.position.set(0, 0, 0);
  230. sp1.sprite.name = name;
  231. _sceneOrtho.add(sp1.sprite);
  232. _clickableObjects.push(sp1.sprite);
  233. return sp1;
  234. }
  235. function animate() {
  236. requestAnimationFrame(animate);
  237. render();
  238. }
  239. function render() {
  240. calPosition();
  241. addSprites();
  242. runRender();
  243. }
  244. function calPosition() {
  245. _lat = Math.max(-85, Math.min(85, _lat));
  246. var phi = tMath.degToRad(90 - _lat);
  247. var theta = tMath.degToRad(_lon);
  248. _camera.target.x = _pRadius * Math.sin(phi) * Math.cos(theta);
  249. _camera.target.y = _pRadius * Math.cos(phi);
  250. _camera.target.z = _pRadius * Math.sin(phi) * Math.sin(theta);
  251. _camera.lookAt(_camera.target);
  252. }
  253. function addSprites() {
  254. if (typeof _sprites != "undefined") {
  255. for (var i = 0; i < _sprites.length; i++) {
  256. var wp = geoPosition2World(_sprites[i].pos.lon, _sprites[i].pos.lat);
  257. var sp = worldPostion2Screen(wp, _camera);
  258. var test = wp.clone();
  259. test.project(_camera);
  260. if (test.x > -1 && test.x < 1 && test.y > -1 && test.y < 1 && test.z > -1 && test.z < 1) {
  261. _sprites[i].sprite.scale.set(32, 32, 32);
  262. _sprites[i].sprite.position.set(sp.x, sp.y, 1);
  263. } else {
  264. _sprites[i].sprite.scale.set(1.0, 1.0, 1.0);
  265. _sprites[i].sprite.position.set(0, 0, 0);
  266. }
  267. }
  268. }
  269. if (typeof _lables != "undefined") {
  270. for (var i = 0; i < _lables.length; i++) {
  271. var wp = geoPosition2World(_lables[i].pos.lon, _lables[i].pos.lat);
  272. var sp = worldPostion2Screen(wp, _camera);
  273. var test = wp.clone();
  274. test.project(_camera);
  275. if (test.x > -1 && test.x < 1 && test.y > -1 && test.y < 1 && test.z > -1 && test.z < 1) {
  276. var metrics = _lables[i].context.measureText(_lables[i].name);
  277. var width = metrics.width * 3.5;
  278. _lables[i].sprite.scale.set(400, 150, 1.0);
  279. _lables[i].sprite.position.set(sp.x + width, sp.y - 40, 1);
  280. } else {
  281. _lables[i].sprite.scale.set(1.0, 1.0, 1.0);
  282. _lables[i].sprite.position.set(0, 0, 0);
  283. }
  284. }
  285. }
  286. }
  287. function geoPosition2World(lon, lat) {
  288. lat = Math.max(-85, Math.min(85, lat));
  289. var phi = tMath.degToRad(90 - lat);
  290. var theta = tMath.degToRad(lon);
  291. var result = {
  292. x: _pRadius * Math.sin(phi) * Math.cos(theta),
  293. y: _pRadius * Math.cos(phi),
  294. z: _pRadius * Math.sin(phi) * Math.sin(theta)
  295. };
  296. return new Vector3(result.x, result.y, result.z);
  297. }
  298. function worldPostion2Screen(world_vector, camera) {
  299. var vector = world_vector.clone();
  300. vector.project(camera);
  301. var result = {
  302. x: Math.round((vector.x + 1) * window.innerWidth / 2 - window.innerWidth / 2),
  303. y: Math.round(window.innerHeight / 2 - (-vector.y + 1) * window.innerHeight / 2),
  304. z: 0
  305. };
  306. return new Vector3(result.x, result.y, result.z);
  307. }
  308. function runRender() {
  309. _renderer.clear();
  310. _renderer.render(_scene, _camera);
  311. _renderer.clearDepth();
  312. _renderer.render(_sceneOrtho, _cameraOrtho);
  313. }
  314. window.tpanorama = tpanorama;
  315. module.exports = tpanorama;