KmlTour.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import defined from "../Core/defined.js";
  2. import Event from "../Core/Event.js";
  3. /**
  4. * @alias KmlTour
  5. * @constructor
  6. *
  7. * @param {String} name name parsed from KML
  8. * @param {String} id id parsed from KML
  9. * @param {Array} playlist array with KMLTourFlyTos, KMLTourWaits and KMLTourSoundCues
  10. */
  11. function KmlTour(name, id) {
  12. /**
  13. * Id of kml gx:Tour entry
  14. * @type String
  15. */
  16. this.id = id;
  17. /**
  18. * Tour name
  19. * @type String
  20. */
  21. this.name = name;
  22. /**
  23. * Index of current entry from playlist
  24. * @type Number
  25. */
  26. this.playlistIndex = 0;
  27. /**
  28. * Array of playlist entries
  29. * @type Array
  30. */
  31. this.playlist = [];
  32. /**
  33. * Event will be called when tour starts to play,
  34. * before any playlist entry starts to play.
  35. * @type Event
  36. */
  37. this.tourStart = new Event();
  38. /**
  39. * Event will be called when all playlist entries are
  40. * played, or tour playback being canceled.
  41. *
  42. * If tour playback was terminated, event callback will
  43. * be called with terminated=true parameter.
  44. * @type Event
  45. */
  46. this.tourEnd = new Event();
  47. /**
  48. * Event will be called when entry from playlist starts to play.
  49. *
  50. * Event callback will be called with curent entry as first parameter.
  51. * @type Event
  52. */
  53. this.entryStart = new Event();
  54. /**
  55. * Event will be called when entry from playlist ends to play.
  56. *
  57. * Event callback will be called with following parameters:
  58. * 1. entry - entry
  59. * 2. terminated - true if playback was terminated by calling {@link KmlTour#stop}
  60. * @type Event
  61. */
  62. this.entryEnd = new Event();
  63. this._activeEntries = [];
  64. }
  65. /**
  66. * Add entry to this tour playlist.
  67. *
  68. * @param {KmlTourFlyTo|KmlTourWait} entry an entry to add to the playlist.
  69. */
  70. KmlTour.prototype.addPlaylistEntry = function (entry) {
  71. this.playlist.push(entry);
  72. };
  73. /**
  74. * Play this tour.
  75. *
  76. * @param {Viewer} viewer viewer widget.
  77. * @param {Object} [cameraOptions] these options will be merged with {@link Camera#flyTo}
  78. * options for FlyTo playlist entries.
  79. */
  80. KmlTour.prototype.play = function (viewer, cameraOptions) {
  81. this.tourStart.raiseEvent();
  82. var tour = this;
  83. playEntry.call(this, viewer, cameraOptions, function (terminated) {
  84. tour.playlistIndex = 0;
  85. // Stop nonblocking entries
  86. if (!terminated) {
  87. cancelAllEntries(tour._activeEntries);
  88. }
  89. tour.tourEnd.raiseEvent(terminated);
  90. });
  91. };
  92. /**
  93. * Stop curently playing tour.
  94. */
  95. KmlTour.prototype.stop = function () {
  96. cancelAllEntries(this._activeEntries);
  97. };
  98. // Stop all activeEntries.
  99. function cancelAllEntries(activeEntries) {
  100. for (
  101. var entry = activeEntries.pop();
  102. entry !== undefined;
  103. entry = activeEntries.pop()
  104. ) {
  105. entry.stop();
  106. }
  107. }
  108. // Play playlist entry.
  109. // This function is called recursevly with playNext and iterates over all entries from playlist.
  110. function playEntry(viewer, cameraOptions, allDone) {
  111. var entry = this.playlist[this.playlistIndex];
  112. if (entry) {
  113. var _playNext = playNext.bind(this, viewer, cameraOptions, allDone);
  114. this._activeEntries.push(entry);
  115. this.entryStart.raiseEvent(entry);
  116. if (entry.blocking) {
  117. entry.play(_playNext, viewer.scene.camera, cameraOptions);
  118. } else {
  119. var tour = this;
  120. entry.play(function () {
  121. tour.entryEnd.raiseEvent(entry);
  122. var indx = tour._activeEntries.indexOf(entry);
  123. if (indx >= 0) {
  124. tour._activeEntries.splice(indx, 1);
  125. }
  126. });
  127. _playNext(viewer, cameraOptions, allDone);
  128. }
  129. } else if (defined(allDone)) {
  130. allDone(false);
  131. }
  132. }
  133. // Increment playlistIndex and call playEntry if terminated isn't true.
  134. function playNext(viewer, cameraOptions, allDone, terminated) {
  135. var entry = this.playlist[this.playlistIndex];
  136. this.entryEnd.raiseEvent(entry, terminated);
  137. if (terminated) {
  138. allDone(terminated);
  139. } else {
  140. var indx = this._activeEntries.indexOf(entry);
  141. if (indx >= 0) {
  142. this._activeEntries.splice(indx, 1);
  143. }
  144. this.playlistIndex++;
  145. playEntry.call(this, viewer, cameraOptions, allDone);
  146. }
  147. }
  148. export default KmlTour;