Start using typescript
This commit is contained in:
parent
8b1fcf7379
commit
a357728358
151
package-lock.json
generated
151
package-lock.json
generated
|
@ -2260,12 +2260,27 @@
|
||||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||||
"dev": true
|
"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": {
|
"@types/q": {
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
||||||
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
|
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
|
||||||
"dev": true
|
"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": {
|
"@types/unist": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
|
||||||
|
@ -3465,6 +3480,12 @@
|
||||||
"randomfill": "^1.0.3"
|
"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": {
|
"css-color-names": {
|
||||||
"version": "0.0.4",
|
"version": "0.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
|
"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==",
|
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||||
"dev": true
|
"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": {
|
"fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"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==",
|
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||||
"dev": true
|
"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": {
|
"har-schema": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||||
|
@ -5694,6 +5732,15 @@
|
||||||
"minimist": "^1.2.0"
|
"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": {
|
"jsprim": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||||
|
@ -6551,6 +6598,12 @@
|
||||||
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
|
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
|
||||||
"dev": true
|
"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": {
|
"p-limit": {
|
||||||
"version": "2.2.2",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
|
||||||
|
@ -8710,6 +8763,22 @@
|
||||||
"readable-stream": "^3.1.1"
|
"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": {
|
"term-size": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz",
|
||||||
|
@ -8885,6 +8954,29 @@
|
||||||
"prelude-ls": "~1.1.2"
|
"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": {
|
"uc.micro": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||||
|
@ -9046,6 +9138,15 @@
|
||||||
"integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
|
"integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
|
||||||
"dev": true
|
"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": {
|
"unist-builder": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz",
|
||||||
|
@ -9149,6 +9250,12 @@
|
||||||
"unist-util-is": "^3.0.0"
|
"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": {
|
"unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
@ -9359,6 +9466,50 @@
|
||||||
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
|
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
|
||||||
"dev": true
|
"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": {
|
"w3c-hr-time": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
|
||||||
|
|
|
@ -7,10 +7,12 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/preset-env": "^7.8.4",
|
"@babel/preset-env": "^7.8.4",
|
||||||
|
"@types/jquery": "^3.3.33",
|
||||||
"jstransformer-markdown-it": "^2.1.0",
|
"jstransformer-markdown-it": "^2.1.0",
|
||||||
"parcel": "^2.0.0-alpha.3.2",
|
"parcel": "^2.0.0-alpha.3.2",
|
||||||
"pug": "^2.0.4",
|
"pug": "^2.0.4",
|
||||||
"sass": "^1.25.0"
|
"sass": "^1.25.0",
|
||||||
|
"typescript-language-server": "^0.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.12.1",
|
"@fortawesome/fontawesome-free": "^5.12.1",
|
||||||
|
|
109
src/index.js
109
src/index.js
|
@ -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();
|
|
||||||
});
|
|
|
@ -76,4 +76,4 @@ block content
|
||||||
[GitHub](https://github.com/tlater) pages.
|
[GitHub](https://github.com/tlater) pages.
|
||||||
|
|
||||||
block footer
|
block footer
|
||||||
script(type="text/javascript" src="./index.js" defer)
|
script(type="text/javascript" src="./index.ts" defer)
|
||||||
|
|
119
src/index.ts
Normal file
119
src/index.ts
Normal 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();
|
||||||
|
});
|
|
@ -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/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="~/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
|
block footer
|
||||||
|
|
Reference in a new issue