mirror of
https://github.com/seigler/aurebesh
synced 2025-07-27 01:36:12 +00:00
better
This commit is contained in:
parent
63216d92cd
commit
26b3e5f2ad
2 changed files with 83 additions and 5 deletions
|
@ -1,7 +1,7 @@
|
||||||
import { hydrate, prerender as ssr } from "preact-iso";
|
import { hydrate, prerender as ssr } from "preact-iso";
|
||||||
|
|
||||||
import "./style.css";
|
import "./style.css";
|
||||||
import { computed, effect, signal } from "@preact/signals";
|
import { computed, effect, signal, useSignal } from "@preact/signals";
|
||||||
|
|
||||||
const fonts: Record<string, { ligatures: string[]; lowercase: boolean }> = {
|
const fonts: Record<string, { ligatures: string[]; lowercase: boolean }> = {
|
||||||
"AB-Equinox": {
|
"AB-Equinox": {
|
||||||
|
@ -97,6 +97,7 @@ export function App() {
|
||||||
<main>
|
<main>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<FontPicker />
|
<FontPicker />
|
||||||
|
<ReadingBox />
|
||||||
</div>
|
</div>
|
||||||
<aside class="reference">
|
<aside class="reference">
|
||||||
<DualText>
|
<DualText>
|
||||||
|
@ -123,6 +124,46 @@ export function App() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ReadingBox() {
|
||||||
|
const isEditing = useSignal(false);
|
||||||
|
const contents =
|
||||||
|
useSignal(`It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire.
|
||||||
|
|
||||||
|
During the battle, Rebel spies managed to steal secret plans to the Empire's ultimate weapon, the DEATH STAR, an armored space station with enough power to destroy an entire planet.
|
||||||
|
|
||||||
|
Pursued by the Empire's sinister agents, Princess Leia races home aboard her starship, custodian of the stolen plans that can save her people and restore freedom to the galaxy...`);
|
||||||
|
return (
|
||||||
|
<div class="readingbox">
|
||||||
|
<span>
|
||||||
|
<label htmlFor="edit-toggle">Edit</label>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="edit-toggle"
|
||||||
|
selected={isEditing}
|
||||||
|
onChange={(event) => {
|
||||||
|
isEditing.value = event.currentTarget.checked;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
{isEditing.value ? (
|
||||||
|
<textarea
|
||||||
|
class="readingbox-textarea"
|
||||||
|
id="reading-material"
|
||||||
|
value={contents}
|
||||||
|
onChange={(event) => {
|
||||||
|
contents.value = event.currentTarget.value;
|
||||||
|
}}
|
||||||
|
spellCheck={false}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div class="readingbox-text aurebesh">
|
||||||
|
<DualText>{contents.value}</DualText>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function FontPicker() {
|
function FontPicker() {
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
|
@ -142,14 +183,25 @@ function FontPicker() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function DualText({ children }: { children: string }) {
|
function DualText({ children }: { children: string }) {
|
||||||
const words = children.split(/\b/);
|
const words: string[] = [];
|
||||||
|
children.split(/\n/).forEach((line, index, lines) => {
|
||||||
|
line.split(/\b(?=\w)/).forEach((word) => {
|
||||||
|
words.push(word);
|
||||||
|
});
|
||||||
|
if (index < lines.length - 1) {
|
||||||
|
words.push("\n");
|
||||||
|
}
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{words.map((word) => {
|
{words.map((word) => {
|
||||||
|
if (word === "\n") {
|
||||||
|
return <br />;
|
||||||
|
}
|
||||||
const letters: string[] = [];
|
const letters: string[] = [];
|
||||||
for (let i = 0; i < word.length; i += 1) {
|
for (let i = 0; i < word.length; i += 1) {
|
||||||
const nextTwoCharacters = word.slice(i, i + 2);
|
const nextTwoCharacters = word.slice(i, i + 2);
|
||||||
if (ligatures.value.includes(nextTwoCharacters)) {
|
if (ligatures.value.includes(nextTwoCharacters.toLowerCase())) {
|
||||||
letters.push(nextTwoCharacters);
|
letters.push(nextTwoCharacters);
|
||||||
i += 1;
|
i += 1;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -153,6 +153,7 @@ h1 {
|
||||||
.dualtext-help > span {
|
.dualtext-help > span {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
transition: all 0.25s ease-in;
|
||||||
}
|
}
|
||||||
.dualtext-help > span::before {
|
.dualtext-help > span::before {
|
||||||
content: attr(data-character);
|
content: attr(data-character);
|
||||||
|
@ -168,7 +169,7 @@ h1 {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
font-family: var(--font-standard);
|
font-family: var(--font-standard);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 0.5em;
|
font-size: clamp(0.45rem, 0.25em, 1rem);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: var(--color-text-light);
|
color: var(--color-text-light);
|
||||||
}
|
}
|
||||||
|
@ -183,6 +184,31 @@ h1 {
|
||||||
main {
|
main {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
max-width: 60rem;
|
width: 100%;
|
||||||
|
max-width: 40rem;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.readingbox {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.readingbox-text {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.readingbox .dualtext-help {
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
.readingbox .dualtext-help > span {
|
||||||
|
opacity: 0;
|
||||||
|
--color-text-light: var(--color-accent1);
|
||||||
|
}
|
||||||
|
.readingbox .dualtext-help > span:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue