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

@ -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; }