No longer automatically download external font, holidays and centaurs
This commit now makes the download of the Google-provided font opt-in, rather than automatic. This is preferable, as most people wouldn't care to have Google automatically know they're running this thing. For modern browsers that understand CSS `::part()` syntax, this commit also provides a way for them to specify exactly what font they want, and an example of that is provided in the `./demo` folder. There are a number of minor details in the Journal Entries that reflect the growth and change of the culture. One was that several of the species introduced, including Centaurs, Tindals, Felinzi and Uncia, had their own language, and Centaurs had their own calendar. Most fell off as use of the common Quen made everything easier, and Uncia found Felinzi easy to learn and use and gave the felinoid species a common tongue that worked well with their mouth and throat shapes. But I've added the Centaur calendar. Use the flag attribute "centaurs" (no arguments, it's a flag) in the component's HTML tag to see it. Again, the use can be seen in the demo folder. I've also fixed a bug where the holidays, which belong to no month and have no weekday, are also rendered correctly.
This commit is contained in:
parent
bf73427be7
commit
3e91b9498a
39
README.md
39
README.md
|
@ -1,9 +1,5 @@
|
||||||
# \<pendor-clock>
|
# \<pendor-clock>
|
||||||
|
|
||||||
<script type="module" src="./raw/branch/master/build-modern/pendor-clock.js"></script>
|
|
||||||
|
|
||||||
<pendor-clock></pendor-clock>
|
|
||||||
|
|
||||||
Way back at the dawn of the Internet, I started writing (and sometimes still write) a long-running
|
Way back at the dawn of the Internet, I started writing (and sometimes still write) a long-running
|
||||||
adult space opera serial called [The Journal Entries](https://pendorwright.com/journals). One of the
|
adult space opera serial called [The Journal Entries](https://pendorwright.com/journals). One of the
|
||||||
conceits of the series in that the distant world of Pendor was built and terraformed to have a
|
conceits of the series in that the distant world of Pendor was built and terraformed to have a
|
||||||
|
@ -13,9 +9,9 @@ applets](https://en.wikipedia.org/wiki/Java_applet) (remember those?) I wrote wa
|
||||||
showed the time of day on Pendor.
|
showed the time of day on Pendor.
|
||||||
|
|
||||||
This is the Pendorclock, but modernized into a custom Web Component, capable of running in any
|
This is the Pendorclock, but modernized into a custom Web Component, capable of running in any
|
||||||
browser without your needing to do anything at all to make it work correctly. It will load its own
|
browser without your needing to do anything at all to make it work correctly.
|
||||||
font (Google Audiowide) and run anywhere you want. The font is not currently customizable without a
|
|
||||||
rebuild, but the following CSS Custom Attributes are exposed and you're free to change any of them:
|
The following CSS Custom Attributes are exposed and you're free to change any of them:
|
||||||
|
|
||||||
``` JavaScript
|
``` JavaScript
|
||||||
background-color: var(--pendorclock-background-color, #000030);
|
background-color: var(--pendorclock-background-color, #000030);
|
||||||
|
@ -28,6 +24,35 @@ font-weight: var(--pendorclock-font-weight, 700);
|
||||||
This is mostly my set-up these days, complete with the hard-core `lint:hard`, Codespell, and
|
This is mostly my set-up these days, complete with the hard-core `lint:hard`, Codespell, and
|
||||||
automatic Prettier.
|
automatic Prettier.
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
The clock has a single configurable attribute, `with-internal-font`. Setting that will cause the
|
||||||
|
component to use the Google Font [Audiowide](https://fonts.google.com/specimen/Audiowide), which,
|
||||||
|
while stylish, is not the original font from 1993, which was Bitwise. Using it is just like using
|
||||||
|
any boolean attribute in HTML:
|
||||||
|
|
||||||
|
``` html
|
||||||
|
<pendor-clock with-internal-font></pendor-clock>
|
||||||
|
```
|
||||||
|
|
||||||
|
Along with the CSS Custom Attributes, there is only CSS target within the clock:
|
||||||
|
'<div part="clock" />'. Using that target it is possible to use any font at all for the
|
||||||
|
clock by providing some additional CSS to the host page. This can be seen in the demo-with-font.html
|
||||||
|
file in the demo.
|
||||||
|
|
||||||
|
``` css
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bitwise";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url("./Bitwise.woff2") format("woff2"), url("./Bitwise.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
pendor-clock::clock {
|
||||||
|
font-family: Bitwise;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## LICENSE
|
## LICENSE
|
||||||
|
|
||||||
The Pendorwright Clock is Copyright [Elf M. Sternberg](https://elfsternberg.com) (c) 2023, and
|
The Pendorwright Clock is Copyright [Elf M. Sternberg](https://elfsternberg.com) (c) 2023, and
|
||||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-GB">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<style>
|
||||||
|
@font-face {
|
||||||
|
font-family: "Bitwise";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: bold;
|
||||||
|
src: url("./Bitwise.woff2") format("woff2"), url("./Bitwise.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
pendor-clock::clock {
|
||||||
|
font-family: Bitwise;
|
||||||
|
}
|
||||||
|
.demo {
|
||||||
|
border: 1px solid DarkSlateGray;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="demo"></div>
|
||||||
|
<script type="module">
|
||||||
|
import { html, render } from "lit";
|
||||||
|
import "../dist/src/pendor-clock.js";
|
||||||
|
render(
|
||||||
|
html`
|
||||||
|
<div class="demo">
|
||||||
|
<p>Using the local font (Bitwise, in the ./demo folder)</p>
|
||||||
|
<pendor-clock> </pendor-clock>
|
||||||
|
<p>Using the Pendorian centaur calendar and local font (Bitwise, in the ./demo folder)</p>
|
||||||
|
<pendor-clock centaurs> </pendor-clock>
|
||||||
|
<p><a href="./index.html">See demo with an injected font</a></p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
document.querySelector("#demo")
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,36 +1,34 @@
|
||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="en-GB">
|
<html lang="en-GB">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<style>
|
<style>
|
||||||
@font-face {
|
body {
|
||||||
font-family: 'Bitwise';
|
background: #fafafa;
|
||||||
font-style: normal;
|
}
|
||||||
font-weight: 400;
|
.demo {
|
||||||
src: url("https://pendorwright.com/fonts/Bitwise/Bitwise.woff2") format("woff2"),
|
border: 1px solid DarkSlateGray;
|
||||||
url("https://pendorwright.com/fonts/Bitwise/Bitwise.ttf") format("truetype");
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
body {
|
</style>
|
||||||
background: #fafafa;
|
</head>
|
||||||
}
|
<body>
|
||||||
pendor-clock::clock {
|
<div id="demo"></div>
|
||||||
font-family: Bitwise;
|
<script type="module">
|
||||||
}
|
import { html, render } from "lit";
|
||||||
</style>
|
import "../dist/src/pendor-clock.js";
|
||||||
</head>
|
render(
|
||||||
<body>
|
html`
|
||||||
<div id="demo"></div>
|
<div class="demo">
|
||||||
|
<p>Using the internal font (Audiowise from Google Fonts)</p>
|
||||||
<script type="module">
|
<pendor-clock with-internal-font> </pendor-clock>
|
||||||
import { html, render } from 'lit';
|
<p>Using the Pendorian centaur calendar and internal font (Audiowise from Google Fonts)</p>
|
||||||
import '../dist/src/pendor-clock.js';
|
<pendor-clock with-internal-font centaurs> </pendor-clock>
|
||||||
render(
|
<p><a href="./demo-with-font.html">See demo with external font</a></p>
|
||||||
html`
|
</div>
|
||||||
<pendor-clock>
|
`,
|
||||||
</pendor-clock>
|
document.querySelector("#demo")
|
||||||
`,
|
);
|
||||||
document.querySelector('#demo')
|
</script>
|
||||||
);
|
</body>
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
"@typescript-eslint/parser": "^5.48.0",
|
"@typescript-eslint/parser": "^5.48.0",
|
||||||
"@web/dev-server": "^0.1.34",
|
"@web/dev-server": "^0.1.34",
|
||||||
"@web/dev-server-storybook": "^0.5.4",
|
"@web/dev-server-storybook": "^0.5.4",
|
||||||
"codespell": "^1.1.7",
|
|
||||||
"concurrently": "^5.3.0",
|
"concurrently": "^5.3.0",
|
||||||
"eslint": "^8.31.0",
|
"eslint": "^8.31.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
|
@ -4603,18 +4602,6 @@
|
||||||
"node": ">= 0.12.0"
|
"node": ">= 0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/codespell": {
|
|
||||||
"version": "1.1.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/codespell/-/codespell-1.1.7.tgz",
|
|
||||||
"integrity": "sha512-WV6TdUbKUGCxCMTqM8Ow3R1ThkdBE6kRnix3PnxSIQ+EAbOBdUfAr/yX2uOubAVIczsOaXI4Q1RDSKMnQvqm1A==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"chalk": "^2.0.1"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"codespell": "index.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/collapse-white-space": {
|
"node_modules/collapse-white-space": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz",
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { LitElement, ReactiveController, ReactiveControllerHost, css, html, render } from "lit";
|
import { LitElement, ReactiveController, ReactiveControllerHost, css, html, render } from "lit";
|
||||||
|
import { property } from "lit/decorators/property.js";
|
||||||
|
|
||||||
const terranMonthIntervals = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
const terranMonthIntervals = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||||
|
|
||||||
const pendorMonthIntervals = [0, 1, 25, 49, 73, 97, 121, 145, 146, 147, 171, 195, 211, 243, 267, 291, 292];
|
const pendorMonthIntervals = [
|
||||||
|
0, 1, 25, 49, 73, 97, 121, 145, 146, 147, 171, 195, 211, 243, 267, 291, 292,
|
||||||
|
];
|
||||||
|
|
||||||
const pendorMonthNames = [
|
const pendorMonthNames = [
|
||||||
"Yestar",
|
"Yestar",
|
||||||
|
@ -23,6 +26,21 @@ const pendorMonthNames = [
|
||||||
"Mettare",
|
"Mettare",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const centaurMonthIntervals = [0, 1, 43, 85, 145, 146, 147, 189, 249, 291, 292];
|
||||||
|
|
||||||
|
const centaurMonthNames = [
|
||||||
|
"Yestr",
|
||||||
|
"Tuil",
|
||||||
|
"Layr",
|
||||||
|
"Yaiv",
|
||||||
|
"Attendes",
|
||||||
|
"Loende",
|
||||||
|
"Quel",
|
||||||
|
"Rive",
|
||||||
|
"Cair",
|
||||||
|
"Mettare",
|
||||||
|
];
|
||||||
|
|
||||||
const pendorWeekdayNames = ["Seren", "Anar", "Noren", "Aldea", "Erwer", "Elenya"];
|
const pendorWeekdayNames = ["Seren", "Anar", "Noren", "Aldea", "Erwer", "Elenya"];
|
||||||
|
|
||||||
const prefix = (n: number) => `${n < 10 ? "0" : ""}${n.toFixed(0)}`;
|
const prefix = (n: number) => `${n < 10 ? "0" : ""}${n.toFixed(0)}`;
|
||||||
|
@ -91,9 +109,11 @@ const fontStyle = css`
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url(https://fonts.gstatic.com/s/audiowide/v20/l7gdbjpo0cum0ckerWCdlg_O.woff2) format("woff2");
|
src: url(https://fonts.gstatic.com/s/audiowide/v20/l7gdbjpo0cum0ckerWCdlg_O.woff2)
|
||||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
format("woff2");
|
||||||
U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
|
||||||
|
U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
|
||||||
|
U+FEFF, U+FFFD;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -104,6 +124,12 @@ export class PendorClock extends LitElement {
|
||||||
|
|
||||||
clock: ClockController;
|
clock: ClockController;
|
||||||
|
|
||||||
|
@property({ type: Boolean, attribute: "with-internal-font" })
|
||||||
|
useInternalFont = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean, attribute: "centaurs" })
|
||||||
|
useCentaurCalendar = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.clock = new ClockController(this, 250);
|
this.clock = new ClockController(this, 250);
|
||||||
|
@ -111,6 +137,9 @@ export class PendorClock extends LitElement {
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
if (!this.useInternalFont) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (document.getElementById("pendor-font-block")) {
|
if (document.getElementById("pendor-font-block")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -121,17 +150,61 @@ export class PendorClock extends LitElement {
|
||||||
render(style, head);
|
render(style, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pendorDate(days: number) {
|
||||||
|
const nextMonth = pendorMonthIntervals.findIndex((i) => i >= days);
|
||||||
|
if (nextMonth === undefined || pendorMonthIntervals[nextMonth - 1] === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const thisMonth = nextMonth - 1;
|
||||||
|
|
||||||
|
// Holidays! Which have no Day-of-Week or Day-of-Month
|
||||||
|
if ([0, 145, 146, 291].includes(days)) {
|
||||||
|
return `${pendorMonthNames[thisMonth]}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dayOfMonth = days - pendorMonthIntervals[thisMonth];
|
||||||
|
const dayOfWeek = (Math.ceil(days) - 1) % 6;
|
||||||
|
return `${pendorWeekdayNames[dayOfWeek]}, ${
|
||||||
|
pendorMonthNames[thisMonth]
|
||||||
|
} ${dayOfMonth.toFixed(0)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
centaurDate(days: number) {
|
||||||
|
const nextMonth = centaurMonthIntervals.findIndex((i) => i >= days);
|
||||||
|
if (nextMonth === undefined || centaurMonthIntervals[nextMonth - 1] === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const thisMonth = nextMonth - 1;
|
||||||
|
|
||||||
|
// Holidays! Which have no Day-of-Week or Day-of-Month
|
||||||
|
if ([0, 145, 146, 291].includes(days)) {
|
||||||
|
return `${centaurMonthNames[thisMonth]}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dayOfMonth = days - centaurMonthIntervals[thisMonth];
|
||||||
|
const dayOfWeek = (Math.ceil(days) - 1) % 6;
|
||||||
|
return `${pendorWeekdayNames[dayOfWeek]}, ${
|
||||||
|
centaurMonthNames[thisMonth]
|
||||||
|
} ${dayOfMonth.toFixed(0)}`;
|
||||||
|
}
|
||||||
|
|
||||||
tick(now: Date) {
|
tick(now: Date) {
|
||||||
let hours = terranMonthIntervals[now.getMonth()] + now.getDate();
|
let hours = terranMonthIntervals[now.getMonth()] + now.getDate();
|
||||||
if (now.getMonth() > 2 && now.getFullYear() % 4 == 0) {
|
if (now.getMonth() > 2 && now.getFullYear() % 4 == 0) {
|
||||||
hours++;
|
hours++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DST Calculation, and wildly wrong, but WTF
|
// DST Calculation, and wildly wrong, but WTF. It was prejudiced against where I live,
|
||||||
|
// sorry. I just liked watching the clock turnover at midnight every four days, when
|
||||||
|
// Terra's and Pendor's clocks had the same midnight.
|
||||||
|
|
||||||
hours = hours * 24 + now.getHours() - 16;
|
hours = hours * 24 + now.getHours() - 16;
|
||||||
|
|
||||||
|
// Canonically, Pendor was seeded in 1884 CE. This is just a convenience to get the dates
|
||||||
|
// closer. This sixteen has nothing to do with the one above.
|
||||||
const year = now.getFullYear() + 16;
|
const year = now.getFullYear() + 16;
|
||||||
|
|
||||||
const dayOfYear = hours / 30;
|
const days = hours / 30;
|
||||||
hours = hours % 30;
|
hours = hours % 30;
|
||||||
|
|
||||||
let seconds = (now.getSeconds() + now.getMinutes() * 60) / 2.25;
|
let seconds = (now.getSeconds() + now.getMinutes() * 60) / 2.25;
|
||||||
|
@ -139,16 +212,8 @@ export class PendorClock extends LitElement {
|
||||||
seconds = seconds % 40;
|
seconds = seconds % 40;
|
||||||
|
|
||||||
const timePart = `${hours.toFixed(0)}:${prefix(minutes)}:${prefix(seconds)}`;
|
const timePart = `${hours.toFixed(0)}:${prefix(minutes)}:${prefix(seconds)}`;
|
||||||
const nextMonth = pendorMonthIntervals.findIndex(i => i >= dayOfYear);
|
const daysPart = this.useCentaurCalendar ? this.centaurDate(days) : this.pendorDate(days);
|
||||||
if (nextMonth === undefined || pendorMonthIntervals[nextMonth - 1] === undefined) {
|
return `${daysPart}, 00${year.toFixed(0)}, ${timePart}`;
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dayOfMonth = dayOfYear - pendorMonthIntervals[nextMonth - 1];
|
|
||||||
const dayOfWeek = (Math.ceil(dayOfMonth) - 1) % 6;
|
|
||||||
return `${pendorWeekdayNames[dayOfWeek]}, ${pendorMonthNames[nextMonth - 1]} ${dayOfMonth.toFixed(
|
|
||||||
0
|
|
||||||
)}, 00${year.toFixed(0)}, ${timePart}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
Loading…
Reference in New Issue