From 8c1a337e085d03d3881797ccc9b7b403d3c6926a Mon Sep 17 00:00:00 2001 From: h7x4 Date: Sat, 21 Nov 2020 04:12:00 +0100 Subject: [PATCH] Add filtering buttons --- index.html | 6 ++++ script.js | 104 ++++++++++++++++++++++++++++++++++++++++++++--------- style.css | 17 ++++++++- 3 files changed, 109 insertions(+), 18 deletions(-) diff --git a/index.html b/index.html index 99c08d0..e8b9942 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,12 @@ +
+ + + + +
None
diff --git a/script.js b/script.js index df740d2..c490b31 100644 --- a/script.js +++ b/script.js @@ -1,6 +1,7 @@ const responseDiv = document.getElementById("response"); const clearButton = document.getElementById("clear"); const canvas = document.getElementById("canvas"); +const toggleButtons = Array.from(document.getElementById('toggleButtons').children); const ctx = canvas.getContext('2d'); /* -------------------------------------------------------------------------- */ @@ -40,9 +41,14 @@ const sendKanjiRequest = async (strokes) => fetch(API, { .then(data => data.json()) .then(res => { if (res[0] != "SUCCESS") throw Error(res[0]); - responseDiv.innerText = res[1][0][1].join(', '); - }) - .catch(err => console.error(err)); + return res; + }); + + +const updateResponses = async (strokes) => + sendKanjiRequest(strokes) + .then(res => responseDiv.innerText = postProcess(res[1][0][1]).join(', ')) + .catch(err => console.error(err)); /* -------------------------------------------------------------------------- */ /* CANVAS */ @@ -67,8 +73,7 @@ let timerStart = 0; let x = 0; let y = 0; -/** Clear/initialize the newStroke variable after adding the current to globalStrokes */ -genNewStroke = () => { +const resetNewStroke = () => { newStroke = { 'xs': [], 'ys': [], @@ -76,7 +81,7 @@ genNewStroke = () => { }; } -genNewStroke(); +resetNewStroke(); const addPointToNewStroke = (x, y) => { newStroke.xs.push(x); @@ -90,7 +95,7 @@ const drawLine = (dx, dy) => { ctx.stroke(); } -updateStroke = (newX, newY) => { +const updateStroke = (newX, newY) => { drawLine(newX, newY); addPointToNewStroke(newX, newY); x = newX; @@ -99,7 +104,7 @@ updateStroke = (newX, newY) => { } const initStroke = (initX, initY) => { - genNewStroke(); + resetNewStroke(); timerStart = Date.now(); x = initX; y = initY; @@ -123,7 +128,7 @@ const endStroke = () => { mouseDown = false; ctx.closePath(); strokes.push([newStroke.xs, newStroke.ys, newStroke.times]); - sendKanjiRequest(strokes); + updateResponses(strokes); } const clearBoard = () => { @@ -132,11 +137,78 @@ const clearBoard = () => { responseDiv.innerHTML = 'None'; } -canvas.onmousedown = event => initStroke(event.offsetX, event.offsetY); -canvas.onmousemove = event => updateStrokeIfPrevLineIsDone(event.offsetX, event.offsetY); -canvas.onmouseup = () => endStroke(); +/* -------------------------------------------------------------------------- */ +/* POST-PROCESSING AND FILTERING */ +/* -------------------------------------------------------------------------- */ -const getOffset = (x, y) => { +const ON_COLOR = '#4d9e2a'; +const OFF_COLOR = '#fa2b2b'; + +const regexState = { + state: { + kanji: true, + hiragana: true, + katakana: true, + all: false + }, + regex: { + kanji: RegExp(/\p{Script_Extensions=Han}/u), + hiragana: RegExp(/\p{Script_Extensions=Hiragana}/u), + katakana: RegExp(/\p{Script_Extensions=Katakana}/u), + all: RegExp(/./) + } +}; + +const genCharSet = id => id.slice(6).toLowerCase(); + +const colorButton = id => { + const button = document.getElementById(id); + button.style.backgroundColor = + regexState.state[genCharSet(id)] ? ON_COLOR : OFF_COLOR; +} + +const toggleRegexState = event => { + const characterSet = genCharSet(event.target.id); + + regexState.state[characterSet] = !regexState.state[characterSet]; + colorButton(event.target.id); + if (strokes.length !== 0) updateResponses(strokes); +} + +const genCombinedRegexString = () => '^[' + + Object.keys(regexState.regex) + .filter(key => regexState.state[key]) + .map(key => regexState.regex[key].source) + .join('') + ']*$'; + +const postProcess = results => { + const regexString = regexState.state.all + ? '.*' + : genCombinedRegexString(); + + const combinedRegex = RegExp(`${regexString}`, 'u'); + return results.filter(result => combinedRegex.test(result)); +} + +/* -------------------------------------------------------------------------- */ +/* EVENT LISTENERS AND SETUP */ +/* -------------------------------------------------------------------------- */ + +// Add eventlisteners and colors to all toggle-buttons +toggleButtons + .map(button => { + button.addEventListener('click', toggleRegexState); + colorButton(button.id); + }); + + canvas.onmousedown = event => initStroke(event.offsetX, event.offsetY); + canvas.onmousemove = event => updateStrokeIfPrevLineIsDone(event.offsetX, event.offsetY); + canvas.onmouseup = () => endStroke(); + clearButton.onclick = () => clearBoard(); + +// Touch support + +const correctTouchOffset = (x, y) => { const canvasRect = canvas.getBoundingClientRect(); return [x - canvasRect.left, y - canvasRect.top]; } @@ -144,17 +216,15 @@ return [x - canvasRect.left, y - canvasRect.top]; canvas.ontouchstart = event => { event.preventDefault(); ({clientX, clientY} = event.changedTouches[0]); - [x, y] = getOffset(clientX, clientY); + [x, y] = correctTouchOffset(clientX, clientY); initStroke(x, y); } canvas.ontouchmove = event => { event.preventDefault(); ({clientX, clientY} = event.changedTouches[0]); - [x, y] = getOffset(clientX, clientY); + [x, y] = correctTouchOffset(clientX, clientY); updateStrokeIfPrevLineIsDone(x, y); } canvas.ontouchend = () => endStroke(); - -clearButton.onclick = () => clearBoard(); \ No newline at end of file diff --git a/style.css b/style.css index 8f5cf26..9131b4c 100644 --- a/style.css +++ b/style.css @@ -4,11 +4,23 @@ body { #canvas { border: solid black 2px; - border-radius: 5px; + border-radius: 10px; background-color: wheat; margin: 2em; } +#toggleButtons { + margin-bottom: 2em; +} + +#toggleButtons * { + padding: 0.2em 0.4em; + margin: 0em 0.2em; + border-radius: 10px; + color: white; + font-size: 2em; +} + #response { font-size: 2em; margin-bottom: 1em; @@ -17,4 +29,7 @@ body { #clear { font-size: 1.4em; padding: 0.5em 1em; + border-radius: 10px; + color: white; + background-color: #222222; } \ No newline at end of file