matemat/static/js/touchkey.js

127 lines
4.3 KiB
JavaScript

HTMLCollection.prototype.forEach = Array.prototype.forEach;
HTMLCollection.prototype.slice = Array.prototype.slice;
initTouchkey = (keepPattern, svgid, formid, formfieldid) => {
let svg = document.getElementById(svgid);
let form;
if (formid !== null) {
form = document.getElementById(formid);
}
let formfield = document.getElementById(formfieldid);
let currentStroke = null;
let strokeId = 0;
let doneMap = {};
let enteredKey = '';
let drawLine = (fromX, fromY, toX, toY) => {
let line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
let id = 'l-' + (strokeId++);
let idAttr = document.createAttribute('id');
let classAttr = document.createAttribute('class');
let x1attr = document.createAttribute('x1');
let y1attr = document.createAttribute('y1');
let x2attr = document.createAttribute('x2');
let y2attr = document.createAttribute('y2');
let styleAttr = document.createAttribute('style');
idAttr.value = id;
classAttr.value = 'l';
x1attr.value = fromX;
y1attr.value = fromY;
x2attr.value = toX;
y2attr.value = toY;
styleAttr.value = 'stroke: grey; stroke-width: 5%; stroke-linecap: round';
line.setAttributeNode(idAttr);
line.setAttributeNode(classAttr);
line.setAttributeNode(x1attr);
line.setAttributeNode(y1attr);
line.setAttributeNode(x2attr);
line.setAttributeNode(y2attr);
line.setAttributeNode(styleAttr);
svg.appendChild(line);
return id;
};
let endPath = () => {
svg.removeChild(svg.getElementById(currentStroke));
currentStroke = null;
};
let clearTouchkey = () => {
doneMap = {};
enteredKey = '';
svg.getElementsByClassName('l').slice().reverse().forEach((line) => {
svg.removeChild(line);
});
};
svg.onmousedown = (ev) => {
clearTouchkey();
let svgrect = svg.getBoundingClientRect();
let minId = '';
let minDist = Infinity;
let minx = 0;
let miny = 0;
doneMap = {};
document.getElementsByClassName('c').forEach((circle) => {
let x = parseFloat(circle.getAttribute('cx')) / 100.0 * svgrect.width;
let y = parseFloat(circle.getAttribute('cy')) / 100.0 * svgrect.height;
let dist = Math.pow(ev.offsetX - x, 2) + Math.pow(ev.offsetY - y, 2);
if (dist < minDist) {
minDist = dist;
minId = circle.id;
minx = x;
miny = y;
}
});
currentStroke = drawLine(minx, miny, ev.offsetX, ev.offsetY);
doneMap[minId] = 1;
enteredKey += minId;
};
svg.onmouseup = (ev) => {
endPath();
formfield.value = enteredKey;
if (keepPattern !== true) {
clearTouchkey();
}
if (formid !== null) {
form.submit();
}
};
svg.onmousemove = (ev) => {
if (currentStroke != null) {
let svgrect = svg.getBoundingClientRect();
let minId = '';
let minDist = Infinity;
let minx = 0;
let miny = 0;
document.getElementsByClassName('c').forEach((circle) => {
let x = parseFloat(circle.getAttribute('cx')) / 100.0 * svgrect.width;
let y = parseFloat(circle.getAttribute('cy')) / 100.0 * svgrect.height;
let dist = Math.pow(ev.offsetX - x, 2) + Math.pow(ev.offsetY - y, 2);
if (dist < minDist) {
minDist = dist;
minId = circle.id;
minx = x;
miny = y;
}
});
if (minDist < 2000 && !(minId in doneMap)) {
let line = svg.getElementById(currentStroke);
line.setAttribute('x2', minx);
line.setAttribute('y2', miny);
currentStroke = drawLine(minx, miny, ev.offsetX, ev.offsetY);
doneMap[minId] = 1;
enteredKey += minId;
}
let line = svg.getElementById(currentStroke);
line.setAttribute('x2', ev.offsetX);
line.setAttribute('y2', ev.offsetY);
}
};
};