dominoclock/src/DominoFace.ts

93 lines
2.7 KiB
TypeScript

import { LitElement, css, html } from "lit";
import { customElement, property, queryAll } from "lit/decorators.js";
type Times = number[];
type Coordinates = Times;
const MATRIX: Coordinates[] = [
[1, 5, 8, 9, 11],
[2, 5, 6, 10, 11],
[3, 6, 7, 9, 11],
[4, 7, 8, 10, 11],
];
// An element that takes a single attribute, "time," which is a number between 1
// and 12; that number is scanned in the Coordinates matrix above to determine
// which of four dots should be illuminated, reflecting 12 patterns that can be
// memorized to represent the time. After rendering, if the attribute changes,
// the active/hidden dots are recalculated.
@customElement("domino-face")
export class DominoClockface extends LitElement {
static styles = css`
:host {
--dominoclock-default-dot-size: 1rem;
--dominoclock-default-dot-color: #2f4f4f;
--dominoclock-default-face-size: 5rem;
--dominoclock-default-background-color: #daaf20;
--dominoclock-default-border-radius: 0.5rem;
}
.face {
position: relative;
width: var(--dominoclock-face-size, var(--dominoclock-default-face-size, 5rem));
height: var(--dominoclock-face-size, var(--dominoclock-default-face-size, 5rem));
background-color: var(
--dominoclock-background-color,
var(--dominoclock-default-background-color, #daaf20)
);
border: 1px solid #282828;
border-radius: var(--dominoclock-border-radius, var(--dominoclock-default-border-radius, 0.5rem));
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
.dot {
width: 100%;
height: 100%;
display: grid;
place-items: center center;
}
.dot > div {
transition: opacity 0.6s ease;
width: var(--dominoclock-date-size, var(--dominoclock-default-date-size, 1rem));
height: var(--dominoclock-date-size, var(--dominoclock-default-date-size, 1rem));
background-color: var(--dominoclock-dot-color, var(--dominoclock-default-dot-color, #2f4f4f));
border-radius: calc(var(--dominoclock-dot-size, var(--dominoclock-default-dot-size, 1rem)) / 2);
opacity: 0;
}
.dot.active > div {
opacity: 1;
}
`;
@property({ type: String }) name = "hour";
@property({ type: String }) time = "12";
@queryAll(".dot") dots: HTMLCollection;
calculateDots() {
const time = parseInt(this.time, 10);
return [0, 1, 2, 3].map(i => MATRIX[i].includes(time));
}
render() {
const points = this.calculateDots();
return html`
<div class="face">
${points.map(
pos =>
html`
<div class="dot${pos ? " active" : ""}"><div></div></div>
`
)}
</div>
`;
}
}
export default DominoClockface;