mirror of
https://github.com/eigilnikolajsen/commit-mono.git
synced 2024-09-11 18:37:12 +03:00
rerun prettier
This commit is contained in:
parent
cb3973b1f0
commit
6e5fa43fb1
@ -1,6 +1,5 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"tabs": 4,
|
||||
"useTabs": true,
|
||||
"semi": false
|
||||
"printWidth": 120,
|
||||
"tabWidth": 2,
|
||||
"semi": false
|
||||
}
|
||||
|
60
calt.js
60
calt.js
@ -2,48 +2,48 @@ const fs = require("fs")
|
||||
const readline = require("readline")
|
||||
|
||||
function pbcopy(data) {
|
||||
var proc = require("child_process").spawn("pbcopy")
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.end()
|
||||
var proc = require("child_process").spawn("pbcopy")
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.end()
|
||||
}
|
||||
|
||||
async function featuresToCalt() {
|
||||
const features = ["ss01_arrows", "ss02_less_equal", "ss03_case", "ss04_ellipsis", "ss05_smartkerning"]
|
||||
const features = ["ss01_arrows", "ss02_less_equal", "ss03_case", "ss04_ellipsis", "ss05_smartkerning"]
|
||||
|
||||
let calt = []
|
||||
let calt = []
|
||||
|
||||
for await (const feature of features) {
|
||||
const fileStream = fs.createReadStream(`features/${feature}.fea`)
|
||||
for await (const feature of features) {
|
||||
const fileStream = fs.createReadStream(`features/${feature}.fea`)
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: fileStream,
|
||||
crlfDelay: Infinity,
|
||||
})
|
||||
// Note: we use the crlfDelay option to recognize all instances of CR LF
|
||||
// ('\r\n') in input.txt as a single line break.
|
||||
const rl = readline.createInterface({
|
||||
input: fileStream,
|
||||
crlfDelay: Infinity,
|
||||
})
|
||||
// Note: we use the crlfDelay option to recognize all instances of CR LF
|
||||
// ('\r\n') in input.txt as a single line break.
|
||||
|
||||
const lines = []
|
||||
const lines = []
|
||||
|
||||
lines.push(`### feature ${feature} ###`)
|
||||
lines.push(`### feature ${feature} ###`)
|
||||
|
||||
for await (const line of rl) {
|
||||
// Each line in input.txt will be successively available here as `line`.
|
||||
// console.log(`Line from file: ${line}`)
|
||||
lines.push(line)
|
||||
}
|
||||
for await (const line of rl) {
|
||||
// Each line in input.txt will be successively available here as `line`.
|
||||
// console.log(`Line from file: ${line}`)
|
||||
lines.push(line)
|
||||
}
|
||||
|
||||
calt.push(lines)
|
||||
}
|
||||
calt.push(lines)
|
||||
}
|
||||
|
||||
calt = calt.flat().filter((ln) => !ln.includes("feature") && !ln.includes("} ss"))
|
||||
calt = calt.map((ln) => {
|
||||
if (ln.includes("lookup")) return ln.split("lookup ").join("lookup _")
|
||||
if (ln.includes("} ")) return ln.split("} ").join("} _")
|
||||
return ln
|
||||
})
|
||||
calt = calt.flat().filter((ln) => !ln.includes("feature") && !ln.includes("} ss"))
|
||||
calt = calt.map((ln) => {
|
||||
if (ln.includes("lookup")) return ln.split("lookup ").join("lookup _")
|
||||
if (ln.includes("} ")) return ln.split("} ").join("} _")
|
||||
return ln
|
||||
})
|
||||
|
||||
// calt.forEach((ln) => console.log(ln))
|
||||
pbcopy(`
|
||||
// calt.forEach((ln) => console.log(ln))
|
||||
pbcopy(`
|
||||
feature calt {
|
||||
# Contextual Alternates
|
||||
# Contains all 'cxxx' features
|
||||
|
54
classes.html
54
classes.html
@ -1,30 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Generate Axis Value</title>
|
||||
</head>
|
||||
<body>
|
||||
<br />
|
||||
<label for="classes">Classes</label>
|
||||
<br />
|
||||
<br />
|
||||
<textarea id="classes" name="classes" rows="20" cols="60"></textarea>
|
||||
<br />
|
||||
<br />
|
||||
<button type="submit" id="submit">Submit</button>
|
||||
<br />
|
||||
<br />
|
||||
<p style="user-select: all" id="result"></p>
|
||||
<script>
|
||||
const classes = document.querySelector("#classes")
|
||||
const result = document.querySelector("#result")
|
||||
const submit = document.querySelector("#submit")
|
||||
submit.addEventListener("click", () => {
|
||||
result.textContent = [...new Set(classes.value.split(" "))].join(" ")
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Generate Axis Value</title>
|
||||
</head>
|
||||
<body>
|
||||
<br />
|
||||
<label for="classes">Classes</label>
|
||||
<br />
|
||||
<br />
|
||||
<textarea id="classes" name="classes" rows="20" cols="60"></textarea>
|
||||
<br />
|
||||
<br />
|
||||
<button type="submit" id="submit">Submit</button>
|
||||
<br />
|
||||
<br />
|
||||
<p style="user-select: all" id="result"></p>
|
||||
<script>
|
||||
const classes = document.querySelector("#classes")
|
||||
const result = document.querySelector("#result")
|
||||
const submit = document.querySelector("#submit")
|
||||
submit.addEventListener("click", () => {
|
||||
result.textContent = [...new Set(classes.value.split(" "))].join(" ")
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
22
f.js
22
f.js
@ -6,10 +6,10 @@
|
||||
// @c3_3 = [exclam.c3_3 comma.c3_3 period.c3_3 slash.c3_3 colon.c3_3 semicolon.c3_3 question.c3_3 backslash.c3_3 bar.c3_3];
|
||||
|
||||
const input =
|
||||
"exclam exclam.square comma period period.square slash slash.case colon colon.square colon.case colon.case.square semicolon semicolon.square semicolon.case semicolon.case.square question question.square backslash backslash.case bar bar.case less less.case greater greater.case asterisk asterisk.case plus plus.case hyphen hyphen.case equal equal.case asciitilde asciitilde.case"
|
||||
"exclam exclam.square comma period period.square slash slash.case colon colon.square colon.case colon.case.square semicolon semicolon.square semicolon.case semicolon.case.square question question.square backslash backslash.case bar bar.case less less.case greater greater.case asterisk asterisk.case plus plus.case hyphen hyphen.case equal equal.case asciitilde asciitilde.case"
|
||||
function c002(input) {
|
||||
const s = input.split(" ")
|
||||
return `
|
||||
const s = input.split(" ")
|
||||
return `
|
||||
@dflt = [${input}];
|
||||
@c2_1 = [${s.join(".c2_1 ")}.c2_1];
|
||||
@c2_2 = [${s.join(".c2_2 ")}.c2_2];
|
||||
@ -19,20 +19,20 @@ function c002(input) {
|
||||
}
|
||||
|
||||
function classExcess(c) {
|
||||
return [...new Set(c.split(" "))].join(" ")
|
||||
return [...new Set(c.split(" "))].join(" ")
|
||||
}
|
||||
|
||||
function buildGlyphs(g) {
|
||||
return g
|
||||
.split(", ")
|
||||
.map((gl) => gl.split("=")[0])
|
||||
.join(", ")
|
||||
return g
|
||||
.split(", ")
|
||||
.map((gl) => gl.split("=")[0])
|
||||
.join(", ")
|
||||
}
|
||||
|
||||
function pbcopy(data) {
|
||||
var proc = require("child_process").spawn("pbcopy")
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.end()
|
||||
var proc = require("child_process").spawn("pbcopy")
|
||||
proc.stdin.write(data)
|
||||
proc.stdin.end()
|
||||
}
|
||||
|
||||
pbcopy(c002(input))
|
||||
|
1136
index.html
1136
index.html
File diff suppressed because it is too large
Load Diff
100
instances.html
100
instances.html
@ -1,53 +1,53 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Generate Axis Value</title>
|
||||
<style>
|
||||
#resultButton {
|
||||
user-select: all;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<label for="start">Start value</label>
|
||||
<input type="text" name="start" id="start" />
|
||||
<br />
|
||||
<br />
|
||||
<label for="end">End value</label>
|
||||
<input type="text" name="end" id="end" />
|
||||
<br />
|
||||
<br />
|
||||
<label for="precision">Precision</label>
|
||||
<input type="text" name="precision" id="precision" />
|
||||
<br />
|
||||
<br />
|
||||
<button type="submit" id="submit">Submit</button>
|
||||
<br />
|
||||
<br />
|
||||
<p id="resultButton"></p>
|
||||
<script>
|
||||
const submit = document.querySelector("#submit")
|
||||
const start = document.querySelector("#start")
|
||||
const end = document.querySelector("#end")
|
||||
const precision = document.querySelector("#precision")
|
||||
const resultButton = document.querySelector("#resultButton")
|
||||
submit.addEventListener("click", () => {
|
||||
const result = generateAxisValue([+start.value, +end.value], +precision.value)
|
||||
resultButton.textContent = result
|
||||
navigator.clipboard.writeText(result)
|
||||
})
|
||||
const generateAxisValue = ([start, end], precision) => {
|
||||
let value = start
|
||||
let result = ""
|
||||
while (value <= end) {
|
||||
result += `"${value}"=${value}, `
|
||||
value += precision
|
||||
}
|
||||
return result.slice(0, -2)
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Generate Axis Value</title>
|
||||
<style>
|
||||
#resultButton {
|
||||
user-select: all;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<label for="start">Start value</label>
|
||||
<input type="text" name="start" id="start" />
|
||||
<br />
|
||||
<br />
|
||||
<label for="end">End value</label>
|
||||
<input type="text" name="end" id="end" />
|
||||
<br />
|
||||
<br />
|
||||
<label for="precision">Precision</label>
|
||||
<input type="text" name="precision" id="precision" />
|
||||
<br />
|
||||
<br />
|
||||
<button type="submit" id="submit">Submit</button>
|
||||
<br />
|
||||
<br />
|
||||
<p id="resultButton"></p>
|
||||
<script>
|
||||
const submit = document.querySelector("#submit")
|
||||
const start = document.querySelector("#start")
|
||||
const end = document.querySelector("#end")
|
||||
const precision = document.querySelector("#precision")
|
||||
const resultButton = document.querySelector("#resultButton")
|
||||
submit.addEventListener("click", () => {
|
||||
const result = generateAxisValue([+start.value, +end.value], +precision.value)
|
||||
resultButton.textContent = result
|
||||
navigator.clipboard.writeText(result)
|
||||
})
|
||||
const generateAxisValue = ([start, end], precision) => {
|
||||
let value = start
|
||||
let result = ""
|
||||
while (value <= end) {
|
||||
result += `"${value}"=${value}, `
|
||||
value += precision
|
||||
}
|
||||
return result.slice(0, -2)
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,27 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "CommitMono";
|
||||
src: url("/fonts/CommitMono.woff2");
|
||||
font-weight: 450;
|
||||
}
|
||||
:root {
|
||||
--grey: #aaa;
|
||||
}
|
||||
button#grey::before {
|
||||
content: "01";
|
||||
font-style: italic;
|
||||
font-size: 2rem;
|
||||
color: var(--grey);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button id="grey">Commit Mono</button>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "CommitMono";
|
||||
src: url("/fonts/CommitMono.woff2");
|
||||
font-weight: 450;
|
||||
}
|
||||
:root {
|
||||
--grey: #aaa;
|
||||
}
|
||||
button#grey::before {
|
||||
content: "01";
|
||||
font-style: italic;
|
||||
font-size: 2rem;
|
||||
color: var(--grey);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button id="grey">Commit Mono</button>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -6,53 +6,53 @@
|
||||
*/
|
||||
|
||||
function lcs(arr1, arr2) {
|
||||
let matrix = [...Array(arr1.length + 1)].fill(0).map(() => Array(arr2.length + 1).fill(0))
|
||||
let matrix = [...Array(arr1.length + 1)].fill(0).map(() => Array(arr2.length + 1).fill(0))
|
||||
|
||||
for (let rowIndex = 1; rowIndex <= arr1.length; rowIndex++) {
|
||||
for (let columnIndex = 1; columnIndex <= arr2.length; columnIndex++) {
|
||||
if (arr1[rowIndex - 1] === arr2[columnIndex - 1]) {
|
||||
matrix[rowIndex][columnIndex] = 1 + matrix[rowIndex - 1][columnIndex - 1]
|
||||
} else {
|
||||
matrix[rowIndex][columnIndex] = Math.max(matrix[rowIndex - 1][columnIndex], matrix[rowIndex][columnIndex - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
//If there is no match, printing empty string
|
||||
if (matrix[arr1.length][arr2.index] === 0) {
|
||||
console.log("")
|
||||
return
|
||||
}
|
||||
for (let rowIndex = 1; rowIndex <= arr1.length; rowIndex++) {
|
||||
for (let columnIndex = 1; columnIndex <= arr2.length; columnIndex++) {
|
||||
if (arr1[rowIndex - 1] === arr2[columnIndex - 1]) {
|
||||
matrix[rowIndex][columnIndex] = 1 + matrix[rowIndex - 1][columnIndex - 1]
|
||||
} else {
|
||||
matrix[rowIndex][columnIndex] = Math.max(matrix[rowIndex - 1][columnIndex], matrix[rowIndex][columnIndex - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
//If there is no match, printing empty string
|
||||
if (matrix[arr1.length][arr2.index] === 0) {
|
||||
console.log("")
|
||||
return
|
||||
}
|
||||
|
||||
let result = []
|
||||
let rowIndex = arr1.length
|
||||
let columnIndex = arr2.length
|
||||
let result = []
|
||||
let rowIndex = arr1.length
|
||||
let columnIndex = arr2.length
|
||||
|
||||
while (rowIndex > 0 && columnIndex > 0) {
|
||||
if (arr1[rowIndex - 1] === arr2[columnIndex - 1]) {
|
||||
//Prepending everytime a new character is matched in both strings
|
||||
result.unshift(arr1[rowIndex - 1])
|
||||
rowIndex--
|
||||
columnIndex--
|
||||
} else if (matrix[rowIndex - 1][columnIndex] === matrix[rowIndex][columnIndex]) {
|
||||
rowIndex--
|
||||
} else {
|
||||
columnIndex--
|
||||
}
|
||||
}
|
||||
//Converting the LCS array into a comma separated string
|
||||
console.log(result.join(", "))
|
||||
while (rowIndex > 0 && columnIndex > 0) {
|
||||
if (arr1[rowIndex - 1] === arr2[columnIndex - 1]) {
|
||||
//Prepending everytime a new character is matched in both strings
|
||||
result.unshift(arr1[rowIndex - 1])
|
||||
rowIndex--
|
||||
columnIndex--
|
||||
} else if (matrix[rowIndex - 1][columnIndex] === matrix[rowIndex][columnIndex]) {
|
||||
rowIndex--
|
||||
} else {
|
||||
columnIndex--
|
||||
}
|
||||
}
|
||||
//Converting the LCS array into a comma separated string
|
||||
console.log(result.join(", "))
|
||||
}
|
||||
|
||||
//Usage Text
|
||||
const usage = 'Usage: please provide two lists in the format "1, 2, 3, 4, 5"'
|
||||
if (process.argv.length < 4 || process.argv[2] == "" || process.argv[3] == "") {
|
||||
console.log(usage)
|
||||
return
|
||||
console.log(usage)
|
||||
return
|
||||
} else {
|
||||
const input1 = process.argv[2]
|
||||
const input2 = process.argv[3]
|
||||
//Parsing into integers after trimming extra blank spaces
|
||||
const array1 = input1.split(",").map((x) => parseInt(x.trim(), 10))
|
||||
const array2 = input2.split(",").map((y) => parseInt(y.trim(), 10))
|
||||
lcs(array1, array2)
|
||||
const input1 = process.argv[2]
|
||||
const input2 = process.argv[3]
|
||||
//Parsing into integers after trimming extra blank spaces
|
||||
const array1 = input1.split(",").map((x) => parseInt(x.trim(), 10))
|
||||
const array2 = input2.split(",").map((y) => parseInt(y.trim(), 10))
|
||||
lcs(array1, array2)
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
function fibonacci(num: number) {
|
||||
let n = Number(num)
|
||||
let elementOne: number = 0
|
||||
let elementTwo: number = 1
|
||||
let result: number = 0
|
||||
let n = Number(num)
|
||||
let elementOne: number = 0
|
||||
let elementTwo: number = 1
|
||||
let result: number = 0
|
||||
|
||||
for (let i: number = 1; i <= n; i++) {
|
||||
result = elementOne + elementTwo
|
||||
elementOne = elementTwo
|
||||
elementTwo = result
|
||||
console.log(`${i}: ${elementOne}`)
|
||||
}
|
||||
for (let i: number = 1; i <= n; i++) {
|
||||
result = elementOne + elementTwo
|
||||
elementOne = elementTwo
|
||||
elementTwo = result
|
||||
console.log(`${i}: ${elementOne}`)
|
||||
}
|
||||
}
|
||||
|
||||
let num_str = process.argv.length >= 3 ? process.argv[2] : ""
|
||||
let num: number = parseInt(num_str)
|
||||
if (isNaN(num)) {
|
||||
console.log("Usage: please input the count of fibonacci numbers to output")
|
||||
process.exit(0)
|
||||
console.log("Usage: please input the count of fibonacci numbers to output")
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
fibonacci(num)
|
||||
|
5760
letter_group_test.js
5760
letter_group_test.js
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"icons": [
|
||||
{ "src": "/src/favicon/icon-192.png", "type": "image/png", "sizes": "192x192" },
|
||||
{ "src": "/src/favicon/icon-512.png", "type": "image/png", "sizes": "512x512" }
|
||||
]
|
||||
"icons": [
|
||||
{ "src": "/src/favicon/icon-192.png", "type": "image/png", "sizes": "192x192" },
|
||||
{ "src": "/src/favicon/icon-512.png", "type": "image/png", "sizes": "512x512" }
|
||||
]
|
||||
}
|
||||
|
1776
package-lock.json
generated
1776
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@ -1,14 +1,14 @@
|
||||
{
|
||||
"name": "commit-webtests",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "commonjs",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^4.1.1"
|
||||
}
|
||||
"name": "commit-webtests",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "commonjs",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^4.1.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,24 @@
|
||||
@media (max-width: 50rem) {
|
||||
body {
|
||||
overflow: visible;
|
||||
}
|
||||
#main_scale,
|
||||
main {
|
||||
position: relative;
|
||||
}
|
||||
header #keyboard_section {
|
||||
bottom: auto;
|
||||
top: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
#mobile {
|
||||
visibility: visible;
|
||||
}
|
||||
#safari,
|
||||
#navigate_description {
|
||||
visibility: hidden;
|
||||
}
|
||||
header nav {
|
||||
position: absolute;
|
||||
}
|
||||
body {
|
||||
overflow: visible;
|
||||
}
|
||||
#main_scale,
|
||||
main {
|
||||
position: relative;
|
||||
}
|
||||
header #keyboard_section {
|
||||
bottom: auto;
|
||||
top: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
#mobile {
|
||||
visibility: visible;
|
||||
}
|
||||
#safari,
|
||||
#navigate_description {
|
||||
visibility: hidden;
|
||||
}
|
||||
header nav {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
@ -6,193 +6,193 @@
|
||||
} */
|
||||
|
||||
button {
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: 0.75rem;
|
||||
font-variation-settings: inherit;
|
||||
line-height: 1rem;
|
||||
width: max-content;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: 0.75rem;
|
||||
font-variation-settings: inherit;
|
||||
line-height: 1rem;
|
||||
width: max-content;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
button:active {
|
||||
background: repeating-conic-gradient(transparent 0% 25%, var(--text) 0% 50%, var(--text) 0% 100%) 50% / 2px 2px;
|
||||
background: repeating-conic-gradient(transparent 0% 25%, var(--text) 0% 50%, var(--text) 0% 100%) 50% / 2px 2px;
|
||||
}
|
||||
|
||||
#app_root.no_focus {
|
||||
opacity: 0.5;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
:focus,
|
||||
input:focus + label {
|
||||
animation: flicker 60ms 2;
|
||||
animation: flicker 60ms 2;
|
||||
}
|
||||
|
||||
[contenteditable="true"]:focus {
|
||||
animation: flicker 200ms 2;
|
||||
animation: flicker 200ms 2;
|
||||
}
|
||||
|
||||
@keyframes flicker {
|
||||
0%,
|
||||
49% {
|
||||
opacity: 0;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
0%,
|
||||
49% {
|
||||
opacity: 0;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flicker_reverse {
|
||||
0%,
|
||||
49% {
|
||||
opacity: 1;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
0%,
|
||||
49% {
|
||||
opacity: 1;
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.top_container p {
|
||||
white-space: pre-wrap;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.line-through {
|
||||
text-decoration: line-through;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
font-weight: normal;
|
||||
width: fit-content;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
font-weight: normal;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
width: max-content;
|
||||
list-style-type: none;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
ol li::before {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul li::before {
|
||||
content: "• ";
|
||||
position: absolute;
|
||||
margin-left: -2ch;
|
||||
content: "• ";
|
||||
position: absolute;
|
||||
margin-left: -2ch;
|
||||
}
|
||||
|
||||
ul li:focus::before {
|
||||
background-color: transparent;
|
||||
color: var(--text);
|
||||
background-color: transparent;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
color: var(--text);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
a:focus {
|
||||
text-decoration: none;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#safari:focus p:first-of-type {
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
#safari {
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
width: max-content;
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
#safari:focus p,
|
||||
#safari:focus ul {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#safari:focus a,
|
||||
#safari a:focus {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#safari:has(*:focus) * {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#safari #safari_not_working:focus {
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
opacity: 1;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#safari #safari_not_working {
|
||||
opacity: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#safari a:focus + #safari_not_working {
|
||||
visibility: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#nav_form input:checked + label::before {
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
}
|
||||
|
||||
#nav_form input:checked + label {
|
||||
color: var(--text);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.span_key.pressed_key {
|
||||
position: relative;
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
position: relative;
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
}
|
||||
|
||||
ul:focus .span_key.pressed_key {
|
||||
background: repeating-conic-gradient(var(--bg) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
background: repeating-conic-gradient(var(--bg) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
}
|
||||
|
||||
.span_key.pressed_key::after {
|
||||
content: " ✓";
|
||||
position: absolute;
|
||||
right: -1ch;
|
||||
top: -0.5rem;
|
||||
content: " ✓";
|
||||
position: absolute;
|
||||
right: -1ch;
|
||||
top: -0.5rem;
|
||||
}
|
||||
|
||||
#page_animation {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
background-color: var(--bg);
|
||||
pointer-events: none;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
background-color: var(--bg);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#page_animation.page_animation {
|
||||
animation: 220ms steps(5, jump-start) forwards page_animation;
|
||||
animation: 220ms steps(5, jump-start) forwards page_animation;
|
||||
}
|
||||
|
||||
@keyframes page_animation {
|
||||
0% {
|
||||
transform: translateY(0vh);
|
||||
}
|
||||
99.9% {
|
||||
visibility: visible;
|
||||
}
|
||||
100% {
|
||||
visibility: hidden;
|
||||
transform: translateY(100vh);
|
||||
}
|
||||
0% {
|
||||
transform: translateY(0vh);
|
||||
}
|
||||
99.9% {
|
||||
visibility: visible;
|
||||
}
|
||||
100% {
|
||||
visibility: hidden;
|
||||
transform: translateY(100vh);
|
||||
}
|
||||
}
|
||||
|
@ -1,88 +1,88 @@
|
||||
#keyboard_container {
|
||||
font-size: 0.75rem;
|
||||
display: flex;
|
||||
width: max-content;
|
||||
gap: 4ch;
|
||||
align-items: end;
|
||||
font-size: 0.75rem;
|
||||
display: flex;
|
||||
width: max-content;
|
||||
gap: 4ch;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.key_group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.keys {
|
||||
font-size: 0.75rem;
|
||||
display: flex;
|
||||
gap: 0.375ch;
|
||||
margin-bottom: 0.125rem;
|
||||
font-size: 0.75rem;
|
||||
display: flex;
|
||||
gap: 0.375ch;
|
||||
margin-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
.key {
|
||||
font-size: 0.75rem;
|
||||
height: 1.2rem;
|
||||
border: 0.0625rem solid var(--text);
|
||||
border-bottom: 0.125rem solid var(--text);
|
||||
display: grid;
|
||||
place-content: center;
|
||||
padding: 0 0.25rem;
|
||||
user-select: none;
|
||||
font-size: 0.75rem;
|
||||
height: 1.2rem;
|
||||
border: 0.0625rem solid var(--text);
|
||||
border-bottom: 0.125rem solid var(--text);
|
||||
display: grid;
|
||||
place-content: center;
|
||||
padding: 0 0.25rem;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.key:hover {
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.key[data-noclick="true"]:hover {
|
||||
cursor: not-allowed;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.key.active_key,
|
||||
.key:active {
|
||||
background: var(--text);
|
||||
color: var(--bg);
|
||||
height: 1.1rem;
|
||||
margin-top: 0.1rem;
|
||||
background: var(--text);
|
||||
color: var(--bg);
|
||||
height: 1.1rem;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
#select_element .key:nth-child(1) {
|
||||
width: 5rem;
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
#escape_textfield .key:nth-child(2) {
|
||||
letter-spacing: -0.1rem;
|
||||
text-indent: -0.1rem;
|
||||
padding: 0.25rem;
|
||||
letter-spacing: -0.1rem;
|
||||
text-indent: -0.1rem;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
#safari p,
|
||||
#safari ul {
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
opacity: 0;
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#safari a {
|
||||
opacity: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#safari p:first-of-type {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#tutorial li {
|
||||
margin-top: 0.3rem;
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
|
||||
.span_key {
|
||||
display: inline;
|
||||
border: 0.0625rem solid var(--text);
|
||||
border-bottom: 0.125rem solid var(--text);
|
||||
padding: 0 calc(0.5ch - 0.0625rem);
|
||||
margin: 0;
|
||||
display: inline;
|
||||
border: 0.0625rem solid var(--text);
|
||||
border-bottom: 0.125rem solid var(--text);
|
||||
padding: 0 calc(0.5ch - 0.0625rem);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul:focus .span_key {
|
||||
border: 0.0625rem solid var(--bg);
|
||||
border-bottom: 0.125rem solid var(--bg);
|
||||
border: 0.0625rem solid var(--bg);
|
||||
border-bottom: 0.125rem solid var(--bg);
|
||||
}
|
||||
|
@ -1,74 +1,74 @@
|
||||
table {
|
||||
margin: 4rem 0 2rem 0;
|
||||
border-collapse: collapse;
|
||||
margin: 4rem 0 2rem 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th > div > p,
|
||||
td > div > p {
|
||||
/* width: 6rem; */
|
||||
font-size: 0.5rem;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
/* width: 6rem; */
|
||||
font-size: 0.5rem;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th > div,
|
||||
td > div {
|
||||
width: 6rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
width: 6rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
tr:first-of-type th > div {
|
||||
width: 6rem;
|
||||
aspect-ratio: 3 / 1;
|
||||
width: 6rem;
|
||||
aspect-ratio: 3 / 1;
|
||||
}
|
||||
|
||||
td > div > input,
|
||||
td > div > label,
|
||||
td > div > p {
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
display: inline-block;
|
||||
margin: auto;
|
||||
white-space: pre;
|
||||
text-align: center;
|
||||
line-height: 1.1;
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
display: inline-block;
|
||||
margin: auto;
|
||||
white-space: pre;
|
||||
text-align: center;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
tr th:first-of-type > div {
|
||||
font-size: 0.5rem;
|
||||
width: 2rem;
|
||||
justify-content: start;
|
||||
font-size: 0.5rem;
|
||||
width: 2rem;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
tr th:first-of-type > div > p {
|
||||
font-size: 0.5rem;
|
||||
text-align: start;
|
||||
font-size: 0.5rem;
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
td > div > label {
|
||||
font-size: 4rem;
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
||||
#section_2 fieldset {
|
||||
border: none;
|
||||
display: block;
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#section_2 input {
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#section_2 input:focus:checked + label {
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
transform: scale(4);
|
||||
z-index: 2;
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
transform: scale(4);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#section_2 input:checked + label::before {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
@ -1,92 +1,92 @@
|
||||
#familiar_form fieldset {
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#familiar_form fieldset::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 0.0625rem;
|
||||
bottom: 0.125rem;
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
background-color: var(--text);
|
||||
content: "";
|
||||
position: absolute;
|
||||
height: 0.0625rem;
|
||||
bottom: 0.125rem;
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#familiar_form fieldset div {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
#familiar_form input[type="radio"] {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
|
||||
color: var(--text);
|
||||
width: 0.375rem;
|
||||
height: 0.375rem;
|
||||
color: var(--text);
|
||||
width: 0.375rem;
|
||||
height: 0.375rem;
|
||||
|
||||
display: grid;
|
||||
place-content: center;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
}
|
||||
|
||||
#familiar_form input[type="radio"]:checked {
|
||||
transform: scale(1.5);
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
#familiar_form input[type="radio"]:focus {
|
||||
transform: scale(2);
|
||||
transform: scale(2);
|
||||
}
|
||||
|
||||
#familiar_form fieldset > div:nth-child(2) {
|
||||
margin-left: 16rem;
|
||||
margin-left: 16rem;
|
||||
}
|
||||
|
||||
#familiar_form fieldset > div:nth-child(3) {
|
||||
margin-left: 15rem;
|
||||
margin-left: 15rem;
|
||||
}
|
||||
|
||||
#familiar_form fieldset > div:nth-child(5) {
|
||||
margin-left: 1rem;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
#familiar_container p {
|
||||
max-width: none;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
figure {
|
||||
width: max-content;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
blockquote,
|
||||
blockquote ~ * {
|
||||
font-size: 0.75rem;
|
||||
padding-left: 2ch;
|
||||
position: relative;
|
||||
border-left: 0.0625rem solid var(--text);
|
||||
max-width: var(--max-width);
|
||||
font-size: 0.75rem;
|
||||
padding-left: 2ch;
|
||||
position: relative;
|
||||
border-left: 0.0625rem solid var(--text);
|
||||
max-width: var(--max-width);
|
||||
}
|
||||
|
||||
blockquote::before {
|
||||
content: "“";
|
||||
left: -0.5ch;
|
||||
top: 0;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
content: "“";
|
||||
left: -0.5ch;
|
||||
top: 0;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
#familiar_container svg {
|
||||
width: 100rem;
|
||||
height: 20rem;
|
||||
width: 100rem;
|
||||
height: 20rem;
|
||||
}
|
||||
|
||||
#familiar_container svg path {
|
||||
fill: var(--text);
|
||||
fill: var(--text);
|
||||
}
|
||||
|
@ -1,122 +1,122 @@
|
||||
#original figure > div,
|
||||
#smart_kerning figure > div {
|
||||
display: flex;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#original p,
|
||||
#smart_kerning p {
|
||||
font-size: 24rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
border-right: 0.0625rem solid var(--text);
|
||||
border-left: 0.0625rem solid var(--text);
|
||||
margin-left: -0.0625rem;
|
||||
font-size: 24rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
border-right: 0.0625rem solid var(--text);
|
||||
border-left: 0.0625rem solid var(--text);
|
||||
margin-left: -0.0625rem;
|
||||
}
|
||||
|
||||
#original p::after,
|
||||
#smart_kerning p::after {
|
||||
font-size: 0.75rem;
|
||||
text-align: center;
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 0.75rem;
|
||||
text-align: center;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#original p:nth-child(1)::after,
|
||||
#smart_kerning p:nth-child(1)::after {
|
||||
content: "Wide letter";
|
||||
content: "Wide letter";
|
||||
}
|
||||
|
||||
#original p:nth-child(2)::after {
|
||||
content: "Smart kerning OFF";
|
||||
content: "Smart kerning OFF";
|
||||
}
|
||||
|
||||
#smart_kerning p:nth-child(2)::after {
|
||||
content: "Smart kerning ON";
|
||||
content: "Smart kerning ON";
|
||||
}
|
||||
|
||||
#original p:nth-child(3)::after,
|
||||
#smart_kerning p:nth-child(3)::after {
|
||||
content: "Narrow letter";
|
||||
content: "Narrow letter";
|
||||
}
|
||||
|
||||
#smart_kerning p:nth-child(2)::before {
|
||||
content: "o";
|
||||
position: absolute;
|
||||
transform: translateX(calc(24rem / 1000 * 40));
|
||||
color: var(--middle);
|
||||
z-index: -1;
|
||||
content: "o";
|
||||
position: absolute;
|
||||
transform: translateX(calc(24rem / 1000 * 40));
|
||||
color: var(--middle);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
#before p,
|
||||
#after p {
|
||||
font-size: 8rem;
|
||||
line-height: 1;
|
||||
max-width: none;
|
||||
white-space: nowrap;
|
||||
font-size: 8rem;
|
||||
line-height: 1;
|
||||
max-width: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#before p {
|
||||
font-feature-settings: "calt" 0;
|
||||
font-feature-settings: "calt" 0;
|
||||
}
|
||||
|
||||
#intelligent_form fieldset {
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
background-color: var(--bg);
|
||||
width: max-content;
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
background-color: var(--bg);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
#intelligent_form > div {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#intelligent_form input {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
|
||||
color: var(--text);
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
color: var(--text);
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#intelligent_form input + label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#intelligent_form input + label::before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
#intelligent_form input:focus:checked + label::before {
|
||||
background-color: var(--text);
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#intelligent_form input:focus:checked + label {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
#intelligent_form input:checked + label::before {
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
}
|
||||
|
||||
#intelligent_form input:checked + label {
|
||||
color: var(--text);
|
||||
color: var(--text);
|
||||
}
|
||||
|
@ -1,71 +1,71 @@
|
||||
#code_form fieldset {
|
||||
font-size: 1.5rem;
|
||||
gap: 1ch;
|
||||
font-size: 1.5rem;
|
||||
gap: 1ch;
|
||||
}
|
||||
|
||||
form fieldset {
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 4ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
background-color: var(--bg);
|
||||
width: max-content;
|
||||
border: none;
|
||||
display: flex;
|
||||
gap: 4ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
background-color: var(--bg);
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
form > div {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
form input {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background-color: var(--text);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
|
||||
color: var(--text);
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
color: var(--text);
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
form input + label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
form input + label::before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
form input:focus:checked + label::before {
|
||||
background-color: var(--text);
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
form input:focus:checked + label {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
form input:checked + label::before {
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
}
|
||||
|
||||
form input:checked + label {
|
||||
color: var(--text);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
#canvas {
|
||||
transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
@ -1,126 +1,126 @@
|
||||
#waterfall {
|
||||
display: flex;
|
||||
width: min-content;
|
||||
gap: 2rem;
|
||||
display: flex;
|
||||
width: min-content;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.waterfall_texts_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
height: 10rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: end;
|
||||
height: 10rem;
|
||||
}
|
||||
|
||||
.waterfall_texts_container > div {
|
||||
height: 2.5rem;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
height: 2.5rem;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.waterfall_text {
|
||||
line-height: 0.6;
|
||||
white-space: pre;
|
||||
line-height: 0.6;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.waterfall_desc {
|
||||
width: max-content;
|
||||
white-space: pre;
|
||||
width: max-content;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.question_container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.75rem;
|
||||
gap: 2ch;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.75rem;
|
||||
gap: 2ch;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.question_character.hide_character {
|
||||
opacity: 1;
|
||||
animation: 0ms 0s 3 forwards flicker_reverse;
|
||||
opacity: 1;
|
||||
animation: 0ms 0s 3 forwards flicker_reverse;
|
||||
}
|
||||
|
||||
.question_character.show_character {
|
||||
opacity: 0;
|
||||
animation: 100ms 0s 3 forwards flicker;
|
||||
opacity: 0;
|
||||
animation: 100ms 0s 3 forwards flicker;
|
||||
}
|
||||
|
||||
.button_container button {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
:root {
|
||||
--question-character-size: 6rem;
|
||||
--question-character-size: 6rem;
|
||||
}
|
||||
|
||||
.question_character {
|
||||
font-size: var(--question-character-size);
|
||||
line-height: var(--question-character-size);
|
||||
border: 0.0625rem solid var(--text);
|
||||
position: relative;
|
||||
font-size: var(--question-character-size);
|
||||
line-height: var(--question-character-size);
|
||||
border: 0.0625rem solid var(--text);
|
||||
position: relative;
|
||||
}
|
||||
.question_character::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 15%;
|
||||
/* height: 0.0625rem; */
|
||||
background-color: var(--text);
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 15%;
|
||||
/* height: 0.0625rem; */
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#score_points {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
#score_points.view_score {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.question_button:focus::before {
|
||||
content: "<-";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
color: var(--text);
|
||||
content: "<-";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
color: var(--text);
|
||||
}
|
||||
.question_button.right_button::before {
|
||||
content: "<-";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
color: var(--text);
|
||||
content: "<-";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
color: var(--text);
|
||||
}
|
||||
.question_button.wrong_button::before {
|
||||
content: "->";
|
||||
position: absolute;
|
||||
left: auto;
|
||||
right: -2ch;
|
||||
color: var(--text);
|
||||
content: "->";
|
||||
position: absolute;
|
||||
left: auto;
|
||||
right: -2ch;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.question_button.button_choice {
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
color: var(--text);
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
color: var(--text);
|
||||
}
|
||||
.question_button.button_choice:focus {
|
||||
background: repeating-conic-gradient(transparent 0% 25%, var(--text) 0% 50%, var(--text) 0% 100%) 50% / 2px 2px;
|
||||
color: var(--bg);
|
||||
background: repeating-conic-gradient(transparent 0% 25%, var(--text) 0% 50%, var(--text) 0% 100%) 50% / 2px 2px;
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
.answer_feedback {
|
||||
position: relative;
|
||||
font-size: 0.75rem;
|
||||
top: calc(var(--question-character-size) * 0.5);
|
||||
top: 40%;
|
||||
width: 0;
|
||||
margin-left: -2ch;
|
||||
left: 0;
|
||||
position: relative;
|
||||
font-size: 0.75rem;
|
||||
top: calc(var(--question-character-size) * 0.5);
|
||||
top: 40%;
|
||||
width: 0;
|
||||
margin-left: -2ch;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.question_container.active_question ~ .question_container.active_question {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.question_container.active_question ~ .question_container {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
@ -1,152 +1,152 @@
|
||||
#section_7 #alternates_container fieldset,
|
||||
#section_7 #features_container fieldset {
|
||||
display: grid;
|
||||
grid-template-columns: 21ch 3ch 3ch;
|
||||
gap: 2ch;
|
||||
display: grid;
|
||||
grid-template-columns: 21ch 3ch 3ch;
|
||||
gap: 2ch;
|
||||
}
|
||||
|
||||
#section_7 #examplesettings_form fieldset p {
|
||||
white-space: pre;
|
||||
font-variant-ligatures: none;
|
||||
white-space: pre;
|
||||
font-variant-ligatures: none;
|
||||
}
|
||||
|
||||
fieldset.alternates > div {
|
||||
width: 4ch;
|
||||
width: 4ch;
|
||||
}
|
||||
|
||||
#section_7 form > div {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#section_7 form input[type="radio"] + label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#section_7 form input[type="radio"] + label::before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
#section_7 form input[type="radio"]:focus:checked + label::before {
|
||||
background-color: var(--text);
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#section_7 form input[type="radio"]:focus:checked + label {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
#section_7 form input[type="radio"]:checked + label::before {
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
background: repeating-conic-gradient(var(--text) 0% 25%, transparent 0% 50%, transparent 0% 100%) 50% / 2px 2px;
|
||||
}
|
||||
|
||||
#section_7 form input[type="radio"]:checked + label {
|
||||
color: var(--text);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
#examples_container {
|
||||
width: fit-content;
|
||||
max-height: 20.6rem;
|
||||
margin-bottom: 0.4rem;
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
width: fit-content;
|
||||
max-height: 20.6rem;
|
||||
margin-bottom: 0.4rem;
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
#examples_container::-webkit-scrollbar {
|
||||
display: none; /* Safari and Chrome */
|
||||
display: none; /* Safari and Chrome */
|
||||
}
|
||||
|
||||
p#code_example {
|
||||
white-space: pre;
|
||||
max-width: none;
|
||||
min-width: 102ch;
|
||||
padding-left: 5ch;
|
||||
position: relative;
|
||||
font-variant-ligatures: none;
|
||||
white-space: pre;
|
||||
max-width: none;
|
||||
min-width: 102ch;
|
||||
padding-left: 5ch;
|
||||
position: relative;
|
||||
font-variant-ligatures: none;
|
||||
}
|
||||
p#code_example::before {
|
||||
content: attr(data-before);
|
||||
position: absolute;
|
||||
white-space: pre;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
content: attr(data-before);
|
||||
position: absolute;
|
||||
white-space: pre;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#section_7 form input[type="checkbox"] {
|
||||
opacity: 1;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
display: inline-block;
|
||||
background-color: transparent;
|
||||
border: 0.0625rem solid var(--text);
|
||||
opacity: 1;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
display: inline-block;
|
||||
background-color: transparent;
|
||||
border: 0.0625rem solid var(--text);
|
||||
}
|
||||
|
||||
#section_7 form input[type="checkbox"]:checked {
|
||||
background-color: var(--text);
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#section_7 form input[type="checkbox"]:focus + label {
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
background-color: var(--text);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
button:focus a {
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
color: var(--bg);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.download_button {
|
||||
display: block;
|
||||
width: max-content;
|
||||
display: block;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.download_button.line-through:focus {
|
||||
text-decoration: line-through;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.download_button.line-through:focus::after {
|
||||
content: "Not possible at the moment.";
|
||||
text-decoration: none;
|
||||
position: absolute;
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
content: "Not possible at the moment.";
|
||||
text-decoration: none;
|
||||
position: absolute;
|
||||
background-color: var(--bg);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.download_button.loading::after {
|
||||
content: ".";
|
||||
position: absolute;
|
||||
color: var(--text);
|
||||
right: -2ch;
|
||||
animation: 800ms 0ms steps(4, jump-none) infinite loading;
|
||||
content: ".";
|
||||
position: absolute;
|
||||
color: var(--text);
|
||||
right: -2ch;
|
||||
animation: 800ms 0ms steps(4, jump-none) infinite loading;
|
||||
}
|
||||
.download_button.loaded::after {
|
||||
content: "✓";
|
||||
position: absolute;
|
||||
color: var(--text);
|
||||
right: -2ch;
|
||||
animation: none;
|
||||
content: "✓";
|
||||
position: absolute;
|
||||
color: var(--text);
|
||||
right: -2ch;
|
||||
animation: none;
|
||||
}
|
||||
.download_button.error::after {
|
||||
content: "✕";
|
||||
position: absolute;
|
||||
color: var(--text);
|
||||
right: -2ch;
|
||||
animation: none;
|
||||
content: "✕";
|
||||
position: absolute;
|
||||
color: var(--text);
|
||||
right: -2ch;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(2ch);
|
||||
}
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(2ch);
|
||||
}
|
||||
}
|
||||
|
@ -1,64 +1,64 @@
|
||||
ol {
|
||||
font-size: 0.75rem;
|
||||
margin-left: 0;
|
||||
width: max-content;
|
||||
font-size: 0.75rem;
|
||||
margin-left: 0;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
ol li {
|
||||
margin-left: 3ch;
|
||||
max-width: calc(var(--max-width) - 3ch);
|
||||
margin-left: 3ch;
|
||||
max-width: calc(var(--max-width) - 3ch);
|
||||
}
|
||||
|
||||
ol li p {
|
||||
max-width: calc(var(--max-width) - 6ch);
|
||||
max-width: calc(var(--max-width) - 6ch);
|
||||
}
|
||||
|
||||
ol:focus li p {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
ol li ul li p {
|
||||
position: relative;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
ol li ul li p::before {
|
||||
content: "•";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
content: "•";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
}
|
||||
|
||||
.accordion_header {
|
||||
margin-left: 2ch;
|
||||
position: relative;
|
||||
max-width: calc(var(--max-width) - 2ch);
|
||||
margin-left: 2ch;
|
||||
position: relative;
|
||||
max-width: calc(var(--max-width) - 2ch);
|
||||
}
|
||||
|
||||
.accordion_header::before {
|
||||
content: "+";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
content: "+";
|
||||
position: absolute;
|
||||
left: -2ch;
|
||||
}
|
||||
|
||||
.accordion_point {
|
||||
margin-left: 2ch;
|
||||
margin-bottom: 1rem;
|
||||
max-width: calc(var(--max-width) - 2ch);
|
||||
margin-left: 2ch;
|
||||
margin-bottom: 1rem;
|
||||
max-width: calc(var(--max-width) - 2ch);
|
||||
}
|
||||
|
||||
ol.accordion_point {
|
||||
margin-top: 0;
|
||||
margin-left: 3ch;
|
||||
margin-top: 0;
|
||||
margin-left: 3ch;
|
||||
}
|
||||
|
||||
.accordion_header + .accordion_point {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.accordion_header:focus:has(+ .accordion_point)::before {
|
||||
content: "-";
|
||||
color: var(--text);
|
||||
content: "-";
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.accordion_header:focus + .accordion_point {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
|
@ -1,163 +1,163 @@
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
:root {
|
||||
--text: #111;
|
||||
--middle: #555;
|
||||
--bg: #aaa;
|
||||
--max-width: 54ch;
|
||||
font-size: 16px;
|
||||
--text: #111;
|
||||
--middle: #555;
|
||||
--bg: #aaa;
|
||||
--max-width: 54ch;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: var(--text);
|
||||
background-color: var(--middle);
|
||||
color: var(--text);
|
||||
background-color: var(--middle);
|
||||
}
|
||||
|
||||
#block_tab_start,
|
||||
#block_tab_end {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
#main_scale {
|
||||
inset: 0;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
main {
|
||||
min-width: 100vw;
|
||||
padding: 4rem 0 0 4ch;
|
||||
min-width: 100vw;
|
||||
padding: 4rem 0 0 4ch;
|
||||
}
|
||||
|
||||
header nav {
|
||||
width: max-content;
|
||||
padding: 1rem 4ch 0 4ch;
|
||||
background-color: var(--bg);
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: max-content;
|
||||
padding: 1rem 4ch 0 4ch;
|
||||
background-color: var(--bg);
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
header #keyboard_section {
|
||||
width: 100%;
|
||||
padding: 0.25rem 0 1rem 4ch;
|
||||
background-color: var(--bg);
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 0.25rem 0 1rem 4ch;
|
||||
background-color: var(--bg);
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#keyboard_section.hidden {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nav_form {
|
||||
display: flex;
|
||||
gap: 4ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
display: flex;
|
||||
gap: 4ch;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
|
||||
#nav_form input {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#nav_form input + label {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#nav_form input + label::before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: var(--bg);
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: var(--bg);
|
||||
}
|
||||
|
||||
#nav_form input:focus:checked + label::before {
|
||||
background-color: var(--text);
|
||||
background-color: var(--text);
|
||||
}
|
||||
|
||||
#nav_form input:focus:checked + label {
|
||||
color: var(--bg);
|
||||
color: var(--bg);
|
||||
}
|
||||
|
||||
#section_container {
|
||||
inset: 1rem 2rem;
|
||||
inset: 1rem 2rem;
|
||||
}
|
||||
|
||||
p,
|
||||
a,
|
||||
figcaption,
|
||||
button {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
max-width: var(--max-width);
|
||||
width: fit-content;
|
||||
vertical-align: top;
|
||||
color: inherit;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
max-width: var(--max-width);
|
||||
width: fit-content;
|
||||
vertical-align: top;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
a,
|
||||
.download_button {
|
||||
text-decoration: underline;
|
||||
text-decoration-skip-ink: none;
|
||||
text-underline-offset: 0.24ch;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
text-decoration-skip-ink: none;
|
||||
text-underline-offset: 0.24ch;
|
||||
cursor: pointer;
|
||||
}
|
||||
a:focus,
|
||||
.download_button:focus {
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
font-weight: normal;
|
||||
width: fit-content;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
font-weight: normal;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#click_focus,
|
||||
#change_setting {
|
||||
inset: 0;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
inset: 0;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#content_root.faded {
|
||||
opacity: 0.33;
|
||||
opacity: 0.33;
|
||||
}
|
||||
|
||||
#mobile {
|
||||
visibility: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
:focus {
|
||||
text-decoration: none;
|
||||
color: var(--bg);
|
||||
background-color: var(--text);
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
color: var(--bg);
|
||||
background-color: var(--text);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
ul li,
|
||||
ol li {
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
margin-left: 2ch;
|
||||
max-width: 54ch;
|
||||
width: fit-content;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
margin-left: 2ch;
|
||||
max-width: 54ch;
|
||||
width: fit-content;
|
||||
}
|
||||
|
@ -2,332 +2,332 @@ const codeForm = document.querySelector("#code_form")
|
||||
const codeFieldset = document.querySelector("#code_form fieldset")
|
||||
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "code") {
|
||||
section.content.characters.forEach((character, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "code"
|
||||
input.id = character.name
|
||||
input.classList.add("code_character")
|
||||
input.value = character.name
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = character.value
|
||||
label.setAttribute("for", character.name)
|
||||
div.append(input, label)
|
||||
codeFieldset.append(div)
|
||||
})
|
||||
}
|
||||
if (section.name == "code") {
|
||||
section.content.characters.forEach((character, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "code"
|
||||
input.id = character.name
|
||||
input.classList.add("code_character")
|
||||
input.value = character.name
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = character.value
|
||||
label.setAttribute("for", character.name)
|
||||
div.append(input, label)
|
||||
codeFieldset.append(div)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
function updateCode(event, form) {
|
||||
console.log("update code")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
console.log("update code")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
|
||||
let displayCharacter = ""
|
||||
let displayName = ""
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "code") {
|
||||
section.content.characters.forEach((character, index) => {
|
||||
if (character.name == output) {
|
||||
displayCharacter = character.value
|
||||
displayName = character.name
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
let displayCharacter = ""
|
||||
let displayName = ""
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "code") {
|
||||
section.content.characters.forEach((character, index) => {
|
||||
if (character.name == output) {
|
||||
displayCharacter = character.value
|
||||
displayName = character.name
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
let selectedGlyphData
|
||||
if (commitMonoFont) {
|
||||
Object.values(commitMonoFont.glyphs.glyphs).forEach((glyph) => {
|
||||
if (glyph.name == output) selectedGlyphData = glyph
|
||||
})
|
||||
updateCanvas(selectedGlyphData, commitMonoFont, displayCharacter, displayName)
|
||||
}
|
||||
let selectedGlyphData
|
||||
if (commitMonoFont) {
|
||||
Object.values(commitMonoFont.glyphs.glyphs).forEach((glyph) => {
|
||||
if (glyph.name == output) selectedGlyphData = glyph
|
||||
})
|
||||
updateCanvas(selectedGlyphData, commitMonoFont, displayCharacter, displayName)
|
||||
}
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
const canvasScale = 16
|
||||
|
||||
const drawFontLine = (GLYPH_SCALE, ctx, upem, width, name, value, yOffset) => {
|
||||
let scaledValue = mapRange(value, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue = width - scaledValue + (yOffset * GLYPH_SCALE * width) / upem
|
||||
let scaledValue = mapRange(value, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue = width - scaledValue + (yOffset * GLYPH_SCALE * width) / upem
|
||||
|
||||
ctx.strokeStyle = getCssVar("--text")
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(7 * canvasScale, scaledValue)
|
||||
ctx.lineTo(width - 7 * canvasScale, scaledValue)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
ctx.strokeStyle = getCssVar("--text")
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(7 * canvasScale, scaledValue)
|
||||
ctx.lineTo(width - 7 * canvasScale, scaledValue)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
|
||||
ctx.fillStyle = getCssVar("--text")
|
||||
ctx.font = `${0.75 * canvasScale}px "Commit Mono"`
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillText(name, 0, scaledValue + 0.25 * canvasScale)
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillText(value, width - 4 * canvasScale, scaledValue + 0.25 * canvasScale)
|
||||
ctx.fillStyle = getCssVar("--text")
|
||||
ctx.font = `${0.75 * canvasScale}px "Commit Mono"`
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillText(name, 0, scaledValue + 0.25 * canvasScale)
|
||||
ctx.textAlign = "left"
|
||||
ctx.fillText(value, width - 4 * canvasScale, scaledValue + 0.25 * canvasScale)
|
||||
}
|
||||
|
||||
const drawFontLineVertical = (GLYPH_SCALE, ctx, upem, width, value, yOffset, ascender, descender) => {
|
||||
let scaledValue1 = mapRange(ascender, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue1 = width - scaledValue1 + (yOffset * GLYPH_SCALE * width) / upem
|
||||
let scaledValue2 = mapRange(descender, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue2 = width - scaledValue2 + (yOffset * GLYPH_SCALE * width) / upem
|
||||
let scaledValue1 = mapRange(ascender, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue1 = width - scaledValue1 + (yOffset * GLYPH_SCALE * width) / upem
|
||||
let scaledValue2 = mapRange(descender, 0, upem, 0, width * GLYPH_SCALE)
|
||||
scaledValue2 = width - scaledValue2 + (yOffset * GLYPH_SCALE * width) / upem
|
||||
|
||||
ctx.strokeStyle = getCssVar("--text")
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(value, scaledValue1)
|
||||
ctx.lineTo(value, scaledValue2)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
ctx.strokeStyle = getCssVar("--text")
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(value, scaledValue1)
|
||||
ctx.lineTo(value, scaledValue2)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
function updateCanvas(selectedGlyphData, selectedFont, displayCharacter, displayName) {
|
||||
// initialize canvas
|
||||
let CANVAS_SCALE = window.devicePixelRatio
|
||||
const canvas = document.querySelector("#canvas")
|
||||
let canvasWidth = 60 * canvasScale
|
||||
let canvasHeight = 42 * canvasScale
|
||||
canvas.style.width = `${canvasWidth}px`
|
||||
canvas.style.height = `${canvasHeight}px`
|
||||
canvas.width = canvasWidth * CANVAS_SCALE
|
||||
canvas.height = canvasHeight * CANVAS_SCALE
|
||||
const ctx = canvas.getContext("2d")
|
||||
ctx.scale(CANVAS_SCALE, CANVAS_SCALE)
|
||||
// initialize canvas
|
||||
let CANVAS_SCALE = window.devicePixelRatio
|
||||
const canvas = document.querySelector("#canvas")
|
||||
let canvasWidth = 60 * canvasScale
|
||||
let canvasHeight = 42 * canvasScale
|
||||
canvas.style.width = `${canvasWidth}px`
|
||||
canvas.style.height = `${canvasHeight}px`
|
||||
canvas.width = canvasWidth * CANVAS_SCALE
|
||||
canvas.height = canvasHeight * CANVAS_SCALE
|
||||
const ctx = canvas.getContext("2d")
|
||||
ctx.scale(CANVAS_SCALE, CANVAS_SCALE)
|
||||
|
||||
let GLYPH_SCALE = 0.6
|
||||
ctx.clearRect(0, 0, canvasWidth, canvasHeight)
|
||||
let GLYPH_SCALE = 0.6
|
||||
ctx.clearRect(0, 0, canvasWidth, canvasHeight)
|
||||
|
||||
if (selectedGlyphData.path) {
|
||||
const CANVAS_GLYPH_COMPOSITION_FILL = [
|
||||
{
|
||||
type: "outline",
|
||||
fill: true,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
]
|
||||
const CANVAS_GLYPH_COMPOSITION_BEZIER = [
|
||||
// {
|
||||
// type: "outline",
|
||||
// fill: true,
|
||||
// color: "rgba(0, 0, 0, 0.1)",
|
||||
// pointSize: undefined,
|
||||
// },
|
||||
{
|
||||
type: "handles",
|
||||
fill: false,
|
||||
color: getCssVar("--middle"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
{
|
||||
type: "outline",
|
||||
fill: false,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
{
|
||||
type: "points",
|
||||
fill: true,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: 10, // size of point on bezier glyph
|
||||
},
|
||||
{
|
||||
type: "handle points",
|
||||
fill: true,
|
||||
color: getCssVar("--middle"),
|
||||
pointSize: 10, // size of handles on bezier glyph
|
||||
},
|
||||
]
|
||||
if (selectedGlyphData.path) {
|
||||
const CANVAS_GLYPH_COMPOSITION_FILL = [
|
||||
{
|
||||
type: "outline",
|
||||
fill: true,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
]
|
||||
const CANVAS_GLYPH_COMPOSITION_BEZIER = [
|
||||
// {
|
||||
// type: "outline",
|
||||
// fill: true,
|
||||
// color: "rgba(0, 0, 0, 0.1)",
|
||||
// pointSize: undefined,
|
||||
// },
|
||||
{
|
||||
type: "handles",
|
||||
fill: false,
|
||||
color: getCssVar("--middle"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
{
|
||||
type: "outline",
|
||||
fill: false,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: undefined,
|
||||
},
|
||||
{
|
||||
type: "points",
|
||||
fill: true,
|
||||
color: getCssVar("--text"),
|
||||
pointSize: 10, // size of point on bezier glyph
|
||||
},
|
||||
{
|
||||
type: "handle points",
|
||||
fill: true,
|
||||
color: getCssVar("--middle"),
|
||||
pointSize: 10, // size of handles on bezier glyph
|
||||
},
|
||||
]
|
||||
|
||||
const upem = selectedFont?.unitsPerEm || 1000
|
||||
const width = 60 * canvasScale
|
||||
const upem = selectedFont?.unitsPerEm || 1000
|
||||
const width = 60 * canvasScale
|
||||
|
||||
const yOffset = -45 * canvasScale
|
||||
const xOffset = 20 * canvasScale
|
||||
const ascender = selectedFont?.tables.os2?.sTypoAscender || 750
|
||||
const capHeight = selectedFont?.tables.os2?.sCapHeight || 700
|
||||
const xHeight = selectedFont?.tables.os2?.sxHeight
|
||||
const baseline = 0
|
||||
const descender = selectedFont?.tables.os2?.sTypoDescender || -200
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Ascender", ascender, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Cap Height", capHeight, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "X-height", xHeight || 500, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Baseline", baseline, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Descender", descender, yOffset)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 7 * canvasScale, yOffset, ascender, descender)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 30 * canvasScale, yOffset, ascender, descender)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 53 * canvasScale, yOffset, ascender, descender)
|
||||
const yOffset = -45 * canvasScale
|
||||
const xOffset = 20 * canvasScale
|
||||
const ascender = selectedFont?.tables.os2?.sTypoAscender || 750
|
||||
const capHeight = selectedFont?.tables.os2?.sCapHeight || 700
|
||||
const xHeight = selectedFont?.tables.os2?.sxHeight
|
||||
const baseline = 0
|
||||
const descender = selectedFont?.tables.os2?.sTypoDescender || -200
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Ascender", ascender, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Cap Height", capHeight, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "X-height", xHeight || 500, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Baseline", baseline, yOffset)
|
||||
drawFontLine(GLYPH_SCALE, ctx, upem, width, "Descender", descender, yOffset)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 7 * canvasScale, yOffset, ascender, descender)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 30 * canvasScale, yOffset, ascender, descender)
|
||||
drawFontLineVertical(GLYPH_SCALE, ctx, upem, width, 53 * canvasScale, yOffset, ascender, descender)
|
||||
|
||||
ctx.fillStyle = getCssVar("--text")
|
||||
ctx.font = `${0.75 * canvasScale}px "Commit Mono"`
|
||||
ctx.textAlign = "center"
|
||||
ctx.fillText(displayName, (30 - 11.5) * canvasScale, 2.75 * canvasScale)
|
||||
ctx.fillText(displayName, (30 + 11.5) * canvasScale, 2.75 * canvasScale)
|
||||
ctx.fillStyle = getCssVar("--text")
|
||||
ctx.font = `${0.75 * canvasScale}px "Commit Mono"`
|
||||
ctx.textAlign = "center"
|
||||
ctx.fillText(displayName, (30 - 11.5) * canvasScale, 2.75 * canvasScale)
|
||||
ctx.fillText(displayName, (30 + 11.5) * canvasScale, 2.75 * canvasScale)
|
||||
|
||||
// make ready transformation matrixes for manipulating paths
|
||||
let firstMatrix = new DOMMatrix()
|
||||
firstMatrix = firstMatrix.scaleSelf(width / upem)
|
||||
let secondMatrix = new DOMMatrix()
|
||||
secondMatrix = secondMatrix.scaleSelf(GLYPH_SCALE)
|
||||
secondMatrix = secondMatrix.translateSelf(-width * 0.5, -width) // translate to left edge, top
|
||||
secondMatrix = secondMatrix.translateSelf((width * 0.5) / GLYPH_SCALE, width / GLYPH_SCALE) // translate to center, baseline
|
||||
secondMatrix = secondMatrix.translateSelf(0, (yOffset * width) / upem) // translate yOffset
|
||||
secondMatrix = secondMatrix.translateSelf((xOffset * width) / upem, 0) // translate xOffset
|
||||
// make ready transformation matrixes for manipulating paths
|
||||
let firstMatrix = new DOMMatrix()
|
||||
firstMatrix = firstMatrix.scaleSelf(width / upem)
|
||||
let secondMatrix = new DOMMatrix()
|
||||
secondMatrix = secondMatrix.scaleSelf(GLYPH_SCALE)
|
||||
secondMatrix = secondMatrix.translateSelf(-width * 0.5, -width) // translate to left edge, top
|
||||
secondMatrix = secondMatrix.translateSelf((width * 0.5) / GLYPH_SCALE, width / GLYPH_SCALE) // translate to center, baseline
|
||||
secondMatrix = secondMatrix.translateSelf(0, (yOffset * width) / upem) // translate yOffset
|
||||
secondMatrix = secondMatrix.translateSelf((xOffset * width) / upem, 0) // translate xOffset
|
||||
|
||||
// set initial value for glyph composition based on if bezier is switched on or off
|
||||
// let canvasGlyphComposition = bezier ? CANVAS_GLYPH_COMPOSITION_BEZIER : CANVAS_GLYPH_COMPOSITION_FILL
|
||||
// set initial value for glyph composition based on if bezier is switched on or off
|
||||
// let canvasGlyphComposition = bezier ? CANVAS_GLYPH_COMPOSITION_BEZIER : CANVAS_GLYPH_COMPOSITION_FILL
|
||||
|
||||
CANVAS_GLYPH_COMPOSITION_BEZIER.forEach((composite) => {
|
||||
const calcPointsize = composite.pointSize * (upem / 1000)
|
||||
const firstPath2d = glyphBezier(selectedGlyphData, upem, composite.type, calcPointsize)
|
||||
const secondPath2d = new Path2D()
|
||||
secondPath2d.addPath(firstPath2d, firstMatrix)
|
||||
const finalPath2d = new Path2D()
|
||||
finalPath2d.addPath(secondPath2d, secondMatrix)
|
||||
CANVAS_GLYPH_COMPOSITION_BEZIER.forEach((composite) => {
|
||||
const calcPointsize = composite.pointSize * (upem / 1000)
|
||||
const firstPath2d = glyphBezier(selectedGlyphData, upem, composite.type, calcPointsize)
|
||||
const secondPath2d = new Path2D()
|
||||
secondPath2d.addPath(firstPath2d, firstMatrix)
|
||||
const finalPath2d = new Path2D()
|
||||
finalPath2d.addPath(secondPath2d, secondMatrix)
|
||||
|
||||
if (composite.fill) {
|
||||
ctx.fillStyle = composite.color
|
||||
ctx.fill(finalPath2d)
|
||||
} else {
|
||||
ctx.strokeStyle = composite.color
|
||||
ctx.stroke(finalPath2d)
|
||||
}
|
||||
})
|
||||
CANVAS_GLYPH_COMPOSITION_FILL.forEach((composite) => {
|
||||
secondMatrix = secondMatrix.translateSelf((-2 * xOffset * width) / upem, 0) // translate xOffset
|
||||
if (composite.fill) {
|
||||
ctx.fillStyle = composite.color
|
||||
ctx.fill(finalPath2d)
|
||||
} else {
|
||||
ctx.strokeStyle = composite.color
|
||||
ctx.stroke(finalPath2d)
|
||||
}
|
||||
})
|
||||
CANVAS_GLYPH_COMPOSITION_FILL.forEach((composite) => {
|
||||
secondMatrix = secondMatrix.translateSelf((-2 * xOffset * width) / upem, 0) // translate xOffset
|
||||
|
||||
const calcPointsize = composite.pointSize * (upem / 1000)
|
||||
const firstPath2d = glyphBezier(selectedGlyphData, upem, composite.type, calcPointsize)
|
||||
const secondPath2d = new Path2D()
|
||||
secondPath2d.addPath(firstPath2d, firstMatrix)
|
||||
const finalPath2d = new Path2D()
|
||||
finalPath2d.addPath(secondPath2d, secondMatrix)
|
||||
const calcPointsize = composite.pointSize * (upem / 1000)
|
||||
const firstPath2d = glyphBezier(selectedGlyphData, upem, composite.type, calcPointsize)
|
||||
const secondPath2d = new Path2D()
|
||||
secondPath2d.addPath(firstPath2d, firstMatrix)
|
||||
const finalPath2d = new Path2D()
|
||||
finalPath2d.addPath(secondPath2d, secondMatrix)
|
||||
|
||||
if (composite.fill) {
|
||||
ctx.fillStyle = composite.color
|
||||
ctx.fill(finalPath2d)
|
||||
} else {
|
||||
ctx.strokeStyle = composite.color
|
||||
ctx.stroke(finalPath2d)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (composite.fill) {
|
||||
ctx.fillStyle = composite.color
|
||||
ctx.fill(finalPath2d)
|
||||
} else {
|
||||
ctx.strokeStyle = composite.color
|
||||
ctx.stroke(finalPath2d)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function glyphBezier(glyph, upem, typeOfOutline, pointSize) {
|
||||
let ps = pointSize
|
||||
let offsetX = (upem - glyph.advanceWidth) * 0.5
|
||||
let path2d = new Path2D()
|
||||
let ps = pointSize
|
||||
let offsetX = (upem - glyph.advanceWidth) * 0.5
|
||||
let path2d = new Path2D()
|
||||
|
||||
if (typeOfOutline == "outline") {
|
||||
let commandString = ""
|
||||
glyph.path.commands.forEach((command) => {
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "L":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "C":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x1 + offsetX} ${upem - command.y1}, `
|
||||
commandString += `${command.x2 + offsetX} ${upem - command.y2}, `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "Q":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x1 + offsetX} ${upem - command.y1}, `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "Z":
|
||||
commandString += `${command.type} `
|
||||
break
|
||||
}
|
||||
})
|
||||
path2d.addPath(new Path2D(commandString))
|
||||
}
|
||||
if (typeOfOutline == "outline") {
|
||||
let commandString = ""
|
||||
glyph.path.commands.forEach((command) => {
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "L":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "C":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x1 + offsetX} ${upem - command.y1}, `
|
||||
commandString += `${command.x2 + offsetX} ${upem - command.y2}, `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "Q":
|
||||
commandString += `${command.type} `
|
||||
commandString += `${command.x1 + offsetX} ${upem - command.y1}, `
|
||||
commandString += `${command.x + offsetX} ${upem - command.y} `
|
||||
break
|
||||
case "Z":
|
||||
commandString += `${command.type} `
|
||||
break
|
||||
}
|
||||
})
|
||||
path2d.addPath(new Path2D(commandString))
|
||||
}
|
||||
|
||||
if (typeOfOutline == "points") {
|
||||
glyph.path.commands.forEach((command) => {
|
||||
let p = new Path2D()
|
||||
const x = command.x + offsetX
|
||||
const y = upem - command.y
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "L":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "C":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "Q":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
}
|
||||
path2d.addPath(p)
|
||||
})
|
||||
}
|
||||
if (typeOfOutline == "points") {
|
||||
glyph.path.commands.forEach((command) => {
|
||||
let p = new Path2D()
|
||||
const x = command.x + offsetX
|
||||
const y = upem - command.y
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "L":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "C":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "Q":
|
||||
p.rect(x - ps * 0.5, y - ps * 0.5, ps, ps)
|
||||
break
|
||||
}
|
||||
path2d.addPath(p)
|
||||
})
|
||||
}
|
||||
|
||||
if (typeOfOutline == "handles") {
|
||||
let p = new Path2D()
|
||||
glyph.path.commands.forEach((command) => {
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "L":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "C":
|
||||
p.lineTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
p.lineTo(command.x2 + offsetX, upem - command.y2)
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "Q":
|
||||
p.lineTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.moveTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.lineTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "Z":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
}
|
||||
})
|
||||
path2d.addPath(p)
|
||||
}
|
||||
if (typeOfOutline == "handles") {
|
||||
let p = new Path2D()
|
||||
glyph.path.commands.forEach((command) => {
|
||||
switch (command.type) {
|
||||
case "M":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "L":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "C":
|
||||
p.lineTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
p.lineTo(command.x2 + offsetX, upem - command.y2)
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "Q":
|
||||
p.lineTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.moveTo(command.x1 + offsetX, upem - command.y1)
|
||||
p.lineTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
case "Z":
|
||||
p.moveTo(command.x + offsetX, upem - command.y)
|
||||
break
|
||||
}
|
||||
})
|
||||
path2d.addPath(p)
|
||||
}
|
||||
|
||||
if (typeOfOutline == "handle points") {
|
||||
glyph.path.commands.forEach((command) => {
|
||||
let p = new Path2D()
|
||||
const x1 = command.x1 + offsetX
|
||||
const x2 = command.x2 + offsetX
|
||||
const y1 = upem - command.y1
|
||||
const y2 = upem - command.y2
|
||||
switch (command.type) {
|
||||
case "C":
|
||||
p.rect(x1 - ps * 0.5, y1 - ps * 0.5, ps, ps)
|
||||
p.rect(x2 - ps * 0.5, y2 - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "Q":
|
||||
p.rect(x1 - ps * 0.5, y1 - ps * 0.5, ps, ps)
|
||||
break
|
||||
}
|
||||
path2d.addPath(p)
|
||||
})
|
||||
}
|
||||
if (typeOfOutline == "handle points") {
|
||||
glyph.path.commands.forEach((command) => {
|
||||
let p = new Path2D()
|
||||
const x1 = command.x1 + offsetX
|
||||
const x2 = command.x2 + offsetX
|
||||
const y1 = upem - command.y1
|
||||
const y2 = upem - command.y2
|
||||
switch (command.type) {
|
||||
case "C":
|
||||
p.rect(x1 - ps * 0.5, y1 - ps * 0.5, ps, ps)
|
||||
p.rect(x2 - ps * 0.5, y2 - ps * 0.5, ps, ps)
|
||||
break
|
||||
case "Q":
|
||||
p.rect(x1 - ps * 0.5, y1 - ps * 0.5, ps, ps)
|
||||
break
|
||||
}
|
||||
path2d.addPath(p)
|
||||
})
|
||||
}
|
||||
|
||||
return path2d
|
||||
return path2d
|
||||
}
|
||||
|
@ -1,37 +1,37 @@
|
||||
let waterfall, gtc
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
waterfall = section.content.waterfall
|
||||
gtc = section.content.gtc
|
||||
}
|
||||
if (section.name == "distinction") {
|
||||
waterfall = section.content.waterfall
|
||||
gtc = section.content.gtc
|
||||
}
|
||||
})
|
||||
|
||||
function updateWaterfall() {
|
||||
const waterfallContainer = document.querySelector("#waterfall")
|
||||
waterfallContainer.innerHTML = ""
|
||||
waterfall.sizes.forEach((size) => {
|
||||
const div = document.createElement("div")
|
||||
div.id = `size_${size}`
|
||||
const waterfallContainer = document.querySelector("#waterfall")
|
||||
waterfallContainer.innerHTML = ""
|
||||
waterfall.sizes.forEach((size) => {
|
||||
const div = document.createElement("div")
|
||||
div.id = `size_${size}`
|
||||
|
||||
const desc = document.createElement("p")
|
||||
desc.classList.add("waterfall_desc")
|
||||
desc.textContent = `${size}rem\n${size * rem}px`
|
||||
const desc = document.createElement("p")
|
||||
desc.classList.add("waterfall_desc")
|
||||
desc.textContent = `${size}rem\n${size * rem}px`
|
||||
|
||||
const textsContainer = document.createElement("div")
|
||||
textsContainer.classList.add("waterfall_texts_container")
|
||||
waterfall.texts.forEach((text) => {
|
||||
const div2 = document.createElement("div")
|
||||
const p = document.createElement("p")
|
||||
p.classList.add("waterfall_text")
|
||||
p.style.fontSize = `${size * rem}px`
|
||||
p.textContent = text
|
||||
div2.append(p)
|
||||
textsContainer.append(div2)
|
||||
})
|
||||
div.append(desc, textsContainer)
|
||||
const textsContainer = document.createElement("div")
|
||||
textsContainer.classList.add("waterfall_texts_container")
|
||||
waterfall.texts.forEach((text) => {
|
||||
const div2 = document.createElement("div")
|
||||
const p = document.createElement("p")
|
||||
p.classList.add("waterfall_text")
|
||||
p.style.fontSize = `${size * rem}px`
|
||||
p.textContent = text
|
||||
div2.append(p)
|
||||
textsContainer.append(div2)
|
||||
})
|
||||
div.append(desc, textsContainer)
|
||||
|
||||
waterfallContainer.append(div)
|
||||
})
|
||||
waterfallContainer.append(div)
|
||||
})
|
||||
}
|
||||
|
||||
updateWaterfall()
|
||||
@ -40,42 +40,42 @@ const gtcForm = document.querySelector("#gtc_form")
|
||||
const gtcFieldset = document.querySelector("#gtc_form fieldset")
|
||||
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
section.content.gtcDifficulties.forEach((difficulty, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "difficulty"
|
||||
input.id = `difficulty_${difficulty.name}`
|
||||
input.classList.add("gtc_difficulty")
|
||||
input.value = difficulty.name
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = difficulty.name
|
||||
label.setAttribute("for", `difficulty_${difficulty.name}`)
|
||||
div.append(input, label)
|
||||
gtcFieldset.append(div)
|
||||
})
|
||||
}
|
||||
if (section.name == "distinction") {
|
||||
section.content.gtcDifficulties.forEach((difficulty, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "difficulty"
|
||||
input.id = `difficulty_${difficulty.name}`
|
||||
input.classList.add("gtc_difficulty")
|
||||
input.value = difficulty.name
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = difficulty.name
|
||||
label.setAttribute("for", `difficulty_${difficulty.name}`)
|
||||
div.append(input, label)
|
||||
gtcFieldset.append(div)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
function updateGTC(event, form) {
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
section.content.gtcDifficulties.forEach((difficulty) => {
|
||||
if (difficulty.name == output) {
|
||||
setCssVar(["--question-character-size", `${difficulty.size}rem`])
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "distinction") {
|
||||
section.content.gtcDifficulties.forEach((difficulty) => {
|
||||
if (difficulty.name == output) {
|
||||
setCssVar(["--question-character-size", `${difficulty.size}rem`])
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
let answers = []
|
||||
@ -83,103 +83,103 @@ let score = -1
|
||||
let currentQuestion = -1
|
||||
let firstButtons = []
|
||||
function createGTC() {
|
||||
const gtcContainer = document.querySelector("#gtc_questions_container")
|
||||
gtcContainer.innerHTML = ""
|
||||
answers = []
|
||||
firstButtons = []
|
||||
gtc.forEach((question, index) => {
|
||||
const div = document.createElement("div")
|
||||
div.classList.add("question_container")
|
||||
div.dataset.index = index
|
||||
const gtcContainer = document.querySelector("#gtc_questions_container")
|
||||
gtcContainer.innerHTML = ""
|
||||
answers = []
|
||||
firstButtons = []
|
||||
gtc.forEach((question, index) => {
|
||||
const div = document.createElement("div")
|
||||
div.classList.add("question_container")
|
||||
div.dataset.index = index
|
||||
|
||||
const answer = Math.round(Math.random())
|
||||
const wrongAnswer = (answer + 1) % 2
|
||||
answers.push(answer)
|
||||
const answer = Math.round(Math.random())
|
||||
const wrongAnswer = (answer + 1) % 2
|
||||
answers.push(answer)
|
||||
|
||||
const p = document.createElement("p")
|
||||
p.classList.add("question_character")
|
||||
p.textContent = question.value[answer]
|
||||
const pWrong = document.createElement("p")
|
||||
pWrong.classList.add("question_character", "wrong_character", "hide_character")
|
||||
pWrong.textContent = question.value[wrongAnswer]
|
||||
const buttonContainer = document.createElement("div")
|
||||
buttonContainer.classList.add("button_container")
|
||||
const option0 = document.createElement("button")
|
||||
option0.classList.add("question_button")
|
||||
option0.textContent = question.options[0]
|
||||
option0.dataset.questionIndex = index
|
||||
option0.tabIndex = -1
|
||||
firstButtons.push(option0)
|
||||
const option1 = document.createElement("button")
|
||||
option1.classList.add("question_button")
|
||||
option1.textContent = question.options[1]
|
||||
option1.dataset.questionIndex = index
|
||||
option1.tabIndex = -1
|
||||
const p = document.createElement("p")
|
||||
p.classList.add("question_character")
|
||||
p.textContent = question.value[answer]
|
||||
const pWrong = document.createElement("p")
|
||||
pWrong.classList.add("question_character", "wrong_character", "hide_character")
|
||||
pWrong.textContent = question.value[wrongAnswer]
|
||||
const buttonContainer = document.createElement("div")
|
||||
buttonContainer.classList.add("button_container")
|
||||
const option0 = document.createElement("button")
|
||||
option0.classList.add("question_button")
|
||||
option0.textContent = question.options[0]
|
||||
option0.dataset.questionIndex = index
|
||||
option0.tabIndex = -1
|
||||
firstButtons.push(option0)
|
||||
const option1 = document.createElement("button")
|
||||
option1.classList.add("question_button")
|
||||
option1.textContent = question.options[1]
|
||||
option1.dataset.questionIndex = index
|
||||
option1.tabIndex = -1
|
||||
|
||||
const options = [option0, option1]
|
||||
options[answer].addEventListener("click", () => nextQuestion(true, answer, wrongAnswer))
|
||||
options[wrongAnswer].addEventListener("click", () => nextQuestion(false, answer, wrongAnswer))
|
||||
const options = [option0, option1]
|
||||
options[answer].addEventListener("click", () => nextQuestion(true, answer, wrongAnswer))
|
||||
options[wrongAnswer].addEventListener("click", () => nextQuestion(false, answer, wrongAnswer))
|
||||
|
||||
const answerFeedback = document.createElement("p")
|
||||
answerFeedback.classList.add("answer_feedback")
|
||||
const answerFeedback = document.createElement("p")
|
||||
answerFeedback.classList.add("answer_feedback")
|
||||
|
||||
buttonContainer.append(option0, option1)
|
||||
const br = document.createElement("br")
|
||||
div.append(answerFeedback, p, buttonContainer, pWrong)
|
||||
gtcContainer.append(br, div)
|
||||
})
|
||||
const scorePoints = document.createElement("p")
|
||||
scorePoints.id = "score_points"
|
||||
scorePoints.textContent = `You scored ${score} out of ${gtc.length}`
|
||||
gtcContainer.append(scorePoints)
|
||||
nextQuestion(true, 0, 1)
|
||||
buttonContainer.append(option0, option1)
|
||||
const br = document.createElement("br")
|
||||
div.append(answerFeedback, p, buttonContainer, pWrong)
|
||||
gtcContainer.append(br, div)
|
||||
})
|
||||
const scorePoints = document.createElement("p")
|
||||
scorePoints.id = "score_points"
|
||||
scorePoints.textContent = `You scored ${score} out of ${gtc.length}`
|
||||
gtcContainer.append(scorePoints)
|
||||
nextQuestion(true, 0, 1)
|
||||
}
|
||||
|
||||
function nextQuestion(correct, answer, wrongAnswer) {
|
||||
const scoreTally = document.querySelector("#score_tally")
|
||||
const allQuestions = document.querySelectorAll(".question_container")
|
||||
let answerFeedback
|
||||
const scoreTally = document.querySelector("#score_tally")
|
||||
const allQuestions = document.querySelectorAll(".question_container")
|
||||
let answerFeedback
|
||||
|
||||
if (correct) score++
|
||||
if (correct) score++
|
||||
|
||||
allQuestions.forEach((question, index) => {
|
||||
const wrongCharacter = question.querySelector(".wrong_character")
|
||||
allQuestions.forEach((question, index) => {
|
||||
const wrongCharacter = question.querySelector(".wrong_character")
|
||||
|
||||
if (index == currentQuestion) {
|
||||
question.classList.add("active_question")
|
||||
const rightButton = question.querySelector(`.button_container .question_button:nth-child(${answer + 1})`)
|
||||
const wrongButton = question.querySelector(`.button_container .question_button:nth-child(${wrongAnswer + 1})`)
|
||||
correct ? rightButton.classList.add("button_choice") : wrongButton.classList.add("button_choice")
|
||||
rightButton.classList.add("right_button")
|
||||
wrongButton.classList.add("wrong_button")
|
||||
if (index == currentQuestion) {
|
||||
question.classList.add("active_question")
|
||||
const rightButton = question.querySelector(`.button_container .question_button:nth-child(${answer + 1})`)
|
||||
const wrongButton = question.querySelector(`.button_container .question_button:nth-child(${wrongAnswer + 1})`)
|
||||
correct ? rightButton.classList.add("button_choice") : wrongButton.classList.add("button_choice")
|
||||
rightButton.classList.add("right_button")
|
||||
wrongButton.classList.add("wrong_button")
|
||||
|
||||
answerFeedback = question.querySelector(".answer_feedback")
|
||||
answerFeedback.textContent = correct ? "✓" : "✕"
|
||||
answerFeedback = question.querySelector(".answer_feedback")
|
||||
answerFeedback.textContent = correct ? "✓" : "✕"
|
||||
|
||||
wrongCharacter.classList.remove("hide_character")
|
||||
wrongCharacter.classList.add("show_character")
|
||||
} else if (index == currentQuestion + 1) {
|
||||
question.classList.add("active_question")
|
||||
} else {
|
||||
question.classList.remove("active_question")
|
||||
}
|
||||
})
|
||||
wrongCharacter.classList.remove("hide_character")
|
||||
wrongCharacter.classList.add("show_character")
|
||||
} else if (index == currentQuestion + 1) {
|
||||
question.classList.add("active_question")
|
||||
} else {
|
||||
question.classList.remove("active_question")
|
||||
}
|
||||
})
|
||||
|
||||
currentQuestion++
|
||||
currentQuestion++
|
||||
|
||||
allQuestions.forEach((question, index) => {
|
||||
if (index == currentQuestion) {
|
||||
question.querySelectorAll(".question_button").forEach((button) => (button.tabIndex = 0))
|
||||
}
|
||||
})
|
||||
scoreTally.textContent = `Score: ${score}/${gtc.length}`
|
||||
allQuestions.forEach((question, index) => {
|
||||
if (index == currentQuestion) {
|
||||
question.querySelectorAll(".question_button").forEach((button) => (button.tabIndex = 0))
|
||||
}
|
||||
})
|
||||
scoreTally.textContent = `Score: ${score}/${gtc.length}`
|
||||
|
||||
if (currentQuestion < gtc.length) {
|
||||
if (!isMobile) setTimeout(() => firstButtons[currentQuestion]?.focus(), 10)
|
||||
} else {
|
||||
scoreTally.tabIndex = 0
|
||||
setTimeout(() => scoreTally.focus(), 10)
|
||||
}
|
||||
if (currentQuestion < gtc.length) {
|
||||
if (!isMobile) setTimeout(() => firstButtons[currentQuestion]?.focus(), 10)
|
||||
} else {
|
||||
scoreTally.tabIndex = 0
|
||||
setTimeout(() => scoreTally.focus(), 10)
|
||||
}
|
||||
}
|
||||
|
||||
createGTC()
|
||||
|
@ -1,47 +1,47 @@
|
||||
document.onvisibilitychange = () => {
|
||||
// dynamicFavicon()
|
||||
if (document.visibilityState === "visible") changeFavicon(true)
|
||||
else changeFavicon(false)
|
||||
// dynamicFavicon()
|
||||
if (document.visibilityState === "visible") changeFavicon(true)
|
||||
else changeFavicon(false)
|
||||
}
|
||||
|
||||
let faviconIntervalID
|
||||
let faviconCounter = 0
|
||||
|
||||
function dynamicFavicon() {
|
||||
if (document.visibilityState === "visible") {
|
||||
faviconIntervalID = setInterval(changeFav, 500)
|
||||
} else {
|
||||
clearInterval(faviconIntervalID)
|
||||
faviconIntervalID = null
|
||||
if (faviconCounter % 2 == 1) changeFav()
|
||||
}
|
||||
if (document.visibilityState === "visible") {
|
||||
faviconIntervalID = setInterval(changeFav, 500)
|
||||
} else {
|
||||
clearInterval(faviconIntervalID)
|
||||
faviconIntervalID = null
|
||||
if (faviconCounter % 2 == 1) changeFav()
|
||||
}
|
||||
|
||||
function changeFav() {
|
||||
const link = document.createElement("link"),
|
||||
oldLink = document.getElementById("dynamic-favicon")
|
||||
function changeFav() {
|
||||
const link = document.createElement("link"),
|
||||
oldLink = document.getElementById("dynamic-favicon")
|
||||
|
||||
link.id = "dynamic-favicon"
|
||||
link.rel = "icon"
|
||||
link.href = faviconCounter % 2 == 0 ? "src/favicon/icon-off.svg" : "src/favicon/icon.svg"
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink)
|
||||
}
|
||||
document.head.appendChild(link)
|
||||
faviconCounter++
|
||||
}
|
||||
link.id = "dynamic-favicon"
|
||||
link.rel = "icon"
|
||||
link.href = faviconCounter % 2 == 0 ? "src/favicon/icon-off.svg" : "src/favicon/icon.svg"
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink)
|
||||
}
|
||||
document.head.appendChild(link)
|
||||
faviconCounter++
|
||||
}
|
||||
}
|
||||
|
||||
function changeFavicon(hasFocus) {
|
||||
const link = document.createElement("link"),
|
||||
oldLink = document.getElementById("dynamic-favicon")
|
||||
const link = document.createElement("link"),
|
||||
oldLink = document.getElementById("dynamic-favicon")
|
||||
|
||||
link.id = "dynamic-favicon"
|
||||
link.rel = "icon"
|
||||
link.href = hasFocus ? "src/favicon/icon-off.svg" : "src/favicon/icon.svg"
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink)
|
||||
}
|
||||
document.head.appendChild(link)
|
||||
link.id = "dynamic-favicon"
|
||||
link.rel = "icon"
|
||||
link.href = hasFocus ? "src/favicon/icon-off.svg" : "src/favicon/icon.svg"
|
||||
if (oldLink) {
|
||||
document.head.removeChild(oldLink)
|
||||
}
|
||||
document.head.appendChild(link)
|
||||
}
|
||||
|
||||
changeFavicon(true)
|
||||
|
@ -7,189 +7,189 @@ const alternatesContainer = document.querySelector("#alternates_container")
|
||||
const featuresContainer = document.querySelector("#features_container")
|
||||
|
||||
function createCodeSection() {
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") {
|
||||
fontsFieldset.innerHTML = ""
|
||||
section.content.fonts.forEach((font, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "font"
|
||||
input.id = font.id
|
||||
input.classList.add("example_font")
|
||||
input.value = font.name
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = font.name
|
||||
label.setAttribute("for", font.id)
|
||||
div.append(input, label)
|
||||
fontsFieldset.append(div)
|
||||
})
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") {
|
||||
fontsFieldset.innerHTML = ""
|
||||
section.content.fonts.forEach((font, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "font"
|
||||
input.id = font.id
|
||||
input.classList.add("example_font")
|
||||
input.value = font.name
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = font.name
|
||||
label.setAttribute("for", font.id)
|
||||
div.append(input, label)
|
||||
fontsFieldset.append(div)
|
||||
})
|
||||
|
||||
exampleFieldset.innerHTML = ""
|
||||
section.content.languages.forEach((language, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "language"
|
||||
input.id = language.languageName
|
||||
input.classList.add("example_language")
|
||||
input.value = language.languageName
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = language.languageName
|
||||
label.setAttribute("for", language.languageName)
|
||||
div.append(input, label)
|
||||
exampleFieldset.append(div)
|
||||
})
|
||||
exampleFieldset.innerHTML = ""
|
||||
section.content.languages.forEach((language, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "language"
|
||||
input.id = language.languageName
|
||||
input.classList.add("example_language")
|
||||
input.value = language.languageName
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = language.languageName
|
||||
label.setAttribute("for", language.languageName)
|
||||
div.append(input, label)
|
||||
exampleFieldset.append(div)
|
||||
})
|
||||
|
||||
weightFieldset.innerHTML = ""
|
||||
section.content.weights.forEach((weight, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "weight"
|
||||
input.id = `weight_${weight}`
|
||||
input.classList.add("example_weight")
|
||||
input.value = weight
|
||||
if (index == 6) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = weight
|
||||
label.setAttribute("for", `weight_${weight}`)
|
||||
div.append(input, label)
|
||||
weightFieldset.append(div)
|
||||
})
|
||||
weightFieldset.innerHTML = ""
|
||||
section.content.weights.forEach((weight, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "weight"
|
||||
input.id = `weight_${weight}`
|
||||
input.classList.add("example_weight")
|
||||
input.value = weight
|
||||
if (index == 6) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = weight
|
||||
label.setAttribute("for", `weight_${weight}`)
|
||||
div.append(input, label)
|
||||
weightFieldset.append(div)
|
||||
})
|
||||
|
||||
featuresContainer.innerHTML = ""
|
||||
alternatesContainer.innerHTML = ""
|
||||
section.content.features.forEach((feature, index) => {
|
||||
const fieldset = document.createElement("fieldset")
|
||||
const duo = [0, 0]
|
||||
const p = document.createElement("p")
|
||||
p.textContent = feature.label
|
||||
p.id = `alt_${feature.name}`
|
||||
fieldset.append(p)
|
||||
duo.forEach((d, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = feature.name
|
||||
input.id = `${feature.name}${index}`
|
||||
input.value = `'${feature.feature}' ${index == 0 ? "off" : "on"}`
|
||||
if (!feature.on && index == 0) input.setAttribute("checked", "true")
|
||||
if (feature.on && index == 1) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = index == 0 ? "OFF" : "ON"
|
||||
label.setAttribute("for", `${feature.name}${index}`)
|
||||
div.append(input, label)
|
||||
fieldset.append(div)
|
||||
})
|
||||
if (feature.type == "feature") featuresContainer.append(fieldset)
|
||||
else alternatesContainer.append(fieldset)
|
||||
})
|
||||
}
|
||||
})
|
||||
featuresContainer.innerHTML = ""
|
||||
alternatesContainer.innerHTML = ""
|
||||
section.content.features.forEach((feature, index) => {
|
||||
const fieldset = document.createElement("fieldset")
|
||||
const duo = [0, 0]
|
||||
const p = document.createElement("p")
|
||||
p.textContent = feature.label
|
||||
p.id = `alt_${feature.name}`
|
||||
fieldset.append(p)
|
||||
duo.forEach((d, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = feature.name
|
||||
input.id = `${feature.name}${index}`
|
||||
input.value = `'${feature.feature}' ${index == 0 ? "off" : "on"}`
|
||||
if (!feature.on && index == 0) input.setAttribute("checked", "true")
|
||||
if (feature.on && index == 1) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = index == 0 ? "OFF" : "ON"
|
||||
label.setAttribute("for", `${feature.name}${index}`)
|
||||
div.append(input, label)
|
||||
fieldset.append(div)
|
||||
})
|
||||
if (feature.type == "feature") featuresContainer.append(fieldset)
|
||||
else alternatesContainer.append(fieldset)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
updateExamples(null, exampleForm)
|
||||
updateExampleSettings(null, exampleSettingsForm)
|
||||
updateExamples(null, exampleForm)
|
||||
updateExampleSettings(null, exampleSettingsForm)
|
||||
}
|
||||
|
||||
const codeExample = document.querySelector("#code_example")
|
||||
function updateExamples(event, form) {
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") {
|
||||
section.content.languages.forEach((language, index) => {
|
||||
if (language.languageName == output) {
|
||||
codeExample.textContent = language.codeExample
|
||||
let nums = Array.from(new Array(1000), (x, i) => i + 1).join("\n")
|
||||
codeExample.setAttribute("data-before", nums)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "customize") {
|
||||
section.content.languages.forEach((language, index) => {
|
||||
if (language.languageName == output) {
|
||||
codeExample.textContent = language.codeExample
|
||||
let nums = Array.from(new Array(1000), (x, i) => i + 1).join("\n")
|
||||
codeExample.setAttribute("data-before", nums)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
function updateFont(event, form) {
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
codeExample.style.fontFamily = output
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
codeExample.style.fontFamily = output
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
function updateWeight(event, form) {
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = +entry[1]
|
||||
}
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = +entry[1]
|
||||
}
|
||||
|
||||
fontDownloadSettings.weight = output
|
||||
websiteData.weight = output
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}`
|
||||
document.querySelector("#download").textContent = `Download CommitMono-${websiteData.weight} with current settings`
|
||||
fontDownloadSettings.weight = output
|
||||
websiteData.weight = output
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}`
|
||||
document.querySelector("#download").textContent = `Download CommitMono-${websiteData.weight} with current settings`
|
||||
|
||||
console.log(fontDownloadSettings)
|
||||
console.log(fontDownloadSettings)
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
let fontDownloadSettings = { weight: 450, alternates: {}, features: {} }
|
||||
let fontDownloadSettingsDefault = {
|
||||
weight: 450,
|
||||
alternates: {
|
||||
cv01: false,
|
||||
cv02: false,
|
||||
cv03: false,
|
||||
cv04: false,
|
||||
cv05: false,
|
||||
cv06: false,
|
||||
cv07: false,
|
||||
},
|
||||
features: {
|
||||
ss01: false,
|
||||
ss02: false,
|
||||
ss03: true,
|
||||
ss04: true,
|
||||
ss05: true,
|
||||
},
|
||||
weight: 450,
|
||||
alternates: {
|
||||
cv01: false,
|
||||
cv02: false,
|
||||
cv03: false,
|
||||
cv04: false,
|
||||
cv05: false,
|
||||
cv06: false,
|
||||
cv07: false,
|
||||
},
|
||||
features: {
|
||||
ss01: false,
|
||||
ss02: false,
|
||||
ss03: true,
|
||||
ss04: true,
|
||||
ss05: true,
|
||||
},
|
||||
}
|
||||
function updateExampleSettings(event, form) {
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
let font = ""
|
||||
function updateDownloadSettings(type, feature) {
|
||||
const key = feature.split("' ")[0].slice(1)
|
||||
const value = feature.split("' ")[1] == "on"
|
||||
fontDownloadSettings[type][key] = value
|
||||
}
|
||||
for (const entry of data) {
|
||||
if (entry[0] != "font") {
|
||||
output += `${entry[1]}, `
|
||||
if (entry[1].includes("cv")) updateDownloadSettings("alternates", entry[1])
|
||||
if (entry[1].includes("ss")) updateDownloadSettings("features", entry[1])
|
||||
} else font = entry[1]
|
||||
const label = document.querySelector(`#alt_${entry[0]}`)
|
||||
if (label) label.style.fontFeatureSettings = entry[1]
|
||||
}
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
let font = ""
|
||||
function updateDownloadSettings(type, feature) {
|
||||
const key = feature.split("' ")[0].slice(1)
|
||||
const value = feature.split("' ")[1] == "on"
|
||||
fontDownloadSettings[type][key] = value
|
||||
}
|
||||
for (const entry of data) {
|
||||
if (entry[0] != "font") {
|
||||
output += `${entry[1]}, `
|
||||
if (entry[1].includes("cv")) updateDownloadSettings("alternates", entry[1])
|
||||
if (entry[1].includes("ss")) updateDownloadSettings("features", entry[1])
|
||||
} else font = entry[1]
|
||||
const label = document.querySelector(`#alt_${entry[0]}`)
|
||||
if (label) label.style.fontFeatureSettings = entry[1]
|
||||
}
|
||||
|
||||
console.log(fontDownloadSettings)
|
||||
console.log(fontDownloadSettings)
|
||||
|
||||
const codeExample = document.querySelector("#code_example")
|
||||
codeExample.style.fontFeatureSettings = output.slice(0, -2)
|
||||
const codeExample = document.querySelector("#code_example")
|
||||
codeExample.style.fontFeatureSettings = output.slice(0, -2)
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
createCodeSection()
|
||||
|
@ -2,50 +2,50 @@ const familiarContainer = document.querySelector("#familiar_container")
|
||||
|
||||
let familiarContent
|
||||
websiteData.sections.forEach((section) => {
|
||||
if (section.name == "familiar") familiarContent = section.content
|
||||
if (section.name == "familiar") familiarContent = section.content
|
||||
})
|
||||
|
||||
function buildFamiliar() {
|
||||
familiarContainer.innerHTML = ""
|
||||
familiarContent.timeline.forEach((example, index) => {
|
||||
const div = document.createElement("div")
|
||||
div.style.display = index != 0 ? "none" : "block"
|
||||
div.id = example.name
|
||||
div.dataset.name = example.name
|
||||
const svgContainer = document.createElement("div")
|
||||
svgContainer.innerHTML = familiarContent.svgs[example.name]
|
||||
const img = document.createElement("img")
|
||||
img.src = `/src/img/familiar/${example.src}`
|
||||
example.description.forEach((description) => {
|
||||
const p = document.createElement("p")
|
||||
p.textContent = description
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
div.append(p)
|
||||
})
|
||||
const br = document.createElement("br")
|
||||
div.append(br, svgContainer)
|
||||
familiarContainer.append(div)
|
||||
})
|
||||
familiarContainer.innerHTML = ""
|
||||
familiarContent.timeline.forEach((example, index) => {
|
||||
const div = document.createElement("div")
|
||||
div.style.display = index != 0 ? "none" : "block"
|
||||
div.id = example.name
|
||||
div.dataset.name = example.name
|
||||
const svgContainer = document.createElement("div")
|
||||
svgContainer.innerHTML = familiarContent.svgs[example.name]
|
||||
const img = document.createElement("img")
|
||||
img.src = `/src/img/familiar/${example.src}`
|
||||
example.description.forEach((description) => {
|
||||
const p = document.createElement("p")
|
||||
p.textContent = description
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
div.append(p)
|
||||
})
|
||||
const br = document.createElement("br")
|
||||
div.append(br, svgContainer)
|
||||
familiarContainer.append(div)
|
||||
})
|
||||
}
|
||||
buildFamiliar()
|
||||
|
||||
function updateFamiliar(event, form) {
|
||||
buildFamiliar()
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = entry[1]
|
||||
}
|
||||
familiarContent.timeline.forEach((example) => {
|
||||
const exampleContainer = familiarContainer.querySelector(`#${example.name}`)
|
||||
if (exampleContainer.dataset.name == output) {
|
||||
exampleContainer.style.display = "block"
|
||||
} else {
|
||||
exampleContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
event.preventDefault()
|
||||
buildFamiliar()
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = entry[1]
|
||||
}
|
||||
familiarContent.timeline.forEach((example) => {
|
||||
const exampleContainer = familiarContainer.querySelector(`#${example.name}`)
|
||||
if (exampleContainer.dataset.name == output) {
|
||||
exampleContainer.style.display = "block"
|
||||
} else {
|
||||
exampleContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
// const svgs = {
|
||||
|
@ -1,17 +1,17 @@
|
||||
function updateIntelligent(event, form) {
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
const examples = ["original", "smart_kerning", "before", "after"]
|
||||
examples.forEach((example) => {
|
||||
const exampleContainer = document.querySelector(`#${example}`)
|
||||
if (exampleContainer.id == output) {
|
||||
exampleContainer.style.display = "block"
|
||||
} else {
|
||||
exampleContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
event.preventDefault()
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
const examples = ["original", "smart_kerning", "before", "after"]
|
||||
examples.forEach((example) => {
|
||||
const exampleContainer = document.querySelector(`#${example}`)
|
||||
if (exampleContainer.id == output) {
|
||||
exampleContainer.style.display = "block"
|
||||
} else {
|
||||
exampleContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
event.preventDefault()
|
||||
}
|
||||
|
538
src/js/nav.js
538
src/js/nav.js
@ -7,169 +7,169 @@ const navForm = document.querySelector("#nav_form")
|
||||
const changeSetting = document.querySelector("#change_setting p")
|
||||
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "nav"
|
||||
input.id = section.name
|
||||
input.classList.add("nav_section_input")
|
||||
input.value = `section_${index + 1}`
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.for = section.name
|
||||
label.textContent = `${index + 1 < 10 ? `0${index + 1}` : index + 1} ${capitalize(section.name)}`
|
||||
label.classList.add("nav_element")
|
||||
label.dataset.sectionIndex = index + 1
|
||||
label.setAttribute("for", section.name)
|
||||
div.append(input, label)
|
||||
navForm.append(div)
|
||||
if (index == 0) {
|
||||
setTimeout(() => {
|
||||
input.focus()
|
||||
}, 1)
|
||||
}
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.name = "nav"
|
||||
input.id = section.name
|
||||
input.classList.add("nav_section_input")
|
||||
input.value = `section_${index + 1}`
|
||||
if (index == 0) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.for = section.name
|
||||
label.textContent = `${index + 1 < 10 ? `0${index + 1}` : index + 1} ${capitalize(section.name)}`
|
||||
label.classList.add("nav_element")
|
||||
label.dataset.sectionIndex = index + 1
|
||||
label.setAttribute("for", section.name)
|
||||
div.append(input, label)
|
||||
navForm.append(div)
|
||||
if (index == 0) {
|
||||
setTimeout(() => {
|
||||
input.focus()
|
||||
}, 1)
|
||||
}
|
||||
})
|
||||
|
||||
function updateNav(event, form) {
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
pageAnimation()
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const sectionContainer = document.querySelector(`#section_${index + 1}`)
|
||||
if (sectionContainer.id == output) {
|
||||
sectionContainer.style.display = "block"
|
||||
} else {
|
||||
sectionContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
// pushPage("KeyR")
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${entry[1]}`
|
||||
}
|
||||
pageAnimation()
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const sectionContainer = document.querySelector(`#section_${index + 1}`)
|
||||
if (sectionContainer.id == output) {
|
||||
sectionContainer.style.display = "block"
|
||||
} else {
|
||||
sectionContainer.style.display = "none"
|
||||
}
|
||||
})
|
||||
// pushPage("KeyR")
|
||||
|
||||
if (event) event.preventDefault()
|
||||
if (event) event.preventDefault()
|
||||
}
|
||||
|
||||
function pageAnimation() {
|
||||
const element = document.querySelector("#page_animation")
|
||||
element.classList.remove("page_animation")
|
||||
setTimeout(() => element.classList.add("page_animation"), 10)
|
||||
const element = document.querySelector("#page_animation")
|
||||
element.classList.remove("page_animation")
|
||||
setTimeout(() => element.classList.add("page_animation"), 10)
|
||||
}
|
||||
|
||||
let currentSection = 1
|
||||
let insideTextField = false
|
||||
function enterTextField() {
|
||||
active = document.activeElement
|
||||
setTimeout(() => {
|
||||
active.setAttribute("contenteditable", "true")
|
||||
active.blur()
|
||||
active.focus()
|
||||
}, 40)
|
||||
insideTextField = true
|
||||
active = document.activeElement
|
||||
setTimeout(() => {
|
||||
active.setAttribute("contenteditable", "true")
|
||||
active.blur()
|
||||
active.focus()
|
||||
}, 40)
|
||||
insideTextField = true
|
||||
}
|
||||
function exitTextField() {
|
||||
document.activeElement.setAttribute("contenteditable", "false")
|
||||
insideTextField = false
|
||||
document.activeElement.setAttribute("contenteditable", "false")
|
||||
insideTextField = false
|
||||
}
|
||||
|
||||
const keys = document.querySelectorAll(".key")
|
||||
keys.forEach((key) => {
|
||||
key.addEventListener("click", () => {
|
||||
if (key.dataset.noclick != "true") {
|
||||
key.dataset.keyCode.includes("Shift")
|
||||
? keyDown({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: true })
|
||||
: keyDown({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: false })
|
||||
key.dataset.keyCode.includes("Shift")
|
||||
? keyUp({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: true })
|
||||
: keyUp({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: false })
|
||||
}
|
||||
})
|
||||
key.addEventListener("click", () => {
|
||||
if (key.dataset.noclick != "true") {
|
||||
key.dataset.keyCode.includes("Shift")
|
||||
? keyDown({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: true })
|
||||
: keyDown({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: false })
|
||||
key.dataset.keyCode.includes("Shift")
|
||||
? keyUp({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: true })
|
||||
: keyUp({ code: key.dataset.keyCode, key: key.dataset.key, shiftKey: false })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
let changeSettingTimeoutID
|
||||
function keyDown(e) {
|
||||
console.log(e.code)
|
||||
console.log(e.code)
|
||||
|
||||
websiteData.tutorial.forEach((key) => {
|
||||
if (e.code == key) {
|
||||
const keyNode = document.querySelector(`.key_code_${key}`)
|
||||
keyNode.classList.add("pressed_key")
|
||||
}
|
||||
if (key == "ShiftTab" && e.code == "Tab" && e.shiftKey) {
|
||||
const keyNode = document.querySelector(".key_code_ShiftTab")
|
||||
keyNode.classList.add("pressed_key")
|
||||
}
|
||||
})
|
||||
websiteData.tutorial.forEach((key) => {
|
||||
if (e.code == key) {
|
||||
const keyNode = document.querySelector(`.key_code_${key}`)
|
||||
keyNode.classList.add("pressed_key")
|
||||
}
|
||||
if (key == "ShiftTab" && e.code == "Tab" && e.shiftKey) {
|
||||
const keyNode = document.querySelector(".key_code_ShiftTab")
|
||||
keyNode.classList.add("pressed_key")
|
||||
}
|
||||
})
|
||||
|
||||
if (e.code == "KeyE" && document.activeElement.dataset.edit == "true" && !insideTextField) enterTextField()
|
||||
if (e.code == "KeyE" && document.activeElement.dataset.edit == "true" && !insideTextField) enterTextField()
|
||||
|
||||
if (e.code == "Escape") exitTextField()
|
||||
if (e.code == "Escape") exitTextField()
|
||||
|
||||
if (!insideTextField) {
|
||||
// show keypress on frontpage
|
||||
const activeKey = !e.shiftKey
|
||||
? document.querySelector(`.key[data-key-code="${e.code}"]`)
|
||||
: document.querySelector(`.key[data-key-code="Shift${e.code}"]`)
|
||||
activeKey?.classList.add("active_key")
|
||||
if (!insideTextField) {
|
||||
// show keypress on frontpage
|
||||
const activeKey = !e.shiftKey
|
||||
? document.querySelector(`.key[data-key-code="${e.code}"]`)
|
||||
: document.querySelector(`.key[data-key-code="Shift${e.code}"]`)
|
||||
activeKey?.classList.add("active_key")
|
||||
|
||||
if (e.code.includes("Digit")) {
|
||||
goToSection(e.code)
|
||||
}
|
||||
if (e.code.includes("Digit")) {
|
||||
goToSection(e.code)
|
||||
}
|
||||
|
||||
// push page
|
||||
if (
|
||||
e.code == "KeyW" ||
|
||||
e.code == "KeyA" ||
|
||||
e.code == "KeyS" ||
|
||||
e.code == "KeyD" ||
|
||||
e.code == "KeyR" ||
|
||||
e.code == "Minus" ||
|
||||
e.code == "Slash"
|
||||
) {
|
||||
pushPage(e.code)
|
||||
}
|
||||
// push page
|
||||
if (
|
||||
e.code == "KeyW" ||
|
||||
e.code == "KeyA" ||
|
||||
e.code == "KeyS" ||
|
||||
e.code == "KeyD" ||
|
||||
e.code == "KeyR" ||
|
||||
e.code == "Minus" ||
|
||||
e.code == "Slash"
|
||||
) {
|
||||
pushPage(e.code)
|
||||
}
|
||||
|
||||
if (e.code == "KeyH") {
|
||||
document.querySelector("#keyboard_section").classList.toggle("hidden")
|
||||
}
|
||||
if (e.code == "KeyH") {
|
||||
document.querySelector("#keyboard_section").classList.toggle("hidden")
|
||||
}
|
||||
|
||||
if (e.code == "KeyB" || e.code == "KeyL") {
|
||||
if (e.code == "KeyB") websiteData.weight = websiteData.weight == 700 ? 700 : websiteData.weight + 25
|
||||
if (e.code == "KeyL") websiteData.weight = websiteData.weight == 300 ? 300 : websiteData.weight - 25
|
||||
updateCodeFont()
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}`
|
||||
changeSetting.textContent = `Weight: ${websiteData.weight}. Def: 450, Min: 300, Max: 700.`
|
||||
changeSetting.style.visibility = "visible"
|
||||
clearTimeout(changeSettingTimeoutID)
|
||||
changeSettingTimeoutID = setTimeout(() => (changeSetting.style.visibility = "hidden"), 500)
|
||||
document.querySelector(
|
||||
"#download"
|
||||
).textContent = `Download CommitMono-${websiteData.weight} with current settings`
|
||||
document.forms["weight_form"][`weight_${websiteData.weight}`].checked = true
|
||||
}
|
||||
if (e.code == "KeyB" || e.code == "KeyL") {
|
||||
if (e.code == "KeyB") websiteData.weight = websiteData.weight == 700 ? 700 : websiteData.weight + 25
|
||||
if (e.code == "KeyL") websiteData.weight = websiteData.weight == 300 ? 300 : websiteData.weight - 25
|
||||
updateCodeFont()
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" ${websiteData.weight}`
|
||||
changeSetting.textContent = `Weight: ${websiteData.weight}. Def: 450, Min: 300, Max: 700.`
|
||||
changeSetting.style.visibility = "visible"
|
||||
clearTimeout(changeSettingTimeoutID)
|
||||
changeSettingTimeoutID = setTimeout(() => (changeSetting.style.visibility = "hidden"), 500)
|
||||
document.querySelector(
|
||||
"#download"
|
||||
).textContent = `Download CommitMono-${websiteData.weight} with current settings`
|
||||
document.forms["weight_form"][`weight_${websiteData.weight}`].checked = true
|
||||
}
|
||||
|
||||
if (e.code == "KeyM") {
|
||||
if (websiteData.invert) {
|
||||
setCssVar(["--bg", "#aaa"])
|
||||
setCssVar(["--text", "#111"])
|
||||
} else {
|
||||
setCssVar(["--bg", "#111"])
|
||||
setCssVar(["--text", "#aaa"])
|
||||
}
|
||||
updateCode(null, codeForm)
|
||||
websiteData.invert = !websiteData.invert
|
||||
}
|
||||
}
|
||||
if (e.code == "KeyM") {
|
||||
if (websiteData.invert) {
|
||||
setCssVar(["--bg", "#aaa"])
|
||||
setCssVar(["--text", "#111"])
|
||||
} else {
|
||||
setCssVar(["--bg", "#111"])
|
||||
setCssVar(["--text", "#aaa"])
|
||||
}
|
||||
updateCode(null, codeForm)
|
||||
websiteData.invert = !websiteData.invert
|
||||
}
|
||||
}
|
||||
}
|
||||
function keyUp(e) {
|
||||
const activeKey = document.querySelectorAll(".active_key")
|
||||
activeKey?.forEach((key) => key.classList.remove("active_key"))
|
||||
const activeKey = document.querySelectorAll(".active_key")
|
||||
activeKey?.forEach((key) => key.classList.remove("active_key"))
|
||||
|
||||
if (e.code == "Tab" && document.activeElement.id.includes("block_tab")) {
|
||||
console.log("active nav section then tab")
|
||||
const checkedMenuInput = document.querySelector("#nav_form input:checked")
|
||||
checkedMenuInput.focus()
|
||||
}
|
||||
if (e.code == "Tab" && document.activeElement.id.includes("block_tab")) {
|
||||
console.log("active nav section then tab")
|
||||
const checkedMenuInput = document.querySelector("#nav_form input:checked")
|
||||
checkedMenuInput.focus()
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", keyDown)
|
||||
@ -181,179 +181,179 @@ const keySection = document.querySelector("#keyboard_section")
|
||||
let rem = +document.documentElement.style.fontSize.split("px")[0]
|
||||
|
||||
function pushPage(keyCode) {
|
||||
console.log("push page", keyCode)
|
||||
const x = websiteData.pushPage.coordinates.x
|
||||
const y = websiteData.pushPage.coordinates.y
|
||||
const scale = websiteData.pushPage.scale
|
||||
const dist = websiteData.pushPage.distance
|
||||
console.log("push page", keyCode)
|
||||
const x = websiteData.pushPage.coordinates.x
|
||||
const y = websiteData.pushPage.coordinates.y
|
||||
const scale = websiteData.pushPage.scale
|
||||
const dist = websiteData.pushPage.distance
|
||||
|
||||
// move left
|
||||
if (keyCode == "KeyW") {
|
||||
main.style.transform = `translate(${x}px, ${y + dist}px)`
|
||||
navForm.style.transform = `translate(${x}px, 0)`
|
||||
keySection.style.transform = `translate(${x}px, 0)`
|
||||
websiteData.pushPage.coordinates.y += dist
|
||||
}
|
||||
// move left
|
||||
if (keyCode == "KeyW") {
|
||||
main.style.transform = `translate(${x}px, ${y + dist}px)`
|
||||
navForm.style.transform = `translate(${x}px, 0)`
|
||||
keySection.style.transform = `translate(${x}px, 0)`
|
||||
websiteData.pushPage.coordinates.y += dist
|
||||
}
|
||||
|
||||
// move left
|
||||
else if (keyCode == "KeyA") {
|
||||
main.style.transform = `translate(${x + dist}px, ${y}px)`
|
||||
navForm.style.transform = `translate(${x + dist}px, 0)`
|
||||
keySection.style.transform = `translate(${x + dist}px, 0)`
|
||||
websiteData.pushPage.coordinates.x += dist
|
||||
}
|
||||
// move left
|
||||
else if (keyCode == "KeyA") {
|
||||
main.style.transform = `translate(${x + dist}px, ${y}px)`
|
||||
navForm.style.transform = `translate(${x + dist}px, 0)`
|
||||
keySection.style.transform = `translate(${x + dist}px, 0)`
|
||||
websiteData.pushPage.coordinates.x += dist
|
||||
}
|
||||
|
||||
// move down
|
||||
else if (keyCode == "KeyS") {
|
||||
main.style.transform = `translate(${x}px, ${y - dist}px)`
|
||||
navForm.style.transform = `translate(${x}px, 0)`
|
||||
keySection.style.transform = `translate(${x}px, 0)`
|
||||
websiteData.pushPage.coordinates.y -= dist
|
||||
}
|
||||
// move down
|
||||
else if (keyCode == "KeyS") {
|
||||
main.style.transform = `translate(${x}px, ${y - dist}px)`
|
||||
navForm.style.transform = `translate(${x}px, 0)`
|
||||
keySection.style.transform = `translate(${x}px, 0)`
|
||||
websiteData.pushPage.coordinates.y -= dist
|
||||
}
|
||||
|
||||
// move right
|
||||
else if (keyCode == "KeyD") {
|
||||
main.style.transform = `translate(${x - dist}px, ${y}px)`
|
||||
navForm.style.transform = `translate(${x - dist}px, 0)`
|
||||
keySection.style.transform = `translate(${x - dist}px, 0)`
|
||||
websiteData.pushPage.coordinates.x -= dist
|
||||
}
|
||||
// move right
|
||||
else if (keyCode == "KeyD") {
|
||||
main.style.transform = `translate(${x - dist}px, ${y}px)`
|
||||
navForm.style.transform = `translate(${x - dist}px, 0)`
|
||||
keySection.style.transform = `translate(${x - dist}px, 0)`
|
||||
websiteData.pushPage.coordinates.x -= dist
|
||||
}
|
||||
|
||||
// zoom in ("Minus" is the plus key, very confusing)
|
||||
else if (keyCode == "Minus") {
|
||||
rem = +rem + 2
|
||||
document.documentElement.style.fontSize = `${rem}px`
|
||||
updateWaterfall()
|
||||
document.querySelector("#canvas").style.transform = `scale(${rem / 16})`
|
||||
changeSetting.textContent = `Base font size: ${rem}px`
|
||||
changeSetting.style.visibility = "visible"
|
||||
clearTimeout(changeSettingTimeoutID)
|
||||
changeSettingTimeoutID = setTimeout(() => (changeSetting.style.visibility = "hidden"), 500)
|
||||
}
|
||||
// zoom in ("Minus" is the plus key, very confusing)
|
||||
else if (keyCode == "Minus") {
|
||||
rem = +rem + 2
|
||||
document.documentElement.style.fontSize = `${rem}px`
|
||||
updateWaterfall()
|
||||
document.querySelector("#canvas").style.transform = `scale(${rem / 16})`
|
||||
changeSetting.textContent = `Base font size: ${rem}px`
|
||||
changeSetting.style.visibility = "visible"
|
||||
clearTimeout(changeSettingTimeoutID)
|
||||
changeSettingTimeoutID = setTimeout(() => (changeSetting.style.visibility = "hidden"), 500)
|
||||
}
|
||||
|
||||
// zoom out
|
||||
else if (keyCode == "Slash") {
|
||||
rem = +rem - 2
|
||||
document.documentElement.style.fontSize = `${rem}px`
|
||||
updateWaterfall()
|
||||
document.querySelector("#canvas").style.transform = `scale(${rem / 16})`
|
||||
changeSetting.textContent = `Base font size: ${rem}px`
|
||||
changeSetting.style.visibility = "visible"
|
||||
clearTimeout(changeSettingTimeoutID)
|
||||
changeSettingTimeoutID = setTimeout(() => (changeSetting.style.visibility = "hidden"), 500)
|
||||
}
|
||||
// zoom out
|
||||
else if (keyCode == "Slash") {
|
||||
rem = +rem - 2
|
||||
document.documentElement.style.fontSize = `${rem}px`
|
||||
updateWaterfall()
|
||||
document.querySelector("#canvas").style.transform = `scale(${rem / 16})`
|
||||
changeSetting.textContent = `Base font size: ${rem}px`
|
||||
changeSetting.style.visibility = "visible"
|
||||
clearTimeout(changeSettingTimeoutID)
|
||||
changeSettingTimeoutID = setTimeout(() => (changeSetting.style.visibility = "hidden"), 500)
|
||||
}
|
||||
|
||||
// reset transforms
|
||||
else if (keyCode == "KeyR") {
|
||||
main.style.transform = `translate(0)`
|
||||
navForm.style.transform = `translate(0)`
|
||||
keySection.style.transform = `translate(0)`
|
||||
mainScale.style.transform = `scale(1)`
|
||||
websiteData.pushPage.coordinates.x = 0
|
||||
websiteData.pushPage.coordinates.y = 0
|
||||
websiteData.pushPage.scale = 1
|
||||
rem = 16
|
||||
document.documentElement.style.fontSize = "16px"
|
||||
document.querySelector("#canvas").style.transform = "scale(1)"
|
||||
websiteData.weight = 450
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" 450`
|
||||
if (typeof updateCodeFont === "function") updateCodeFont()
|
||||
if (typeof updateWaterfall === "function") updateWaterfall()
|
||||
if (typeof createCodeSection === "function") createCodeSection()
|
||||
}
|
||||
// reset transforms
|
||||
else if (keyCode == "KeyR") {
|
||||
main.style.transform = `translate(0)`
|
||||
navForm.style.transform = `translate(0)`
|
||||
keySection.style.transform = `translate(0)`
|
||||
mainScale.style.transform = `scale(1)`
|
||||
websiteData.pushPage.coordinates.x = 0
|
||||
websiteData.pushPage.coordinates.y = 0
|
||||
websiteData.pushPage.scale = 1
|
||||
rem = 16
|
||||
document.documentElement.style.fontSize = "16px"
|
||||
document.querySelector("#canvas").style.transform = "scale(1)"
|
||||
websiteData.weight = 450
|
||||
document.querySelector("body").style.fontVariationSettings = `"wght" 450`
|
||||
if (typeof updateCodeFont === "function") updateCodeFont()
|
||||
if (typeof updateWaterfall === "function") updateWaterfall()
|
||||
if (typeof createCodeSection === "function") createCodeSection()
|
||||
}
|
||||
}
|
||||
|
||||
let active // saves what DOM element is currently active
|
||||
let focusTimeOutID // to be able to use clearTimeout()
|
||||
document.addEventListener("focusin", (e) => {
|
||||
// console.log("focusin", document.activeElement)
|
||||
// console.log("focusin", document.activeElement)
|
||||
|
||||
// new focus: exit text field
|
||||
if (document.activeElement != active) exitTextField()
|
||||
// new focus: exit text field
|
||||
if (document.activeElement != active) exitTextField()
|
||||
|
||||
const prevActive = active
|
||||
const prevActive = active
|
||||
|
||||
// save current focused element
|
||||
active = document.activeElement
|
||||
// save current focused element
|
||||
active = document.activeElement
|
||||
|
||||
// // when current focused element is blurred, start a timer of 100ms.
|
||||
// active.addEventListener("blur", onBlurIn)
|
||||
// // when current focused element is blurred, start a timer of 100ms.
|
||||
// active.addEventListener("blur", onBlurIn)
|
||||
|
||||
// // clear timeout when a new element is focused
|
||||
// clearTimeout(focusTimeOutID)
|
||||
// focusTimeOutID = null
|
||||
// // clear timeout when a new element is focused
|
||||
// clearTimeout(focusTimeOutID)
|
||||
// focusTimeOutID = null
|
||||
|
||||
if (active.id.includes("block_tab")) {
|
||||
console.log("BLOCK TAB")
|
||||
if (prevActive.className.includes("question_button")) {
|
||||
prevActive.parentElement.querySelector(".question_button").focus()
|
||||
} else {
|
||||
const checkedMenuInput = document.querySelector("#nav_form input:checked")
|
||||
checkedMenuInput.focus()
|
||||
}
|
||||
}
|
||||
if (active.id.includes("block_tab")) {
|
||||
console.log("BLOCK TAB")
|
||||
if (prevActive.className.includes("question_button")) {
|
||||
prevActive.parentElement.querySelector(".question_button").focus()
|
||||
} else {
|
||||
const checkedMenuInput = document.querySelector("#nav_form input:checked")
|
||||
checkedMenuInput.focus()
|
||||
}
|
||||
}
|
||||
|
||||
// scroll page, if focus reaches bottom or top
|
||||
const bounds = active.getBoundingClientRect()
|
||||
const paddingOffsetBottom = 200
|
||||
if (bounds.top > window.innerHeight - paddingOffsetBottom) {
|
||||
const numberOfMoves = Math.floor(
|
||||
(bounds.top - (window.innerHeight - paddingOffsetBottom)) / websiteData.pushPage.distance
|
||||
)
|
||||
for (let i = 0; i < numberOfMoves; i++) {
|
||||
pushPage("KeyS")
|
||||
}
|
||||
}
|
||||
const paddingOffsetTop = 16
|
||||
if (bounds.top < paddingOffsetTop) {
|
||||
const numberOfMoves = Math.ceil(Math.abs(bounds.top - paddingOffsetTop - 32) / websiteData.pushPage.distance)
|
||||
console.log("num of moves:", numberOfMoves, "bounds.top:", bounds.top)
|
||||
for (let i = 0; i < numberOfMoves; i++) {
|
||||
pushPage("KeyW")
|
||||
}
|
||||
}
|
||||
// scroll page, if focus reaches bottom or top
|
||||
const bounds = active.getBoundingClientRect()
|
||||
const paddingOffsetBottom = 200
|
||||
if (bounds.top > window.innerHeight - paddingOffsetBottom) {
|
||||
const numberOfMoves = Math.floor(
|
||||
(bounds.top - (window.innerHeight - paddingOffsetBottom)) / websiteData.pushPage.distance
|
||||
)
|
||||
for (let i = 0; i < numberOfMoves; i++) {
|
||||
pushPage("KeyS")
|
||||
}
|
||||
}
|
||||
const paddingOffsetTop = 16
|
||||
if (bounds.top < paddingOffsetTop) {
|
||||
const numberOfMoves = Math.ceil(Math.abs(bounds.top - paddingOffsetTop - 32) / websiteData.pushPage.distance)
|
||||
console.log("num of moves:", numberOfMoves, "bounds.top:", bounds.top)
|
||||
for (let i = 0; i < numberOfMoves; i++) {
|
||||
pushPage("KeyW")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
let prevHasFocus = true
|
||||
function checkDocumentFocus() {
|
||||
if (!isMobile) {
|
||||
if (prevHasFocus != document.hasFocus()) {
|
||||
changedFocus(document.hasFocus())
|
||||
}
|
||||
prevHasFocus = document.hasFocus()
|
||||
}
|
||||
if (!isMobile) {
|
||||
if (prevHasFocus != document.hasFocus()) {
|
||||
changedFocus(document.hasFocus())
|
||||
}
|
||||
prevHasFocus = document.hasFocus()
|
||||
}
|
||||
}
|
||||
|
||||
function changedFocus(hasFocus) {
|
||||
if (hasFocus) active.focus()
|
||||
changeFavicon(hasFocus)
|
||||
hasFocus ? contentRoot.classList.remove("faded") : contentRoot.classList.add("faded")
|
||||
clickFocus.style.visibility = hasFocus ? "hidden" : "visible"
|
||||
updateCode(null, codeForm)
|
||||
if (hasFocus) active.focus()
|
||||
changeFavicon(hasFocus)
|
||||
hasFocus ? contentRoot.classList.remove("faded") : contentRoot.classList.add("faded")
|
||||
clickFocus.style.visibility = hasFocus ? "hidden" : "visible"
|
||||
updateCode(null, codeForm)
|
||||
}
|
||||
|
||||
function onBlurIn(e) {
|
||||
// remove event listener from so they don't stack
|
||||
e.target.removeEventListener("blur", onBlurIn)
|
||||
// remove event listener from so they don't stack
|
||||
e.target.removeEventListener("blur", onBlurIn)
|
||||
|
||||
// if this timer runs out before a new element is focused, refocus same element
|
||||
if (!isMobile)
|
||||
focusTimeOutID = setTimeout(() => {
|
||||
active.focus()
|
||||
}, 100)
|
||||
// if this timer runs out before a new element is focused, refocus same element
|
||||
if (!isMobile)
|
||||
focusTimeOutID = setTimeout(() => {
|
||||
active.focus()
|
||||
}, 100)
|
||||
}
|
||||
|
||||
function goToSection(keyCode) {
|
||||
pageAnimation()
|
||||
const section = +keyCode.split("Digit")[1]
|
||||
const sectionName = websiteData.sections[section - 1]?.name
|
||||
const attemptedSection = document.querySelector(`[value="section_${section}"]`)
|
||||
if (attemptedSection && sectionName) {
|
||||
attemptedSection.focus()
|
||||
document.forms["nav_form"][sectionName].checked = true
|
||||
updateNav(null, navForm)
|
||||
console.log(section, sectionName, attemptedSection)
|
||||
}
|
||||
pageAnimation()
|
||||
const section = +keyCode.split("Digit")[1]
|
||||
const sectionName = websiteData.sections[section - 1]?.name
|
||||
const attemptedSection = document.querySelector(`[value="section_${section}"]`)
|
||||
if (attemptedSection && sectionName) {
|
||||
attemptedSection.focus()
|
||||
document.forms["nav_form"][sectionName].checked = true
|
||||
updateNav(null, navForm)
|
||||
console.log(section, sectionName, attemptedSection)
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(checkDocumentFocus, 100)
|
||||
|
@ -2,20 +2,20 @@ console.log("opentype test")
|
||||
const versionOfCommitMono = "V109"
|
||||
|
||||
const updateLabel = (input) => {
|
||||
console.log(input)
|
||||
input.parentNode.querySelector("output").textContent = input.value
|
||||
console.log(input)
|
||||
input.parentNode.querySelector("output").textContent = input.value
|
||||
}
|
||||
|
||||
const updateOptions = (event, form) => {
|
||||
console.log(event)
|
||||
console.log(event)
|
||||
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${output}${entry[0]}=${entry[1]}\n`
|
||||
}
|
||||
console.log(output)
|
||||
event.preventDefault()
|
||||
const data = new FormData(form)
|
||||
let output = ""
|
||||
for (const entry of data) {
|
||||
output = `${output}${entry[0]}=${entry[1]}\n`
|
||||
}
|
||||
console.log(output)
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
let commitMonoFont
|
||||
@ -37,172 +37,172 @@ let commitMonoFont
|
||||
// }
|
||||
|
||||
async function updateCodeFont() {
|
||||
opentype
|
||||
.load(`/src/fonts/instances/CommitMono${versionOfCommitMono}-${websiteData.weight}.otf`)
|
||||
.then((font) => {
|
||||
commitMonoFont = font
|
||||
updateCode(null, codeForm)
|
||||
})
|
||||
.catch((err) => console.log(err))
|
||||
opentype
|
||||
.load(`/src/fonts/instances/CommitMono${versionOfCommitMono}-${websiteData.weight}.otf`)
|
||||
.then((font) => {
|
||||
commitMonoFont = font
|
||||
updateCode(null, codeForm)
|
||||
})
|
||||
.catch((err) => console.log(err))
|
||||
}
|
||||
|
||||
updateCodeFont()
|
||||
|
||||
let downloadStarted = false
|
||||
async function downloadFont(button) {
|
||||
if (!downloadStarted) {
|
||||
downloadStarted = true
|
||||
let downloadableFont
|
||||
if (button.dataset.type === "staticDefault") {
|
||||
downloadWithSettings(fontDownloadSettingsDefault, button)
|
||||
}
|
||||
if (button.dataset.type === "staticCurrent") {
|
||||
downloadWithSettings(fontDownloadSettings, button)
|
||||
console.log(button.dataset.type)
|
||||
}
|
||||
if (button.dataset.type === "variableDefault") {
|
||||
downloadWithSettings(fontDownloadSettingsDefault, button)
|
||||
console.log(button.dataset.type)
|
||||
}
|
||||
}
|
||||
if (!downloadStarted) {
|
||||
downloadStarted = true
|
||||
let downloadableFont
|
||||
if (button.dataset.type === "staticDefault") {
|
||||
downloadWithSettings(fontDownloadSettingsDefault, button)
|
||||
}
|
||||
if (button.dataset.type === "staticCurrent") {
|
||||
downloadWithSettings(fontDownloadSettings, button)
|
||||
console.log(button.dataset.type)
|
||||
}
|
||||
if (button.dataset.type === "variableDefault") {
|
||||
downloadWithSettings(fontDownloadSettingsDefault, button)
|
||||
console.log(button.dataset.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function downloadWithSettings(settings, button) {
|
||||
console.log(settings)
|
||||
button.classList.add("loading")
|
||||
console.log(settings)
|
||||
button.classList.add("loading")
|
||||
|
||||
const fontFilePath = `/src/fonts/instances/CommitMono${versionOfCommitMono}-${settings.weight}.otf`
|
||||
const fontFilePath = `/src/fonts/instances/CommitMono${versionOfCommitMono}-${settings.weight}.otf`
|
||||
|
||||
opentype
|
||||
.load(fontFilePath)
|
||||
.then(async (font) => {
|
||||
//
|
||||
// #1 change alternates by switching their paths
|
||||
// the below loop does this
|
||||
opentype
|
||||
.load(fontFilePath)
|
||||
.then(async (font) => {
|
||||
//
|
||||
// #1 change alternates by switching their paths
|
||||
// the below loop does this
|
||||
|
||||
// loop through the alternate settings
|
||||
Object.entries(settings.alternates).forEach(([alternate, active]) => {
|
||||
//
|
||||
// filter for only the active ones
|
||||
if (!active) return
|
||||
console.log("alternate", alternate, "active", active)
|
||||
// loop through the alternate settings
|
||||
Object.entries(settings.alternates).forEach(([alternate, active]) => {
|
||||
//
|
||||
// filter for only the active ones
|
||||
if (!active) return
|
||||
console.log("alternate", alternate, "active", active)
|
||||
|
||||
// look at all the fonts features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// if the feature matches the alternate we're currently on
|
||||
if (feature.tag == alternate) {
|
||||
console.log("feature", feature)
|
||||
// look at all the fonts features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// if the feature matches the alternate we're currently on
|
||||
if (feature.tag == alternate) {
|
||||
console.log("feature", feature)
|
||||
|
||||
// then loop through the list of lookup indexes of that feature
|
||||
feature.feature.lookupListIndexes.forEach((lookupIndex) => {
|
||||
console.log("lookupIndex", lookupIndex)
|
||||
// then loop through the list of lookup indexes of that feature
|
||||
feature.feature.lookupListIndexes.forEach((lookupIndex) => {
|
||||
console.log("lookupIndex", lookupIndex)
|
||||
|
||||
// loop through the subtable of each lookup at the lookup index
|
||||
font.tables.gsub.lookups[lookupIndex].subtables.forEach((subtable) => {
|
||||
console.log("subtable", subtable)
|
||||
// loop through the subtable of each lookup at the lookup index
|
||||
font.tables.gsub.lookups[lookupIndex].subtables.forEach((subtable) => {
|
||||
console.log("subtable", subtable)
|
||||
|
||||
// loop through the glyphs of the subtable
|
||||
subtable.coverage.glyphs.forEach((glyphIndexOriginal, index) => {
|
||||
//
|
||||
// glyphIndexOriginal is the index of the original glyph
|
||||
// glyphIndexSubstitute is the index of the glyph to substitute the original with
|
||||
const glyphIndexSubstitute = subtable.substitute[index]
|
||||
console.log("glyphIndexOriginal", glyphIndexOriginal, "glyphIndexSubstitute", glyphIndexSubstitute)
|
||||
// loop through the glyphs of the subtable
|
||||
subtable.coverage.glyphs.forEach((glyphIndexOriginal, index) => {
|
||||
//
|
||||
// glyphIndexOriginal is the index of the original glyph
|
||||
// glyphIndexSubstitute is the index of the glyph to substitute the original with
|
||||
const glyphIndexSubstitute = subtable.substitute[index]
|
||||
console.log("glyphIndexOriginal", glyphIndexOriginal, "glyphIndexSubstitute", glyphIndexSubstitute)
|
||||
|
||||
// get the paths for the original and the substitute glyph
|
||||
const glyphPathOriginal = font.glyphs.glyphs[glyphIndexOriginal].path
|
||||
const glyphPathSubstitute = font.glyphs.glyphs[glyphIndexSubstitute].path
|
||||
// get the paths for the original and the substitute glyph
|
||||
const glyphPathOriginal = font.glyphs.glyphs[glyphIndexOriginal].path
|
||||
const glyphPathSubstitute = font.glyphs.glyphs[glyphIndexSubstitute].path
|
||||
|
||||
// swap the paths, so the original glyph gets the path of the substitute and vice versa
|
||||
font.glyphs.glyphs[glyphIndexOriginal].path = glyphPathSubstitute
|
||||
font.glyphs.glyphs[glyphIndexSubstitute].path = glyphPathOriginal
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
// swap the paths, so the original glyph gets the path of the substitute and vice versa
|
||||
font.glyphs.glyphs[glyphIndexOriginal].path = glyphPathSubstitute
|
||||
font.glyphs.glyphs[glyphIndexSubstitute].path = glyphPathOriginal
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
//
|
||||
// "2 put active features into calt
|
||||
// create empty "calt" feature to store the feature
|
||||
const emptyCalt = { tag: "calt", feature: { featureParams: 0, lookupListIndexes: [] } }
|
||||
font.tables.gsub.features.push(emptyCalt)
|
||||
//
|
||||
// "2 put active features into calt
|
||||
// create empty "calt" feature to store the feature
|
||||
const emptyCalt = { tag: "calt", feature: { featureParams: 0, lookupListIndexes: [] } }
|
||||
font.tables.gsub.features.push(emptyCalt)
|
||||
|
||||
// garbage code that adds a single number to a specific array in the gsub table
|
||||
// like this [0, 1, 2, 3, 4] => [0, 1, 2, 3, 4, 5]
|
||||
font.tables.gsub.scripts.forEach((script) =>
|
||||
script.script.defaultLangSys.featureIndexes.push(script.script.defaultLangSys.featureIndexes.length)
|
||||
)
|
||||
// garbage code that adds a single number to a specific array in the gsub table
|
||||
// like this [0, 1, 2, 3, 4] => [0, 1, 2, 3, 4, 5]
|
||||
font.tables.gsub.scripts.forEach((script) =>
|
||||
script.script.defaultLangSys.featureIndexes.push(script.script.defaultLangSys.featureIndexes.length)
|
||||
)
|
||||
|
||||
// create the empty array that is to be the lookup indexes for the calt feature
|
||||
const caltLookupIndexes = []
|
||||
// create the empty array that is to be the lookup indexes for the calt feature
|
||||
const caltLookupIndexes = []
|
||||
|
||||
// once again, loop through the alternate settings (feature settings)
|
||||
Object.entries(settings.features).forEach(([alternate, active]) => {
|
||||
//
|
||||
// filter for only the active ones
|
||||
if (!active) return
|
||||
console.log("alternate", alternate, "active", active)
|
||||
// once again, loop through the alternate settings (feature settings)
|
||||
Object.entries(settings.features).forEach(([alternate, active]) => {
|
||||
//
|
||||
// filter for only the active ones
|
||||
if (!active) return
|
||||
console.log("alternate", alternate, "active", active)
|
||||
|
||||
// then loop through all features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// and find the ones that match the active tags
|
||||
if (feature.tag == alternate) {
|
||||
console.log("feature", feature)
|
||||
// then loop through all features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// and find the ones that match the active tags
|
||||
if (feature.tag == alternate) {
|
||||
console.log("feature", feature)
|
||||
|
||||
// push the lookup indexes into the empty caltLookupIndexes variable
|
||||
feature.feature.lookupListIndexes.forEach((lookupIndex) => caltLookupIndexes.push(lookupIndex))
|
||||
}
|
||||
})
|
||||
// push the lookup indexes into the empty caltLookupIndexes variable
|
||||
feature.feature.lookupListIndexes.forEach((lookupIndex) => caltLookupIndexes.push(lookupIndex))
|
||||
}
|
||||
})
|
||||
|
||||
// once more loop through all features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// when the calt feature is reached (it's the last one)
|
||||
if (feature.tag === "calt") {
|
||||
//
|
||||
// set its lookup indexes to the variable
|
||||
feature.feature.lookupListIndexes = caltLookupIndexes
|
||||
console.log("caltLookupIndexes", caltLookupIndexes)
|
||||
}
|
||||
})
|
||||
})
|
||||
// once more loop through all features
|
||||
font.tables.gsub.features.forEach((feature) => {
|
||||
//
|
||||
// when the calt feature is reached (it's the last one)
|
||||
if (feature.tag === "calt") {
|
||||
//
|
||||
// set its lookup indexes to the variable
|
||||
feature.feature.lookupListIndexes = caltLookupIndexes
|
||||
console.log("caltLookupIndexes", caltLookupIndexes)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
//
|
||||
// #3 change the names
|
||||
Object.entries(font.names).forEach(([nameKey, nameValue]) => {
|
||||
const oldName = `CommitMono${versionOfCommitMono}`
|
||||
const newName = "CommitMono"
|
||||
if (nameValue.en.includes(oldName)) {
|
||||
nameValue.en = nameValue.en
|
||||
.split(oldName)
|
||||
.map((str, i) => (i == 0 ? newName : str))
|
||||
.join("")
|
||||
}
|
||||
console.log(nameKey)
|
||||
if (nameKey == "fullName") {
|
||||
font.names[nameKey].en = nameValue.en.split(" ").join("-")
|
||||
}
|
||||
})
|
||||
font.tables.name = font.names
|
||||
//
|
||||
// #3 change the names
|
||||
Object.entries(font.names).forEach(([nameKey, nameValue]) => {
|
||||
const oldName = `CommitMono${versionOfCommitMono}`
|
||||
const newName = "CommitMono"
|
||||
if (nameValue.en.includes(oldName)) {
|
||||
nameValue.en = nameValue.en
|
||||
.split(oldName)
|
||||
.map((str, i) => (i == 0 ? newName : str))
|
||||
.join("")
|
||||
}
|
||||
console.log(nameKey)
|
||||
if (nameKey == "fullName") {
|
||||
font.names[nameKey].en = nameValue.en.split(" ").join("-")
|
||||
}
|
||||
})
|
||||
font.tables.name = font.names
|
||||
|
||||
// await wait(1000)
|
||||
await font.download()
|
||||
downloadStarted = false
|
||||
button.classList.remove("loading")
|
||||
button.classList.add("loaded")
|
||||
// await wait(1000)
|
||||
await font.download()
|
||||
downloadStarted = false
|
||||
button.classList.remove("loading")
|
||||
button.classList.add("loaded")
|
||||
|
||||
console.log(font)
|
||||
})
|
||||
.catch(async (err) => {
|
||||
await wait(1000)
|
||||
button.classList.remove("loading")
|
||||
button.classList.add("error")
|
||||
console.log(font)
|
||||
})
|
||||
.catch(async (err) => {
|
||||
await wait(1000)
|
||||
button.classList.remove("loading")
|
||||
button.classList.add("error")
|
||||
|
||||
downloadStarted = false
|
||||
console.log(err)
|
||||
})
|
||||
downloadStarted = false
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
websiteData.sections.forEach((section, index) => {
|
||||
const topContainer = document.querySelector(`#section_${index + 1} .top_container`)
|
||||
if (topContainer) {
|
||||
const h1 = document.createElement("h1")
|
||||
h1.textContent = `${index + 1 < 10 ? `0${index + 1}` : index + 1} ${capitalize(section.name)}`
|
||||
h1.tabIndex = 0
|
||||
h1.dataset.edit = "true"
|
||||
const br = document.createElement("br")
|
||||
const p = document.createElement("p")
|
||||
p.textContent = section.description
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
topContainer.append(h1, br, p)
|
||||
}
|
||||
const topContainer = document.querySelector(`#section_${index + 1} .top_container`)
|
||||
if (topContainer) {
|
||||
const h1 = document.createElement("h1")
|
||||
h1.textContent = `${index + 1 < 10 ? `0${index + 1}` : index + 1} ${capitalize(section.name)}`
|
||||
h1.tabIndex = 0
|
||||
h1.dataset.edit = "true"
|
||||
const br = document.createElement("br")
|
||||
const p = document.createElement("p")
|
||||
p.textContent = section.description
|
||||
p.tabIndex = 0
|
||||
p.dataset.edit = "true"
|
||||
topContainer.append(h1, br, p)
|
||||
}
|
||||
})
|
||||
|
@ -1,68 +1,68 @@
|
||||
function createTable() {
|
||||
const table = document.querySelector("#section_2 .content_container table")
|
||||
const table = document.querySelector("#section_2 .content_container table")
|
||||
|
||||
for (let i = 0; i <= 6; i++) {
|
||||
const tr = document.createElement("tr")
|
||||
const fieldset = document.createElement("fieldset")
|
||||
tr.append(fieldset)
|
||||
for (let j = 0; j <= 16; j++) {
|
||||
if (i == 0 || j == 0) {
|
||||
const th = document.createElement("th")
|
||||
const div = document.createElement("div")
|
||||
const p = document.createElement("p")
|
||||
if (i != 0 && j == 0) {
|
||||
p.textContent = createBinaryString(i + 1, 3)
|
||||
} else if (i == 0 && j != 0) {
|
||||
p.textContent = createBinaryString(j - 1, 4)
|
||||
} else {
|
||||
p.textContent = ""
|
||||
}
|
||||
div.append(p)
|
||||
th.append(div)
|
||||
fieldset.append(th)
|
||||
} else {
|
||||
const charCode = (i - 1) * 16 + j + 31
|
||||
for (let i = 0; i <= 6; i++) {
|
||||
const tr = document.createElement("tr")
|
||||
const fieldset = document.createElement("fieldset")
|
||||
tr.append(fieldset)
|
||||
for (let j = 0; j <= 16; j++) {
|
||||
if (i == 0 || j == 0) {
|
||||
const th = document.createElement("th")
|
||||
const div = document.createElement("div")
|
||||
const p = document.createElement("p")
|
||||
if (i != 0 && j == 0) {
|
||||
p.textContent = createBinaryString(i + 1, 3)
|
||||
} else if (i == 0 && j != 0) {
|
||||
p.textContent = createBinaryString(j - 1, 4)
|
||||
} else {
|
||||
p.textContent = ""
|
||||
}
|
||||
div.append(p)
|
||||
th.append(div)
|
||||
fieldset.append(th)
|
||||
} else {
|
||||
const charCode = (i - 1) * 16 + j + 31
|
||||
|
||||
const td = document.createElement("td")
|
||||
td.id = `td_${charCode}`
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.id = `char_${charCode}`
|
||||
input.name = `row_${i}`
|
||||
input.value = charCode
|
||||
// input.tabIndex = 1
|
||||
if (j == 2) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = i == 6 && j == 16 ? "" : String.fromCharCode(charCode)
|
||||
label.setAttribute("for", `char_${charCode}`)
|
||||
label.dataset.edit = "true"
|
||||
div.append(input, label)
|
||||
td.append(div)
|
||||
fieldset.append(td)
|
||||
}
|
||||
}
|
||||
table.append(tr)
|
||||
}
|
||||
const td = document.createElement("td")
|
||||
td.id = `td_${charCode}`
|
||||
const div = document.createElement("div")
|
||||
const input = document.createElement("input")
|
||||
input.type = "radio"
|
||||
input.id = `char_${charCode}`
|
||||
input.name = `row_${i}`
|
||||
input.value = charCode
|
||||
// input.tabIndex = 1
|
||||
if (j == 2) input.setAttribute("checked", "true")
|
||||
const label = document.createElement("label")
|
||||
label.textContent = i == 6 && j == 16 ? "" : String.fromCharCode(charCode)
|
||||
label.setAttribute("for", `char_${charCode}`)
|
||||
label.dataset.edit = "true"
|
||||
div.append(input, label)
|
||||
td.append(div)
|
||||
fieldset.append(td)
|
||||
}
|
||||
}
|
||||
table.append(tr)
|
||||
}
|
||||
}
|
||||
const createBinaryString = (number, length) => parseInt(number, 10).toString(2).padStart(length, "0")
|
||||
createTable()
|
||||
|
||||
let previousOutput = [33, 49, 65, 81, 97, 113]
|
||||
function updateTable(event, form) {
|
||||
const data = new FormData(form)
|
||||
let output = []
|
||||
for (const entry of data) output.push(+entry[1])
|
||||
let indexOfChange = 0
|
||||
let offset = 0
|
||||
output.forEach((row, index) => (row != previousOutput[index] ? (indexOfChange = index) : null))
|
||||
output.forEach((row, index) => (index == indexOfChange ? (offset = row - previousOutput[index]) : null))
|
||||
output.forEach((row, index) => {
|
||||
if (index != indexOfChange) {
|
||||
document.forms["table_form"][`char_${row + offset}`].checked = true
|
||||
output[index] += offset
|
||||
}
|
||||
})
|
||||
previousOutput = [...output]
|
||||
event.preventDefault()
|
||||
const data = new FormData(form)
|
||||
let output = []
|
||||
for (const entry of data) output.push(+entry[1])
|
||||
let indexOfChange = 0
|
||||
let offset = 0
|
||||
output.forEach((row, index) => (row != previousOutput[index] ? (indexOfChange = index) : null))
|
||||
output.forEach((row, index) => (index == indexOfChange ? (offset = row - previousOutput[index]) : null))
|
||||
output.forEach((row, index) => {
|
||||
if (index != indexOfChange) {
|
||||
document.forms["table_form"][`char_${row + offset}`].checked = true
|
||||
output[index] += offset
|
||||
}
|
||||
})
|
||||
previousOutput = [...output]
|
||||
event.preventDefault()
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// takes a string and returns a string, where the first letter is uppercase
|
||||
function capitalize(string) {
|
||||
const stringArray = string.split("")
|
||||
return stringArray.shift().toUpperCase() + stringArray.join("")
|
||||
const stringArray = string.split("")
|
||||
return stringArray.shift().toUpperCase() + stringArray.join("")
|
||||
}
|
||||
|
||||
const mapRange = (value, x1, y1, x2, y2) => ((value - x1) * (y2 - x2)) / (y1 - x1) + x2
|
||||
@ -10,44 +10,44 @@ const getCssVar = (property) => getComputedStyle(document.documentElement).getPr
|
||||
const setCssVar = ([property, value]) => document.documentElement.style.setProperty(property, value)
|
||||
|
||||
const isMobileTest = () => {
|
||||
if (window.matchMedia("(pointer: coarse) and (max-width: 1000px").matches) {
|
||||
console.log("(pointer: coarse) and (max-width: 1000px)")
|
||||
return true
|
||||
} else return false
|
||||
if (window.matchMedia("(pointer: coarse) and (max-width: 1000px").matches) {
|
||||
console.log("(pointer: coarse) and (max-width: 1000px)")
|
||||
return true
|
||||
} else return false
|
||||
}
|
||||
|
||||
const mobileMediaQuery = "(pointer: coarse) and (max-width: 1000px)"
|
||||
const mql = window.matchMedia(mobileMediaQuery)
|
||||
let isMobile = mql.matches
|
||||
mql.addEventListener("change", (e) => {
|
||||
isMobile = e.matches
|
||||
changedFocus(true)
|
||||
isMobile = e.matches
|
||||
changedFocus(true)
|
||||
})
|
||||
|
||||
function wait(milliseconds) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, milliseconds)
|
||||
})
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, milliseconds)
|
||||
})
|
||||
}
|
||||
|
||||
function appendStyleSheets() {
|
||||
const stylesheetIndexes = [
|
||||
"non_essential",
|
||||
"section_2",
|
||||
"section_3",
|
||||
"section_4",
|
||||
"section_5",
|
||||
"section_6",
|
||||
"section_7",
|
||||
"section_8",
|
||||
"section_9",
|
||||
]
|
||||
const head = document.querySelector("head")
|
||||
stylesheetIndexes.forEach((stylesheet) => {
|
||||
const link = document.createElement("link")
|
||||
link.setAttribute("rel", "stylesheet")
|
||||
link.setAttribute("href", `src/css/${stylesheet}.css`)
|
||||
head.append(link)
|
||||
})
|
||||
const stylesheetIndexes = [
|
||||
"non_essential",
|
||||
"section_2",
|
||||
"section_3",
|
||||
"section_4",
|
||||
"section_5",
|
||||
"section_6",
|
||||
"section_7",
|
||||
"section_8",
|
||||
"section_9",
|
||||
]
|
||||
const head = document.querySelector("head")
|
||||
stylesheetIndexes.forEach((stylesheet) => {
|
||||
const link = document.createElement("link")
|
||||
link.setAttribute("rel", "stylesheet")
|
||||
link.setAttribute("href", `src/css/${stylesheet}.css`)
|
||||
head.append(link)
|
||||
})
|
||||
}
|
||||
appendStyleSheets()
|
||||
|
File diff suppressed because one or more lines are too long
164
tables.html
164
tables.html
@ -1,90 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>School timetable</title>
|
||||
<style>
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>School timetable</title>
|
||||
<style>
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: 0.125rem solid rgb(200, 200, 200);
|
||||
letter-spacing: 0.0625rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: 0.125rem solid rgb(200, 200, 200);
|
||||
letter-spacing: 0.0625rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
border: 0.0625rem solid rgb(190, 190, 190);
|
||||
padding: 10px 20px;
|
||||
}
|
||||
td,
|
||||
th {
|
||||
border: 0.0625rem solid rgb(190, 190, 190);
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: center;
|
||||
}
|
||||
td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>School timetable</h1>
|
||||
caption {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>School timetable</h1>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<th>Mon</th>
|
||||
<th>Tues</th>
|
||||
<th>Wed</th>
|
||||
<th>Thurs</th>
|
||||
<th>Fri</th>
|
||||
<th>Sat</th>
|
||||
<th>Sun</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>1st period</th>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>2nd period</th>
|
||||
<td>English</td>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>3rd period</th>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>4th period</th>
|
||||
<td> </td>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td>English</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
<table>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<th>Mon</th>
|
||||
<th>Tues</th>
|
||||
<th>Wed</th>
|
||||
<th>Thurs</th>
|
||||
<th>Fri</th>
|
||||
<th>Sat</th>
|
||||
<th>Sun</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>1st period</th>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>2nd period</th>
|
||||
<td>English</td>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>3rd period</th>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td> </td>
|
||||
<td>German</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>4th period</th>
|
||||
<td> </td>
|
||||
<td>English</td>
|
||||
<td> </td>
|
||||
<td>English</td>
|
||||
<td>Dutch</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user