CurrentTurnHandler.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /// <reference path="../Elements.ts" />
  2. /// <reference path="../../Controls/Modules/KeyHandler.ts" />
  3. module Elements.CurrentTurnHandler {
  4. export var currentTurnTab = <HTMLElement> document.getElementById("currentTurnTab");
  5. export var currentTurn = <HTMLElement> document.getElementById("currentTurn");
  6. export var turnHr = document.createElement("p");
  7. export var lastReadOffset = currentTurnTab.clientHeight / 2;
  8. turnHr.classList.add("turnStart");
  9. turnHr.appendChild(document.createTextNode("Start of Turn"));
  10. /**
  11. * Creates the "Start of Turn" elements and scrolls the content panel until the start of the new turn.
  12. */
  13. export function startTurn (action? : Action) {
  14. let oldContent = currentTurnTab.getElementsByClassName("content");
  15. for (let i = 0; i < oldContent.length; i++) {
  16. oldContent[i].classList.add("contentOld");
  17. oldContent[i].classList.remove("content");
  18. }
  19. currentTurnTab.appendChild(turnHr);
  20. Elements.startTurn();
  21. scrollToNewTurn();
  22. }
  23. /**
  24. * Are we in the middle of a turn?
  25. */
  26. export function isTurn () {
  27. return Elements.isInTurn();
  28. }
  29. /**
  30. * Removes the blur effect around the turn panel
  31. */
  32. export function endTurn () {
  33. Elements.endTurn();
  34. }
  35. export function getSayElementsAsContent (say : Say) : Promise<Array<HTMLElement>> {
  36. return say.getHTML("p", ["content"]);
  37. }
  38. /**
  39. * Prints given Say directly
  40. * @param say
  41. */
  42. export function printAsContent (say : Say) {
  43. let node = getMarker();
  44. getSayElementsAsContent(say).then(value => {
  45. insertBefore(value, node);
  46. unprint(node);
  47. });
  48. }
  49. /**
  50. * Creates a say for sayValues and then prints it as content.
  51. * @param sayValues
  52. */
  53. export function simplePrint (...sayValues : Array<any>) {
  54. printAsContent(new Say(...sayValues));
  55. }
  56. export function printAsError (msg : Say | string) {
  57. if (msg instanceof Say) {
  58. msg.getHTML("div", ["error"], true).then(value => {
  59. print(...value);
  60. });
  61. } else {
  62. let div = document.createElement("div");
  63. div.classList.add("error");
  64. div.appendChild(document.createTextNode(msg));
  65. print(div);
  66. }
  67. }
  68. export function clear () {
  69. while (currentTurnTab.firstChild != undefined) {
  70. currentTurnTab.removeChild(currentTurnTab.firstChild);
  71. }
  72. Controls.KeyHandler.reset();
  73. }
  74. /**
  75. * Includes the given elements as content.
  76. * This is the only correct way of printing elements.
  77. * @param elements
  78. */
  79. export function print (...elements : Array<Node>) {
  80. if(elements.length > 0) {
  81. elements.forEach((element) => {
  82. currentTurnTab.appendChild(element);
  83. });
  84. scrollTo(lastReadOffset);
  85. }
  86. }
  87. export function getMarker () {
  88. let node = document.createTextNode("");
  89. currentTurnTab.appendChild(node);
  90. return node;
  91. }
  92. export function insertBefore (newChilds : Array<Node>, oldChild) {
  93. newChilds.forEach((newChild) => {
  94. currentTurnTab.insertBefore(newChild, oldChild);
  95. });
  96. scrollTo(lastReadOffset);
  97. }
  98. /**
  99. * Removes elements that have been printed in the past.
  100. * @param elements
  101. */
  102. export function unprint (...elements : Array<Node>) {
  103. elements.forEach((element) => {
  104. if (element.parentElement == currentTurnTab) {
  105. currentTurnTab.removeChild(element);
  106. }
  107. });
  108. }
  109. /**
  110. * Scrolls to the first current turn element. (Or rather, to just after the Start of Turn element)
  111. * This is used internally as a new turn begins.
  112. */
  113. export function scrollToNewTurn () {
  114. let target = turnHr.offsetTop + turnHr.offsetHeight;
  115. lastReadOffset = target;
  116. //turnHr.scrollIntoView({behavior : "smooth", block : "start"});
  117. if (target < currentTurn.scrollTop) {
  118. return; // We don't want to scroll UP.
  119. }
  120. scrollTo(target);
  121. }
  122. /**
  123. * Scrolls to the very bottom of the content panel.
  124. */
  125. export function scrollToBottom () {
  126. scrollTo(currentTurn.scrollHeight - currentTurn.clientHeight);
  127. }
  128. /**
  129. * Scroll half a screen forward
  130. */
  131. export function scrollSpace () {
  132. scrollTo(currentTurn.scrollTop + (currentTurn.clientHeight / 2));
  133. }
  134. /**
  135. * Update text that was read as player scrolls
  136. */
  137. currentTurn.addEventListener("scroll", () => {
  138. let currentRead = currentTurn.scrollTop + currentTurn.clientHeight;
  139. if (currentRead > lastReadOffset) {
  140. lastReadOffset = currentRead;
  141. }
  142. });
  143. /**
  144. * Animation... removing jquery
  145. */
  146. var startOffset : number;
  147. var targetOffset : number;
  148. var startTime : number;
  149. var finishTime : number;
  150. var totalTime : number;
  151. var animationRequest : number;
  152. export function scrollTo (offset : number) {
  153. if (offset <= lastReadOffset) {
  154. startOffset = currentTurn.scrollTop;
  155. targetOffset = offset;
  156. startTime = new Date().getTime();
  157. finishTime = startTime + Elements.animationTime;
  158. totalTime = finishTime - startTime;
  159. startScrolling();
  160. }
  161. }
  162. export function startScrolling () {
  163. if (animationRequest == undefined) {
  164. animationRequest = requestAnimationFrame(updateFrame);
  165. }
  166. }
  167. export let updateFrame = () => {
  168. animationRequest = undefined;
  169. let movingOffset = (targetOffset - startOffset);
  170. let timePassed = new Date().getTime() - startTime;
  171. let idealOffset = movingOffset * (timePassed / totalTime);
  172. let maxScroll = currentTurn.scrollHeight - currentTurn.clientHeight;
  173. currentTurn.scrollTop = startOffset + idealOffset;
  174. if (currentTurn.scrollTop < targetOffset && currentTurn.scrollTop < maxScroll) {
  175. startScrolling();
  176. }
  177. }
  178. }