Japanese flashcards!
This commit is contained in:
parent
533bc1138c
commit
78bd1e4a4e
13 changed files with 315 additions and 38 deletions
|
@ -17,6 +17,8 @@
|
|||
--purple: 161, 49, 232;
|
||||
--lilac: 187, 121, 245;
|
||||
|
||||
--background: var(--white);
|
||||
|
||||
--site-nav-link-color: rgb(var(--mid-blue));
|
||||
|
||||
--separator-color: rgb(var(--lt-gray));
|
||||
|
@ -42,7 +44,7 @@
|
|||
--heading-color: rgb(var(--black));
|
||||
--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);
|
||||
|
||||
--nav-bulleted-spacing: 0.75rem;
|
||||
|
@ -69,6 +71,8 @@
|
|||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: var(--black);
|
||||
|
||||
--separator-color: rgb(var(--dk-gray));
|
||||
--box-shadow-color: rgba(var(--dk-gray), 0.8);
|
||||
--body-code-background-color: rgb(var(--dk-gray));
|
||||
|
@ -76,7 +80,7 @@
|
|||
--heading-color: rgb(var(--white));
|
||||
--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);
|
||||
|
||||
--platter-background-color: rgba(var(--black), var(--platter-background-opacity));
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
en:
|
||||
languageName: English
|
||||
weight: 1
|
||||
es:
|
||||
languageName: Español
|
||||
weight: 2
|
||||
jp:
|
||||
languageName: 日本語
|
||||
weight: 3
|
||||
|
|
6
content/nihongo/flashcards/index.jp.md
Normal file
6
content/nihongo/flashcards/index.jp.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: 私の日本語
|
||||
layout: flashcards
|
||||
---
|
||||
|
||||
日本語学生です。
|
6
content/nihongo/flashcards/index.md
Normal file
6
content/nihongo/flashcards/index.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: My Japanese
|
||||
layout: flashcards
|
||||
---
|
||||
|
||||
I am a Japanese language student.
|
18
content/nihongo/flashcards/old_index.html
Normal file
18
content/nihongo/flashcards/old_index.html
Normal 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>
|
49
content/nihongo/flashcards/script.js
Normal file
49
content/nihongo/flashcards/script.js
Normal 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);
|
||||
}
|
||||
});
|
110
content/nihongo/flashcards/style.css
Normal file
110
content/nihongo/flashcards/style.css
Normal 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; }
|
64
data/nihongo/flashcards/all.json
Normal file
64
data/nihongo/flashcards/all.json
Normal 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": "o’clock, 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" }
|
||||
}
|
||||
]
|
||||
}
|
|
@ -3,30 +3,9 @@
|
|||
{{ end }}
|
||||
|
||||
{{ define "styles" }}
|
||||
{{- range .Resources.Match "*.css" -}}
|
||||
{{- $stylesheet := . | fingerprint "md5" }}
|
||||
<link rel="stylesheet" href="{{ $stylesheet.RelPermalink }}"></script>
|
||||
{{- end -}}
|
||||
{{ partial "single_styles.html" . }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "scripts" }}
|
||||
{{- if .HasShortcode "figures/railroad" -}}
|
||||
{{- 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 -}}
|
||||
{{ partial "single_scripts.html" . }}
|
||||
{{ end }}
|
||||
|
|
25
layouts/nihongo/flashcards.html
Normal file
25
layouts/nihongo/flashcards.html
Normal 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 }}
|
|
@ -2,7 +2,7 @@
|
|||
{{ partial "development/draft_tag.html" . }}
|
||||
<div class="post-title">
|
||||
<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>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
{{ if .Page.Scratch.Get "includes_railroad_diagram" }}
|
||||
<script defer type="module" src="{{ `scripts/railroad.js` | absURL }}"></script>
|
||||
<script defer type="module" src="{{ `scripts/railroad-utils.js` | absURL }}"></script>
|
||||
{{ end }}
|
||||
{{ if .Page.Scratch.Get "includes_p5_sketch" }}
|
||||
<script defer src="{{ `scripts/p5-1.4.1.min.js` | absURL }}"></script>
|
||||
<script defer src="{{ `scripts/sketch-utils.js` | absURL }}"></script>
|
||||
{{ 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 }}
|
||||
{{- if .HasShortcode "figures/railroad" -}}
|
||||
{{- 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 -}}
|
||||
|
|
4
layouts/partials/single_styles.html
Normal file
4
layouts/partials/single_styles.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
{{- range .Resources.Match "*.css" -}}
|
||||
{{- $stylesheet := . | fingerprint "md5" }}
|
||||
<link rel="stylesheet" href="{{ $stylesheet.RelPermalink }}"></script>
|
||||
{{- end -}}
|
Loading…
Add table
Add a link
Reference in a new issue