Start using typescript

pull/1/head
Tristan Daniël Maat 2020-02-29 15:51:28 +00:00 committed by Tristan Daniël Maat
parent 8b1fcf7379
commit a357728358
Signed by: tlater
GPG Key ID: 49670FD774E43268
7 changed files with 275 additions and 112 deletions

151
package-lock.json generated
View File

@ -2260,12 +2260,27 @@
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
"dev": true
},
"@types/jquery": {
"version": "3.3.33",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.33.tgz",
"integrity": "sha512-U6IdXYGkfUI42SR79vB2Spj+h1Ly3J3UZjpd8mi943lh126TK7CB+HZOxGh2nM3IySor7wqVQdemD/xtydsBKA==",
"dev": true,
"requires": {
"@types/sizzle": "*"
}
},
"@types/q": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
"dev": true
},
"@types/sizzle": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
"integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==",
"dev": true
},
"@types/unist": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
@ -3465,6 +3480,12 @@
"randomfill": "^1.0.3"
}
},
"crypto-random-string": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
"dev": true
},
"css-color-names": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
@ -4545,6 +4566,17 @@
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
"dev": true
},
"fs-extra": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -4685,6 +4717,12 @@
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
},
"graceful-fs": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
"dev": true
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
@ -5694,6 +5732,15 @@
"minimist": "^1.2.0"
}
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6"
}
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@ -6551,6 +6598,12 @@
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
"dev": true
},
"p-debounce": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-debounce/-/p-debounce-1.0.0.tgz",
"integrity": "sha1-y38svu/YegnrqGHhErZ1J+Yh4v0=",
"dev": true
},
"p-limit": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
@ -8710,6 +8763,22 @@
"readable-stream": "^3.1.1"
}
},
"temp-dir": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
"integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=",
"dev": true
},
"tempy": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tempy/-/tempy-0.2.1.tgz",
"integrity": "sha512-LB83o9bfZGrntdqPuRdanIVCPReam9SOZKW0fOy5I9X3A854GGWi0tjCqoXEk84XIEYBc/x9Hq3EFop/H5wJaw==",
"dev": true,
"requires": {
"temp-dir": "^1.0.0",
"unique-string": "^1.0.0"
}
},
"term-size": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz",
@ -8885,6 +8954,29 @@
"prelude-ls": "~1.1.2"
}
},
"typescript-language-server": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/typescript-language-server/-/typescript-language-server-0.4.0.tgz",
"integrity": "sha512-K8jNOmDFn+QfrCh8ujby2pGDs5rpjYZQn+zvQnf42rxG4IHbfw5CHoMvbGkWPK/J5Gw8/l5K3i03kVZC2IBElg==",
"dev": true,
"requires": {
"command-exists": "1.2.6",
"commander": "^2.11.0",
"fs-extra": "^7.0.0",
"p-debounce": "^1.0.0",
"tempy": "^0.2.1",
"vscode-languageserver": "^5.3.0-next",
"vscode-uri": "^1.0.5"
},
"dependencies": {
"command-exists": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.6.tgz",
"integrity": "sha512-Qst/zUUNmS/z3WziPxyqjrcz09pm+2Knbs5mAZL4VAE0sSrNY1/w8+/YxeHcoBTsO6iojA6BW7eFf27Eg2MRuw==",
"dev": true
}
}
},
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
@ -9046,6 +9138,15 @@
"integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
"dev": true
},
"unique-string": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
"integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
"dev": true,
"requires": {
"crypto-random-string": "^1.0.0"
}
},
"unist-builder": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz",
@ -9149,6 +9250,12 @@
"unist-util-is": "^3.0.0"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@ -9359,6 +9466,50 @@
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
"dev": true
},
"vscode-jsonrpc": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz",
"integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==",
"dev": true
},
"vscode-languageserver": {
"version": "5.3.0-next.10",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.3.0-next.10.tgz",
"integrity": "sha512-QL7Fe1FT6PdLtVzwJeZ78pTic4eZbzLRy7yAQgPb9xalqqgZESR0+yDZPwJrM3E7PzOmwHBceYcJR54eQZ7Kng==",
"dev": true,
"requires": {
"vscode-languageserver-protocol": "^3.15.0-next.8",
"vscode-textbuffer": "^1.0.0"
}
},
"vscode-languageserver-protocol": {
"version": "3.15.3",
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz",
"integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==",
"dev": true,
"requires": {
"vscode-jsonrpc": "^5.0.1",
"vscode-languageserver-types": "3.15.1"
}
},
"vscode-languageserver-types": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==",
"dev": true
},
"vscode-textbuffer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/vscode-textbuffer/-/vscode-textbuffer-1.0.0.tgz",
"integrity": "sha512-zPaHo4urgpwsm+PrJWfNakolRpryNja18SUip/qIIsfhuEqEIPEXMxHOlFPjvDC4JgTaimkncNW7UMXRJTY6ow==",
"dev": true
},
"vscode-uri": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz",
"integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==",
"dev": true
},
"w3c-hr-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",

View File

@ -7,10 +7,12 @@
"private": true,
"devDependencies": {
"@babel/preset-env": "^7.8.4",
"@types/jquery": "^3.3.33",
"jstransformer-markdown-it": "^2.1.0",
"parcel": "^2.0.0-alpha.3.2",
"pug": "^2.0.4",
"sass": "^1.25.0"
"sass": "^1.25.0",
"typescript-language-server": "^0.4.0"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^5.12.1",

View File

@ -1,109 +0,0 @@
import $ from "jquery";
// Helpers
/**
* "Types" out a DOM element, emulating the way a human might.
*/
class Typer {
/**
* Create the typer.
* @param {HTMLElement} element - The element to type.
* @param {number} blink - The time between cursor blinks.
* @param {number} blink_timeout - How long the cursor should keep
* blinking for after the text
* finishes typing.
*/
constructor(element, blink, blink_timeout) {
// Retrieve the current content and wipe it. We also make the
// element visible if it was hidden.
this._element = $(element);
this._text = this._element.html();
this._element.html("");
this._element.css("visibility", "visible");
this._cursor = false;
this._typed = 0;
this._min = 20;
this._max = 70;
this._blink_tick = blink;
this._blink_timeout = blink_timeout;
this._end = null;
}
/**
* Start typing.
*/
type() {
this._type();
this._blink();
}
/**
* Draw the current text line, i.e., anything that has been typed
* so far, and a cursor if it is currently supposed to be on.
* @private
*/
_draw() {
let text = this._text.slice(0, this._typed);
if (this._cursor) {
text += "\u2588";
}
window.requestAnimationFrame(() => this._element.html(text));
}
/**
* Type the next character, and prepare to draw the next one. If
* no new characters are to be drawn, set the end timestamp.
* @private
*/
_type() {
this._typed += 1;
this._draw();
if (this._typed != this._text.length)
setTimeout(this._type.bind(this), this._type_tick());
else {
this._end = Date.now();
}
}
/**
* Make the cursor change blink status, and prepare for the next
* blink.
* @private
*/
_blink() {
this._cursor = !this._cursor;
this._draw();
// As long as we are typing, keep blinking
if (this._typed != this._text.length)
setTimeout(this._blink.bind(this), this._blink_tick);
// Once typing ends, keep going for a little bit
else if (Date.now() - this._end < this._blink_timeout)
setTimeout(this._blink.bind(this), this._blink_tick);
// Make sure we get rid of the cursor in the end
else {
this._cursor = true;
setTimeout(this._blink.bind(this), this._blink_tick);
}
}
/**
* Calculate a "human" time for the next character to type.
* @private
*/
_type_tick() {
return Math.round(Math.random() * this._max) + this._min;
}
}
$(document).ready(() => {
let typer = new Typer($(".head-line .typed").get(0), 500, 3000);
typer.type();
});

View File

@ -76,4 +76,4 @@ block content
[GitHub](https://github.com/tlater) pages.
block footer
script(type="text/javascript" src="./index.js" defer)
script(type="text/javascript" src="./index.ts" defer)

119
src/index.ts Normal file
View File

@ -0,0 +1,119 @@
import $ from "jquery";
// Helpers
/**
* "Types" out a DOM element, emulating the way a human might.
*/
class Typer {
private element: JQuery;
private text: string;
private cursor: boolean;
private typed: number;
private min: number;
private max: number;
private blink_tick: number;
private blink_timeout: number;
private end?: number;
/**
* Create the typer.
* @param {HTMLElement} element - The element to type.
* @param {number} blink - The time between cursor blinks.
* @param {number} blink_timeout - How long the cursor should keep
* blinking for after the text
* finishes typing.
*/
constructor(element: HTMLElement, blink: number, blink_timeout: number) {
// Retrieve the current content and wipe it. We also make the
// element visible if it was hidden.
this.element = $(element);
this.text = this.element.html();
this.element.html("");
this.element.css("visibility", "visible");
this.cursor = false;
this.typed = 0;
this.min = 20;
this.max = 70;
this.blink_tick = blink;
this.blink_timeout = blink_timeout;
this.end = null;
}
/**
* Start typing.
*/
type() {
this._type();
this._blink();
}
/**
* Draw the current text line, i.e., anything that has been typed
* so far, and a cursor if it is currently supposed to be on.
* @private
*/
_draw() {
let text = this.text.slice(0, this.typed);
if (this.cursor) {
text += "\u2588";
}
window.requestAnimationFrame(() => this.element.html(text));
}
/**
* Type the next character, and prepare to draw the next one. If
* no new characters are to be drawn, set the end timestamp.
* @private
*/
_type() {
this.typed += 1;
this._draw();
if (this.typed != this.text.length)
setTimeout(this._type.bind(this), this._type_tick());
else {
this.end = Date.now();
}
}
/**
* Make the cursor change blink status, and prepare for the next
* blink.
* @private
*/
_blink() {
this.cursor = !this.cursor;
this._draw();
// As long as we are typing, keep blinking
if (this.typed != this.text.length)
setTimeout(this._blink.bind(this), this.blink_tick);
// Once typing ends, keep going for a little bit
else if (Date.now() - this.end < this.blink_timeout)
setTimeout(this._blink.bind(this), this.blink_tick);
// Make sure we get rid of the cursor in the end
else {
this.cursor = true;
setTimeout(this._blink.bind(this), this.blink_tick);
}
}
/**
* Calculate a "human" time for the next character to type.
* @private
*/
_type_tick() {
return Math.round(Math.random() * this.max) + this.min;
}
}
$(document).ready(() => {
let typer = new Typer($(".head-line .typed").get(0), 500, 3000);
typer.type();
});

View File

@ -18,5 +18,5 @@ html.no-js(lang="en")
script(type="text/javascript", src="~/node_modules/jquery/dist/jquery.min.js" defer)
script(type="text/javascript", src="~/node_modules/bootstrap/dist/js/bootstrap.min.js" defer)
script(type="text/javascript", src="~/src/lib/js/main.js" defer)
script(type="text/javascript", src="~/src/lib/js/main.ts" defer)
block footer