mirror of
https://github.com/seigler/aurebesh
synced 2025-07-26 01:06:12 +00:00
polish
This commit is contained in:
parent
6e15a05126
commit
1c6067a2cb
6 changed files with 52 additions and 201 deletions
|
@ -1,8 +1,8 @@
|
|||
import { ligatures } from "./store";
|
||||
|
||||
export default function DualText({ children }: { children: string }) {
|
||||
export default function DualText({ text }: { text: string }) {
|
||||
const words: string[] = [];
|
||||
children.split(/\n/).forEach((line, index, lines) => {
|
||||
text.split(/\n/).forEach((line, index, lines) => {
|
||||
line.split(/\b(?=\w)/).forEach((word) => {
|
||||
words.push(word);
|
||||
});
|
||||
|
@ -10,6 +10,8 @@ export default function DualText({ children }: { children: string }) {
|
|||
words.push("\n");
|
||||
}
|
||||
});
|
||||
const currentLigatures = ligatures.value;
|
||||
|
||||
return (
|
||||
<span>
|
||||
{words.map((word) => {
|
||||
|
@ -19,7 +21,7 @@ export default function DualText({ children }: { children: string }) {
|
|||
const letters: string[] = [];
|
||||
for (let i = 0; i < word.length; i += 1) {
|
||||
const nextTwoCharacters = word.slice(i, i + 2);
|
||||
if (ligatures.value.includes(nextTwoCharacters.toLowerCase())) {
|
||||
if (currentLigatures.includes(nextTwoCharacters.toLowerCase())) {
|
||||
letters.push(nextTwoCharacters);
|
||||
i += 1;
|
||||
} else {
|
||||
|
@ -27,8 +29,8 @@ export default function DualText({ children }: { children: string }) {
|
|||
}
|
||||
}
|
||||
return (
|
||||
<span class="dualtext-word">
|
||||
<span class="aurebesh">{word}</span>
|
||||
<span class="dualtext-word aurebesh">
|
||||
{word}
|
||||
<div className="dualtext-help">
|
||||
{letters.map((character) => {
|
||||
return <span data-character={character} />;
|
||||
|
|
|
@ -1,92 +1,10 @@
|
|||
import { computed, effect, signal } from "@preact/signals";
|
||||
import localforage from "localforage";
|
||||
import { useEffect } from "preact/hooks";
|
||||
import { selectedFont } from "./store";
|
||||
import ReadingBox from "./ReadingBox";
|
||||
|
||||
const fonts: Record<string, { ligatures: string[]; lowercase: boolean }> = {
|
||||
"AB-Equinox": {
|
||||
ligatures: ["ch", "sh", "th", "ae", "eo", "kh", "ng", "oo"],
|
||||
lowercase: false,
|
||||
},
|
||||
"AurebeshAF-Canon": {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
"AurebeshAF-CanonTech": {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
"AurebeshAF-Legends": {
|
||||
ligatures: ["ch", "sh", "th", "ae", "eo", "kh", "ng", "oo"],
|
||||
lowercase: false,
|
||||
},
|
||||
"AurebeshAF-LegendsTech": {
|
||||
ligatures: ["ch", "sh", "th", "ae", "eo", "kh", "ng", "oo"],
|
||||
lowercase: false,
|
||||
},
|
||||
"Aurebesh_Rodian-Oblique": {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
"Aurebesh_Rodian-OblqOutline": {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
Aurebesh_Rodian: {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
"Aurebesh_Rodian-Outline": {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
"AurebeshTypewriter-Light": {
|
||||
ligatures: [],
|
||||
lowercase: true,
|
||||
},
|
||||
"AurebeshTypewriter-Regular": {
|
||||
ligatures: [],
|
||||
lowercase: true,
|
||||
},
|
||||
Droidobesh: {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
LaptiNekAF: {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
Maulobesh: {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
Nirvanabesh: {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
Skyhook: {
|
||||
ligatures: [],
|
||||
lowercase: false,
|
||||
},
|
||||
};
|
||||
|
||||
const fontNames = Object.keys(fonts);
|
||||
|
||||
const selectedFont = signal("AurebeshAF-Legends");
|
||||
effect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
document.documentElement.style.setProperty(
|
||||
"--font-aurebesh",
|
||||
selectedFont.value
|
||||
);
|
||||
}
|
||||
});
|
||||
const ligatures = computed(() => {
|
||||
return fonts[selectedFont.value].ligatures;
|
||||
});
|
||||
const lowercase = computed(() => {
|
||||
return fonts[selectedFont.value].lowercase;
|
||||
});
|
||||
import Reference from "./Reference";
|
||||
import FontPicker from "./FontPicker";
|
||||
import DualText from "./DualText";
|
||||
|
||||
export default function Main() {
|
||||
useEffect(() => {
|
||||
|
@ -105,7 +23,7 @@ export default function Main() {
|
|||
<>
|
||||
<header>
|
||||
<h1>
|
||||
<DualText>Learn Aurebesh</DualText>
|
||||
<DualText text="Learn Aurebesh" />
|
||||
</h1>
|
||||
</header>
|
||||
<main>
|
||||
|
@ -118,85 +36,3 @@ export default function Main() {
|
|||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function FontPicker() {
|
||||
return (
|
||||
<select
|
||||
onChange={(event) => {
|
||||
const newValue = event.currentTarget.value;
|
||||
selectedFont.value = newValue;
|
||||
localforage.setItem("aurebesh-font", newValue);
|
||||
}}
|
||||
>
|
||||
{fontNames.map((font) => {
|
||||
return (
|
||||
<option value={font} selected={font === selectedFont.value}>
|
||||
{font}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
|
||||
function DualText({ children }: { children: string }) {
|
||||
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 (
|
||||
<span>
|
||||
{words.map((word) => {
|
||||
if (word === "\n") {
|
||||
return <br />;
|
||||
}
|
||||
const letters: string[] = [];
|
||||
for (let i = 0; i < word.length; i += 1) {
|
||||
const nextTwoCharacters = word.slice(i, i + 2);
|
||||
if (ligatures.value.includes(nextTwoCharacters.toLowerCase())) {
|
||||
letters.push(nextTwoCharacters);
|
||||
i += 1;
|
||||
} else {
|
||||
letters.push(nextTwoCharacters[0]);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<span class="dualtext-word">
|
||||
<span class="aurebesh">{word}</span>
|
||||
<div className="dualtext-help">
|
||||
{letters.map((character) => {
|
||||
return <span data-character={character} />;
|
||||
})}
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function Reference() {
|
||||
return (
|
||||
<aside class="reference">
|
||||
<DualText>
|
||||
{lowercase.value ? "Aa Bb Cc Dd Ee Ff Gg Hh Ii" : "A B C D E F G H I"}
|
||||
</DualText>
|
||||
<DualText>
|
||||
{lowercase.value ? "Jj Kk Ll Mm Nn Oo Pp Qq Rr" : "J K L M N O P Q R"}
|
||||
</DualText>
|
||||
<DualText>
|
||||
{lowercase.value ? "Ss Tt Uu Vv Ww Xx Yy Zz" : "S T U V W X Y Z"}
|
||||
</DualText>
|
||||
<DualText>0 1 2 3 4 5 6 7 8 9</DualText>
|
||||
{ligatures.value.length > 0 && (
|
||||
<DualText>{ligatures.value.join(" ")}</DualText>
|
||||
)}
|
||||
<DualText>{`, . ? ! : ; ' " ( )`}</DualText>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ Pursued by the Empire's sinister agents, Princess Leia races home aboard her sta
|
|||
}}
|
||||
/>
|
||||
</span>
|
||||
{isEditing.value ? (
|
||||
{isEditing.value && (
|
||||
<textarea
|
||||
class="readingbox-textarea"
|
||||
id="reading-material"
|
||||
|
@ -48,11 +48,10 @@ Pursued by the Empire's sinister agents, Princess Leia races home aboard her sta
|
|||
}}
|
||||
spellCheck={false}
|
||||
/>
|
||||
) : (
|
||||
<div class="readingbox-text aurebesh">
|
||||
<DualText>{contents.value}</DualText>
|
||||
</div>
|
||||
)}
|
||||
<div class="readingbox-text aurebesh">
|
||||
<DualText text={contents.value} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,20 +4,18 @@ import { ligatures, lowercase } from "./store";
|
|||
export default function Reference() {
|
||||
return (
|
||||
<aside class="reference">
|
||||
<DualText>
|
||||
{lowercase.value ? "Aa Bb Cc Dd Ee Ff Gg Hh Ii" : "A B C D E F G H I"}
|
||||
</DualText>
|
||||
<DualText>
|
||||
{lowercase.value ? "Jj Kk Ll Mm Nn Oo Pp Qq Rr" : "J K L M N O P Q R"}
|
||||
</DualText>
|
||||
<DualText>
|
||||
{lowercase.value ? "Ss Tt Uu Vv Ww Xx Yy Zz" : "S T U V W X Y Z"}
|
||||
</DualText>
|
||||
<DualText>0 1 2 3 4 5 6 7 8 9</DualText>
|
||||
<DualText
|
||||
text={
|
||||
lowercase.value
|
||||
? "Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz"
|
||||
: "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
|
||||
}
|
||||
/>
|
||||
<DualText text="0 1 2 3 4 5 6 7 8 9" />
|
||||
{ligatures.value.length > 0 && (
|
||||
<DualText>{ligatures.value.join(" ")}</DualText>
|
||||
<DualText text={ligatures.value.join(" ")} />
|
||||
)}
|
||||
<DualText>{`, . ? ! : ; ' " ( )`}</DualText>
|
||||
<DualText text={`, . ? ! : ; ' " ( )`} />
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ export const fonts: Record<
|
|||
|
||||
export const fontNames = Object.keys(fonts);
|
||||
|
||||
export const selectedFont = signal("AurebeshAF-Legends");
|
||||
export const selectedFont = signal("AurebeshAF-Canon");
|
||||
effect(() => {
|
||||
if (typeof window !== "undefined") {
|
||||
document.documentElement.style.setProperty(
|
||||
|
|
|
@ -5,18 +5,22 @@
|
|||
@font-face {
|
||||
font-family: "AurebeshAF-Canon";
|
||||
src: url(/fonts/AurebeshAF-Canon.otf) format("opentype");
|
||||
size-adjust: 80%;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "AurebeshAF-CanonTech";
|
||||
src: url(/fonts/AurebeshAF-CanonTech.otf) format("opentype");
|
||||
size-adjust: 80%;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "AurebeshAF-Legends";
|
||||
src: url(/fonts/AurebeshAF-Legends.otf) format("opentype");
|
||||
size-adjust: 80%;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "AurebeshAF-LegendsTech";
|
||||
src: url(/fonts/AurebeshAF-LegendsTech.otf) format("opentype");
|
||||
size-adjust: 80%;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Aurebesh_Rodian-Oblique";
|
||||
|
@ -86,7 +90,7 @@
|
|||
--font-aurebesh: Droidobesh;
|
||||
--font-standard: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
|
||||
font-size: clamp(100%, 1.5rem + 3vw, 350%);
|
||||
font-size: clamp(100%, 0.5rem + 1vw, 150%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
@ -108,6 +112,17 @@ body {
|
|||
);
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
line-height: 1.15;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#app {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
|
@ -121,10 +136,11 @@ body {
|
|||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(1rem, 3rem, 9vw);
|
||||
font-size: clamp(1rem, 1.75rem, 9vw);
|
||||
}
|
||||
|
||||
.aurebesh {
|
||||
font-size: 1.5em;
|
||||
font-family: var(--font-aurebesh);
|
||||
}
|
||||
|
||||
|
@ -153,7 +169,8 @@ h1 {
|
|||
.dualtext-help > span {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
transition: opacity 0.25s ease-in;
|
||||
transition: opacity 0.1s ease-in;
|
||||
transition-delay: 0.15s;
|
||||
}
|
||||
.dualtext-help > span::before {
|
||||
content: attr(data-character);
|
||||
|
@ -171,18 +188,17 @@ h1 {
|
|||
padding: 0.1em 0.25em;
|
||||
min-width: 100%;
|
||||
font-family: var(--font-standard);
|
||||
font-size: clamp(0.75rem, 0.25em, 1rem);
|
||||
font-size: clamp(0.75rem, 0.4em, 1rem);
|
||||
line-height: 1;
|
||||
font-weight: 400;
|
||||
color: var(--color-text-light);
|
||||
}
|
||||
|
||||
.reference {
|
||||
font-size: clamp(1rem, 1.5rem, 6vw);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
padding-bottom: 1rem;
|
||||
gap: 0.5em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
main {
|
||||
|
@ -203,7 +219,6 @@ main {
|
|||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: scroll;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
|
@ -232,5 +247,6 @@ main {
|
|||
}
|
||||
.readingbox .dualtext-help > span:hover {
|
||||
opacity: 1;
|
||||
outline: 1px solid var(--color-accent2);
|
||||
box-shadow: 0 0 1em 0.2em var(--color-accent2);
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue