Virtual Abacus
by wio_dude
HTML
<div id="root"></div>
JavaScript
function svgElem(name) {
return document.createElementNS('http://www.w3.org/2000/svg', name);
}
const root = document.getElementById('root');
class AbacusColumn {
#high;
#low;
constructor() {
this.#high = [0];
this.#low = [0, 0, 0, 0];
}
get high() {
return this.#high;
}
get low() {
return this.#low;
}
set value(n) {
if (n < 0 || n > 9) {
throw new Error(`Value ${n} too high, must be 0-9`);
}
if (n >= 5) {
this.#high = [1];
this.#low = [0, 0, 0, 0];
for (let i = 0; i < n - 5; i++) {
this.#low[i] = 1;
}
} else {
this.#high = [0];
this.#low = [0, 0, 0, 0];
for (let i = 0; i < n; i++) {
this.#low[i] = 1;
}
}
}
get value() {
const high = this.#high[0] > 0.5 ? 1 : 0;
let low = 0;
for (let i = 0; i < 4; i++) {
if (this.#low[i] > 0.5) {
low += 1;
} else {
break;
}
}
return high * 5 + low;
}
setBead(high, index, value) {
if (high) {
this.#high[index] = value;
} else {
this.#low[index] = value;
}
}
toJSON() {
return [this.#high, this.#low];
}
}
class Abacus {
#columns;
#selectedColumnIndex;
constructor() {
this.#columns = [];
for (let i = 0; i < 16; i++) {
this.#columns.push(new AbacusColumn());
}
}
set selectedColumnIndex(n) {
this.#selectedColumnIndex = n;
}
set value(n) {
let remaining = n;
for (let i = 0; i < this.#columns.length; i++) {
const digit = remaining % 10;
this.#columns[i].value = digit;
remaining = (remaining - digit) / 10;
}
}
get value() {
let total = 0;
let magnitude = 1;
for (let i = 0; i < this.#columns.length; i++) {
total += magnitude * this.#columns[i].value;
magnitude *= 10;
}
return total;
}
setBead(column, high, bead, value) {
this.#columns[column].setBead(high, bead, value);
}
toJSON() {
return...