forked from s3lph/matemat
131 lines
4.4 KiB
JavaScript
131 lines
4.4 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();
|
|
const svgrect = svg.getBoundingClientRect();
|
|
const trX = ev.x - svgrect.left;
|
|
const trY = ev.y - svgrect.top;
|
|
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(trX - x, 2) + Math.pow(trY - y, 2);
|
|
if (dist < minDist) {
|
|
minDist = dist;
|
|
minId = circle.id;
|
|
minx = x;
|
|
miny = y;
|
|
}
|
|
});
|
|
currentStroke = drawLine(minx, miny, trX, trY);
|
|
doneMap[minId] = 1;
|
|
enteredKey += minId;
|
|
};
|
|
|
|
svg.onmouseup = (ev) => {
|
|
endPath();
|
|
formfield.value = enteredKey;
|
|
if (keepPattern !== true) {
|
|
clearTouchkey();
|
|
}
|
|
if (formid !== null) {
|
|
form.submit();
|
|
}
|
|
};
|
|
|
|
svg.onmousemove = (ev) => {
|
|
const svgrect = svg.getBoundingClientRect();
|
|
const trX = ev.x - svgrect.left;
|
|
const trY = ev.y - svgrect.top;
|
|
if (currentStroke != null) {
|
|
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(trX - x, 2) + Math.pow(trY - 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, trX, trY);
|
|
doneMap[minId] = 1;
|
|
enteredKey += minId;
|
|
}
|
|
let line = svg.getElementById(currentStroke);
|
|
line.setAttribute('x2', trX);
|
|
line.setAttribute('y2', trY);
|
|
}
|
|
};
|
|
|
|
};
|