From 31a10359f60e9bd88769016f0ccd6ecd8861d9d6 Mon Sep 17 00:00:00 2001 From: Philipp Zelinski Date: Wed, 4 May 2022 23:03:59 +0200 Subject: [PATCH 1/4] Add code comments --- CHANGELOG.md | 1 + public/js/general.js | 40 ++++++++++++++++++++++++++++++++++++++++ public/js/notes.js | 31 ++++++++++++++++++++++++++++++- public/js/storage.js | 23 +++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dbeea3..faf3d8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Fix version links in CHANGELOG.md - Fix refresh icon font +- Add code comments ## [0.1.4][] - 2022-05-04 diff --git a/public/js/general.js b/public/js/general.js index a4eb889..2fc6e0d 100644 --- a/public/js/general.js +++ b/public/js/general.js @@ -1,9 +1,36 @@ 'use strict'; +/** + * Alias for document.getElementById + * @param {!string} id - Element's id + * @returns {Element} + */ const getElement = (id) => document.getElementById(id); +/** + * Alias for document.createElement + * @param {string} [tag=div] - HTML tag + * @returns {Element} + */ const createElement = (tag = 'div') => document.createElement(tag); +/** + * An object that describes the basic properties + * of an HTML element to be created + * @typedef {Object} CustomElement + * @property {!string} tag - HTML-tag + * @property {!string} name - Element's identification string + * @property {string[]} [classes] - List of classes to add + * @property {Object.[]} [attributes] - List of atttributes to add + * @property {string} [parent] - The parent of the object to which the item will be added. + * name of the element, which is in the array before + */ + +/** + * Quick creation of HTML elements + * @param {CustomElement[]} data - Elements to create + * @returns {Object.} + */ const createElements = (data) => { const resultElements = {}; for (const { tag, classes, attributes, name, parent } of data) { @@ -19,12 +46,25 @@ const createElements = (data) => { return resultElements; }; +/** + * Finds data by the path (eg. "path.to.string") + * @param {Object} object - Object, to search in + * @param {string} path - Path (eg. "path.to.string") + * @returns {any} - Data that are by the path stored + */ const resolvePath = (object, path) => { const steps = path.split('.'); for (const step of steps) object = object[step]; return object; }; +/** + * Updates value in object by the path (eg. "path.to.string") + * @param {Object} object - Object, to search in + * @param {string} path - Path (eg. "path.to.string") + * @param {any} value - New value + * @returns {undefined} + */ const updateValueByPath = (object, path, value) => path.split('.').reduce((o, p, i) => (o[p] = path.split('.').length === ++i ? value : o[p] || {}), object); diff --git a/public/js/notes.js b/public/js/notes.js index d70d4e8..906f3f0 100644 --- a/public/js/notes.js +++ b/public/js/notes.js @@ -2,31 +2,59 @@ const NOTES_PX_OFFSET = 10; const mainNotes = { g: ['e', 5], f: ['g', 3] }; - const naturalNotes = ['c', 'd', 'e', 'f', 'g', 'a', 'h']; +/** + * @typedef {('f'|'g')} Clef + */ + +/** + * Get margin for note (px) + * @param {string!} note - Note (eg. C#4, Eb5, A2) + * @param {Clef} clef - Clef + * @returns {number} - Amount of px for element to be omit + */ const getMargin = (note, clef) => { + // Parse given note. Get natural and ocatve const [naturalNote, octave] = [note[0].toLowerCase(), +note[note.length - 1]]; const naturalNoteIndex = naturalNotes.findIndex((n) => n === naturalNote); + // The main note is the one between the first and second line (top: 0px) + // Parse its natural value and octave const [mainNote, mainOctave] = mainNotes[clef]; const mainNoteIndex = naturalNotes.findIndex((n) => n === mainNote); + // If the note is in the same octave as the main note, + // return the index difference if (mainOctave === octave) { const result = (mainNoteIndex - naturalNoteIndex) * NOTES_PX_OFFSET; + // If the note equals the main note and the result is 0, then return 1. + // This is because the distance between the lines is 19px + // and there is a 1px hole, when we use top: 0px; return result === 0 ? 1 : result; } + // Count the number of notes that are between the note and the main one const octaveAmount = Math.abs(mainOctave - octave); const notesAmount = octaveAmount * naturalNotes.length; return (notesAmount - naturalNoteIndex + mainNoteIndex) * NOTES_PX_OFFSET; }; +/** + * Creates an element with stave, specified clef and notes + * @param {string!} containerId - Id of an element, to append stave in + * @param {Object} task - Task object + * @param {Clef} task.clef - Clef + * @param {string[]} task.notes - Notes + */ const createStave = (containerId, { clef, notes }) => { + // Check the container const container = window.getElement(containerId); if (!container) throw new Error('Element not found'); + // Create array of custom elements for quick creation const elementsToCreate = [ { name: 'stave', classes: ['stave'] }, { name: 'clefElement', classes: ['clef', clef], parent: 'stave' }, { name: 'notesContainer', classes: ['notes'], parent: 'stave' }, ]; + // Add every note to stave for (const [i, note] of Object.entries(notes)) { const margin = getMargin(note, clef); elementsToCreate.push({ @@ -36,6 +64,7 @@ const createStave = (containerId, { clef, notes }) => { parent: 'notesContainer', }); } + // Append stave into container const { stave } = window.createElements(elementsToCreate); container.appendChild(stave); }; diff --git a/public/js/storage.js b/public/js/storage.js index 0e6e013..246d02a 100644 --- a/public/js/storage.js +++ b/public/js/storage.js @@ -1,5 +1,12 @@ 'use strict'; +/** + * Gets JSON from local storage and parses it + * @param {string!} key - Key + * @param {boolean} [deleteOnError=true] - Whether to delete the current value of an element + * if an error occurred while parsing it + * @returns {Object} + */ const getLocalStorageItem = (key, deleteOnError = true) => { try { const raw = window.localStorage.getItem(key); @@ -12,6 +19,13 @@ const getLocalStorageItem = (key, deleteOnError = true) => { } }; +/** + * Set the new value of the item in local storage. + * The data passes the stringify + * @param {string!} key - Key + * @param {Object} data - JSON data to store + * @returns {boolean} - Whether or not it's successful + */ const setLocalStorageItem = (key, data) => { try { const stringifiedData = JSON.stringify(data); @@ -23,7 +37,16 @@ const setLocalStorageItem = (key, data) => { } }; +/** + * Alias for getLocalStorageItem('settings') + * @returns {Settings} + */ const getSettings = () => getLocalStorageItem('settings'); +/** + * Alias for setLocalStorageItem('settings', newData); + * @param {Settings} [newData=window.gameSettings] - New settings object + * @returns {boolean} - Whether or not it's successful + */ const updateSettings = (newData = window.gameSettings) => setLocalStorageItem('settings', newData); const getState = () => getLocalStorageItem('state'); From 9a9dae95b590057bf37bbb41e8e56bd4e5f54127 Mon Sep 17 00:00:00 2001 From: Philipp Zelinski Date: Wed, 4 May 2022 23:04:34 +0200 Subject: [PATCH 2/4] Return always boolean in `setLocalStorageItem()` --- CHANGELOG.md | 1 + public/js/storage.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index faf3d8b..cf677b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix version links in CHANGELOG.md - Fix refresh icon font - Add code comments +- Return always boolean in `setLocalStorageItem()` ## [0.1.4][] - 2022-05-04 diff --git a/public/js/storage.js b/public/js/storage.js index 246d02a..34494cb 100644 --- a/public/js/storage.js +++ b/public/js/storage.js @@ -33,7 +33,7 @@ const setLocalStorageItem = (key, data) => { return true; } catch (err) { console.error(err); - return null; + return false; } }; From 8d8fa4804bef59e293c95ad9096fedfe72023e70 Mon Sep 17 00:00:00 2001 From: Philipp Zelinski Date: Thu, 5 May 2022 22:36:33 +0200 Subject: [PATCH 3/4] Support d2, a5 lines on notes stave --- public/css/notes.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/public/css/notes.css b/public/css/notes.css index edb1167..65e3d96 100644 --- a/public/css/notes.css +++ b/public/css/notes.css @@ -47,7 +47,8 @@ .note[data-content='c4']::after, .note[data-content='h3']::after, .note[data-content='e2']::after, -.note[data-content='d2']::after { +.note[data-content='d2']::after, +.note[data-content='a5']::after { content: ''; position: absolute; background: #0f172a; @@ -57,6 +58,7 @@ } .note[data-content='c4']::after, -.note[data-content='e2']::after { +.note[data-content='e2']::after, +.note[data-content='a5']::after { top: 50%; } From 34b7b21ae41d78f82be015eaa7acc0b9a6486896 Mon Sep 17 00:00:00 2001 From: Philipp Zelinski Date: Fri, 27 May 2022 23:43:56 +0200 Subject: [PATCH 4/4] Import generation.js to game.html --- public/game.html | 1 + 1 file changed, 1 insertion(+) diff --git a/public/game.html b/public/game.html index 12d75c4..88d3b77 100644 --- a/public/game.html +++ b/public/game.html @@ -105,6 +105,7 @@ +