Japanese flashcards!

This commit is contained in:
Eryn Wells 2023-03-13 21:06:45 -07:00
parent 533bc1138c
commit 78bd1e4a4e
13 changed files with 315 additions and 38 deletions

View file

@ -17,6 +17,8 @@
--purple: 161, 49, 232; --purple: 161, 49, 232;
--lilac: 187, 121, 245; --lilac: 187, 121, 245;
--background: var(--white);
--site-nav-link-color: rgb(var(--mid-blue)); --site-nav-link-color: rgb(var(--mid-blue));
--separator-color: rgb(var(--lt-gray)); --separator-color: rgb(var(--lt-gray));
@ -42,7 +44,7 @@
--heading-color: rgb(var(--black)); --heading-color: rgb(var(--black));
--header-series-arrow-foreground-color: rgb(var(--sub-dk-gray)); --header-series-arrow-foreground-color: rgb(var(--sub-dk-gray));
--html-background-color: rgb(var(--white)); --html-background-color: rgb(var(--background));
--html-color: rgba(var(--black), 0.8); --html-color: rgba(var(--black), 0.8);
--nav-bulleted-spacing: 0.75rem; --nav-bulleted-spacing: 0.75rem;
@ -69,6 +71,8 @@
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
:root { :root {
--background: var(--black);
--separator-color: rgb(var(--dk-gray)); --separator-color: rgb(var(--dk-gray));
--box-shadow-color: rgba(var(--dk-gray), 0.8); --box-shadow-color: rgba(var(--dk-gray), 0.8);
--body-code-background-color: rgb(var(--dk-gray)); --body-code-background-color: rgb(var(--dk-gray));
@ -76,7 +80,7 @@
--heading-color: rgb(var(--white)); --heading-color: rgb(var(--white));
--header-series-arrow-foreground-color: rgb(var(--super-dk-gray)); --header-series-arrow-foreground-color: rgb(var(--super-dk-gray));
--html-background-color: rgb(var(--black)); --html-background-color: rgb(var(--background));
--html-color: rgba(var(--white), 0.8); --html-color: rgba(var(--white), 0.8);
--platter-background-color: rgba(var(--black), var(--platter-background-opacity)); --platter-background-color: rgba(var(--black), var(--platter-background-opacity));

View file

@ -1,4 +1,9 @@
en: en:
languageName: English
weight: 1 weight: 1
es: es:
languageName: Español
weight: 2 weight: 2
jp:
languageName: 日本語
weight: 3

View file

@ -0,0 +1,6 @@
---
title: 私の日本語
layout: flashcards
---
日本語学生です。

View file

@ -0,0 +1,6 @@
---
title: My Japanese
layout: flashcards
---
I am a Japanese language student.

View file

@ -0,0 +1,18 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Ruby</title>
<link rel="stylesheet" href="style.css">
<script preload src="script.js"></script>
</head>
<body>
<header>
<h1>Flash Cards</h1>
<div class="controls">
<input id="furigana" type="checkbox">
<label for="furigana">Furigana</label>
</div>
</header>
</body>
</html>

View file

@ -0,0 +1,49 @@
// Eryn Wells <eryn@erynwells.me>
document.addEventListener("DOMContentLoaded", (event) => {
const furiganaRegex = /(「(.*?)『(.*?)』」)|.*/g;
let parseFlashcardString = str => {
let innerHTML = "";
for (let match of str.matchAll(furiganaRegex)) {
if (match[2] && match[3]) {
const mainText = match[2];
const furiganaText = match[3];
console.debug(`${mainText} is ${mainText.length} characters long`);
innerHTML += `<ruby>${mainText}<rp>(</rp><rt>${furiganaText}</rt><rp>)</rp></ruby>`;
} else {
innerHTML += match[0];
}
}
return innerHTML;
};
let cardsContainer = document.querySelector("section.flashcards > ul");
if (!cardsContainer) {
console.error("Can't find flashcards <ul> element");
return;
}
for (let card of flashcards.cards) {
let frontElement = `<div class="front" lang="${card.front.lang}">${parseFlashcardString(card.front.value)}</div>`;
let backElement = `<div class="back" lang="${card.back.lang}">${parseFlashcardString(card.back.value)}</div>`;
let cardElement = document.createElement("div");
cardElement.classList.add("card")
cardElement.innerHTML = frontElement + backElement;
cardElement.addEventListener("click", (event) => {
let element = event.target;
console.log("Flipping", element);
element.classList.toggle("flipped");
}, true);
let cardContainerElement = document.createElement("li");
cardContainerElement.classList.add("card-container");
cardContainerElement.appendChild(cardElement);
cardsContainer.appendChild(cardContainerElement);
}
});

View file

@ -0,0 +1,110 @@
/* Eryn Wells <eryn@erynwells.me> */
:root {
--card-drop-shadow-spread: 10px;
--card-drop-shadow-color: rgb(var(--lt-gray));
--gradient-full-opaque: var(--background);
}
@media (prefers-color-scheme: dark) {
:root {
--card-drop-shadow-color: rgb(var(--dk-gray));
}
}
section.flashcards {
position: relative;
}
section.flashcards > ul {
align-items: stretch;
display: flex;
flex-flow: row nowrap;
margin: 0;
overflow-x: scroll;
scroll-snap-type: x mandatory;
padding: 0;
}
section.flashcards > ul > li {
padding: 0;
margin: 0;
}
section.flashcards > ul::-webkit-scrollbar {
width: 0;
background: transparent;
}
section.flashcards > .shadow {
position: absolute;
top: 0;
height: 100%;
width: 5%;
z-index: 10;
}
section.flashcards > .shadow.left {
background: linear-gradient(
to right,
rgba(var(--gradient-full-opaque), 1),
rgba(var(--gradient-full-opaque), 0));
left: 0;
}
section.flashcards > .shadow.right {
background: linear-gradient(
to left,
rgba(var(--gradient-full-opaque), 1),
rgba(var(--gradient-full-opaque), 0));
right: 0;
}
ruby>rt,
ruby>rp {
visibility: hidden;
opacity: 0;
transition: 0.25s;
}
.card:hover ruby>rt,
.card:hover ruby>rp {
visibility: visible;
opacity: 0.8;
transition: 0.4s;
}
section.flashcards > ul > li.card-container {
display: flex;
justify-content: center;
align-items: center;
width: var(--content-width);
flex-shrink: 0;
padding-block: var(--card-drop-shadow-spread);
}
.card {
box-sizing: border-box;
border: 1px solid var(--separator-color);
display: flex;
justify-content: center;
align-items: center;
padding: 2rem;
text-align: center;
box-shadow: 4px 4px var(--card-drop-shadow-spread) var(--card-drop-shadow-color);
scroll-snap-align: center;
aspect-ratio: 4/3;
width: calc(var(--content-width) / 2);
}
.vertical {
text-orientation: upright;
writing-mode: vertical-rl;
}
.card > [lang="jp"] { font-size: 300%; }
.card > [lang="en"] { font-size: 200%; }
.card > .front { display: block; }
.card > .back { display: none; }
.card.flipped > .front { display: none; }
.card.flipped > .back { display: block; }

View file

@ -0,0 +1,64 @@
{
"cards": [
{
"front": { "lang": "jp", "value": "「食『た』」べます" },
"back": { "lang": "en", "value": "to eat" }
},
{
"front": { "lang": "jp", "value": "「飲『の』」みます" },
"back": { "lang": "en", "value": "to drink" }
},
{
"front": { "lang": "jp", "value": "「起『お』」きます" },
"back": { "lang": "en", "value": "to get up, awaken" }
},
{
"front": { "lang": "jp", "value": "「寝『ね』」ます" },
"back": { "lang": "en", "value": "to go to bed, sleep" }
},
{
"front": { "lang": "jp", "value": "「行『い』」きます" },
"back": { "lang": "en", "value": "to go" }
},
{
"front": { "lang": "jp", "value": "「今『いま』」" },
"back": { "lang": "en", "value": "now" }
},
{
"front": { "lang": "jp", "value": "「毎『まい』」「日『にち』」" },
"back": { "lang": "en", "value": "every day" }
},
{
"front": { "lang": "jp", "value": "「午『ご』」「後『ご』」" },
"back": { "lang": "en", "value": "in the afternoon, p.m." }
},
{
"front": { "lang": "jp", "value": "「午『ご』」「前『ぜん』」" },
"back": { "lang": "en", "value": "in the morning, a.m." }
},
{
"front": { "lang": "jp", "value": "「時『じ』」" },
"back": { "lang": "en", "value": "oclock, time, when" }
},
{
"front": { "lang": "jp", "value": "「会『かい』」「社『しゃ』」" },
"back": { "lang": "en", "value": "office, company" }
},
{
"front": { "lang": "jp", "value": "「毎『まい』」「朝『あさ』」" },
"back": { "lang": "en", "value": "every morning" }
},
{
"front": { "lang": "jp", "value": "「零『れい』」「時『じ』」" },
"back": { "lang": "en", "value": "midnight" }
},
{
"front": { "lang": "jp", "value": "「犬『いぬ』」" },
"back": { "lang": "en", "value": "dog" }
},
{
"front": { "lang": "jp", "value": "「猫『ねこ』」" },
"back": { "lang": "en", "value": "cat" }
}
]
}

View file

@ -3,30 +3,9 @@
{{ end }} {{ end }}
{{ define "styles" }} {{ define "styles" }}
{{- range .Resources.Match "*.css" -}} {{ partial "single_styles.html" . }}
{{- $stylesheet := . | fingerprint "md5" }}
<link rel="stylesheet" href="{{ $stylesheet.RelPermalink }}"></script>
{{- end -}}
{{ end }} {{ end }}
{{ define "scripts" }} {{ define "scripts" }}
{{- if .HasShortcode "figures/railroad" -}} {{ partial "single_scripts.html" . }}
{{- with partial "resources/railroad_utils.html" . -}}
<script defer type="module" src="{{ .RelPermalink }}"></script>
{{- end -}}
{{- end -}}
{{- if .HasShortcode "figures/p5" -}}
{{- with partial "secure_asset.html" "scripts/lib/p5-1.5.0.js" -}}
<script defer src="{{ .Secure.RelPermalink }}"></script>
{{- end -}}
{{- with partial "secure_asset.html" "scripts/sketch-utils.js" -}}
<script defer src="{{ .Secure.RelPermalink }}"></script>
{{- end -}}
{{- end -}}
{{- range $script := .Resources.Match "*.js" -}}
{{- $isModule := default true $script.Params.is_module -}}
<script defer {{ if $isModule }}type="module"{{ end }} src="{{ $script.Permalink | relURL }}"></script>
{{- end -}}
{{ end }} {{ end }}

View file

@ -0,0 +1,25 @@
{{ define "main" }}
{{ partial "content_header.html" . }}
<nav class="languages">
{{ range .AllTranslations }}
<a href="{{ .Permalink }}">{{ .Language.LanguageName }}</a>
{{ end }}
</nav>
<section class="flashcards">
<div class="shadow left"></div>
<div class="shadow right"></div>
<ul></ul>
</section>
{{ end }}
{{ define "styles" }}
{{ partial "single_styles.html" . }}
{{ end }}
{{ define "scripts" }}
{{- $flashcards := index $.Site.Data.nihongo.flashcards "all" -}}
<script>
const flashcards = {{ $flashcards | jsonify | safeJS }};
</script>
{{ partial "single_scripts.html" . }}
{{ end }}

View file

@ -2,7 +2,7 @@
{{ partial "development/draft_tag.html" . }} {{ partial "development/draft_tag.html" . }}
<div class="post-title"> <div class="post-title">
<h1>{{ .Title }}</h1> <h1>{{ .Title }}</h1>
{{ if not (eq .Section "about") }} {{ if and (not (eq .Section "about")) .Date }}
<div class="post-date"><time>{{ .Date | time.Format "January 2, 2006" }}</time></div> <div class="post-date"><time>{{ .Date | time.Format "January 2, 2006" }}</time></div>
{{ end }} {{ end }}
</div> </div>

View file

@ -1,12 +1,19 @@
{{ if .Page.Scratch.Get "includes_railroad_diagram" }} {{- if .HasShortcode "figures/railroad" -}}
<script defer type="module" src="{{ `scripts/railroad.js` | absURL }}"></script> {{- with partial "resources/railroad_utils.html" . -}}
<script defer type="module" src="{{ `scripts/railroad-utils.js` | absURL }}"></script> <script defer type="module" src="{{ .RelPermalink }}"></script>
{{ end }} {{- end -}}
{{ if .Page.Scratch.Get "includes_p5_sketch" }} {{- end -}}
<script defer src="{{ `scripts/p5-1.4.1.min.js` | absURL }}"></script>
<script defer src="{{ `scripts/sketch-utils.js` | absURL }}"></script> {{- if .HasShortcode "figures/p5" -}}
{{ end }} {{- with partial "secure_asset.html" "scripts/lib/p5-1.5.0.js" -}}
{{ range $script := .Resources.Match "*.js" }} <script defer src="{{ .Secure.RelPermalink }}"></script>
{{ $isModule := default true $script.Params.is_module }} {{- end -}}
<script defer {{ if $isModule }}type="module"{{ end }} src="{{ $script.Permalink | relURL }}"></script> {{- with partial "secure_asset.html" "scripts/sketch-utils.js" -}}
{{ end }} <script defer src="{{ .Secure.RelPermalink }}"></script>
{{- end -}}
{{- end -}}
{{- range $script := .Resources.Match "*.js" -}}
{{- $isModule := default true $script.Params.is_module -}}
<script defer {{ if $isModule }}type="module"{{ end }} src="{{ $script.Permalink | relURL }}"></script>
{{- end -}}

View file

@ -0,0 +1,4 @@
{{- range .Resources.Match "*.css" -}}
{{- $stylesheet := . | fingerprint "md5" }}
<link rel="stylesheet" href="{{ $stylesheet.RelPermalink }}"></script>
{{- end -}}