/// /// module Elements.CurrentTurnHandler { export var currentTurnTab = document.getElementById("currentTurnTab"); export var currentTurn = document.getElementById("currentTurn"); export var turnHr = document.createElement("p"); export var lastReadOffset = currentTurnTab.clientHeight / 2; turnHr.classList.add("turnStart"); turnHr.appendChild(document.createTextNode("Start of Turn")); /** * Creates the "Start of Turn" elements and scrolls the content panel until the start of the new turn. */ export function startTurn (action? : Action) { let oldContent = new Array(...currentTurnTab.getElementsByClassName("content")); for (let i = oldContent.length - 1; i >= 0; i--) { oldContent[i].classList.add("contentOld"); oldContent[i].classList.remove("content"); } currentTurnTab.appendChild(turnHr); Elements.startTurn(); scrollToNewTurn(); } /** * Are we in the middle of a turn? */ export function isTurn () { return Elements.isInTurn(); } /** * Removes the blur effect around the turn panel */ export function endTurn () { Elements.endTurn(); } export function getSayElementsAsContent (say : Say) : Promise> { return say.getHTML("p", ["content"]); } /** * Prints given Say directly * @param say */ export function printAsContent (say : Say) { let node = getMarker(); getSayElementsAsContent(say).then(value => { insertBefore(value, node); unprint(node); }); } /** * Creates a say for sayValues and then prints it as content. * @param sayValues */ export function simplePrint (...sayValues : Array) { printAsContent(new Say(...sayValues)); } export function printAsError (msg : Say | string) { if (msg instanceof Say) { msg.getHTML("div", ["error"], true).then(value => { print(...value); }); } else { let div = document.createElement("div"); div.classList.add("error"); div.appendChild(document.createTextNode(msg)); print(div); } } export function clear () { while (currentTurnTab.firstChild != undefined) { currentTurnTab.removeChild(currentTurnTab.firstChild); } Controls.KeyHandler.reset(); } /** * Includes the given elements as content. * This is the only correct way of printing elements. * @param elements */ export function print (...elements : Array) { if(elements.length > 0) { elements.forEach((element) => { currentTurnTab.appendChild(element); }); scrollTo(lastReadOffset); } } export function getMarker () { let node = document.createTextNode(""); currentTurnTab.appendChild(node); return node; } export function insertBefore (newChilds : Array, oldChild) { newChilds.forEach((newChild) => { currentTurnTab.insertBefore(newChild, oldChild); }); scrollTo(lastReadOffset); } /** * Removes elements that have been printed in the past. * @param elements */ export function unprint (...elements : Array) { elements.forEach((element) => { if (element.parentElement == currentTurnTab) { currentTurnTab.removeChild(element); } }); } /** * Scrolls to the first current turn element. (Or rather, to just after the Start of Turn element) * This is used internally as a new turn begins. */ export function scrollToNewTurn () { let target = turnHr.offsetTop + turnHr.offsetHeight; lastReadOffset = target; //turnHr.scrollIntoView({behavior : "smooth", block : "start"}); if (target < currentTurn.scrollTop) { return; // We don't want to scroll UP. } scrollTo(target); } /** * Scrolls to the very bottom of the content panel. */ export function scrollToBottom () { scrollTo(currentTurn.scrollHeight - currentTurn.clientHeight); } /** * Scroll half a screen forward */ export function scrollSpace () { scrollTo(currentTurn.scrollTop + (currentTurn.clientHeight / 2)); } /** * Update text that was read as player scrolls */ currentTurn.addEventListener("scroll", () => { let currentRead = currentTurn.scrollTop + currentTurn.clientHeight; if (currentRead > lastReadOffset) { lastReadOffset = currentRead; } }); /** * Animation... removing jquery */ var startOffset : number; var targetOffset : number; var startTime : number; var finishTime : number; var totalTime : number; var animationRequest : number; export function scrollTo (offset : number) { if (offset <= lastReadOffset) { startOffset = currentTurn.scrollTop; targetOffset = offset; startTime = new Date().getTime(); finishTime = startTime + Elements.animationTime; totalTime = finishTime - startTime; startScrolling(); } } export function startScrolling () { if (animationRequest == undefined) { animationRequest = requestAnimationFrame(updateFrame); } } export let updateFrame = () => { animationRequest = undefined; let movingOffset = (targetOffset - startOffset); let timePassed = new Date().getTime() - startTime; let idealOffset = movingOffset * (timePassed / totalTime); let maxScroll = currentTurn.scrollHeight - currentTurn.clientHeight; currentTurn.scrollTop = startOffset + idealOffset; if (currentTurn.scrollTop < targetOffset && currentTurn.scrollTop < maxScroll) { startScrolling(); } } }