UNPKG

handwritten-mathematics-recogniser

Version:

Easy and abstracted way to recognise handwritten mathematics in a browser or in a web view.

121 lines (119 loc) 4.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const mouse_1 = require("./mouse"); class Drawer { constructor(selector, width, height) { if (typeof selector === 'string') { const elements = document.querySelectorAll(selector); if (!document) { throw new Error('No DOM found.'); } if (elements.length === 0) { throw new Error(`No HTMLElement found with selector ${selector}.`); } else if (elements.length > 1) { throw new Error('Selector must explicitly identify a single canvas.'); } this.feedbackCanvas = elements[0]; this.feedbackContext = this.feedbackCanvas.getContext('2d'); } else { this.feedbackCanvas = selector; this.feedbackContext = this.feedbackCanvas.getContext('2d'); } if (width) { this.feedbackCanvas.width = width; } if (height) { this.feedbackCanvas.height = height; } this.feedbackCanvas.style.cursor = 'crosshair'; this.mouse = new mouse_1.Mouse(); this.addListeners(); this.feedbackContext.globalCompositeOperation = 'source-over'; this.feedbackContext.globalAlpha = 1; this.feedbackContext.strokeStyle = 'rgba(0,0,0,1)'; this.feedbackContext.lineCap = 'round'; this.feedbackContext.lineJoin = 'round'; this.feedbackContext.lineWidth = 4; } clear() { const width = this.feedbackCanvas.width; const height = this.feedbackCanvas.height; this.feedbackContext.clearRect(-10, -10, width + 20, height + 20); } mouseDown(mousePosition) { mousePosition.preventDefault(); this.mouseMove(mousePosition); this.mouse.px = this.mouse.x; this.mouse.py = this.mouse.y; this.mouse.down = true; this.feedbackContext.beginPath(); this.feedbackContext.moveTo(this.mouse.px, this.mouse.py); } mouseMove(e) { e.preventDefault(); const rect = this.feedbackCanvas.getBoundingClientRect(); const position = e.changedTouches && e.changedTouches[0] || e; let x = position.offsetX; let y = position.offsetY; if (typeof x === 'undefined') { x = position.clientX + document.documentElement.scrollLeft - rect.left; } if (typeof y === 'undefined') { y = position.clientY + document.documentElement.scrollTop - rect.top; } if (this.mouse.down) { this.draw(x, y); } else { this.mouse.x = x; this.mouse.y = y; } } mouseUp() { this.mouse.down = false; this.feedbackContext.closePath(); } lineDistance(x1, y1, x2, y2) { const xs = Math.pow(x2 - x1, 2); const ys = Math.pow(y2 - y1, 2); return Math.sqrt(xs + ys); } draw(mX, mY) { const mouse = this.mouse; const rawDist = this.lineDistance(mX, mY, mouse.px, mouse.py); const smoothingFactor = Math.min(0.87, 0.85 + (rawDist - 60) / 3000); mouse.x = mX - (mX - mouse.px) * smoothingFactor; mouse.y = mY - (mY - mouse.py) * smoothingFactor; this.feedbackContext.quadraticCurveTo(mouse.px, mouse.py, mouse.x, mouse.y); this.feedbackContext.stroke(); mouse.px = mouse.x; mouse.py = mouse.y; } addListeners() { this.feedbackCanvas.style.msTouchAction = 'none'; this.feedbackCanvas.style.touchAction = 'none'; this.feedbackCanvas.addEventListener('mousedown', this.mouseDown.bind(this)); this.feedbackCanvas.addEventListener('touchstart', this.mouseDown.bind(this)); this.feedbackCanvas.addEventListener('mousemove', this.mouseMove.bind(this)); this.feedbackCanvas.addEventListener('touchmove', this.mouseMove.bind(this)); document.addEventListener('mouseup', this.mouseUp.bind(this)); this.feedbackCanvas.addEventListener('touchend', this.mouseUp.bind(this)); } removeListeners() { this.clear(); this.feedbackCanvas.addEventListener('mousedown', this.mouseDown.bind(this)); this.feedbackCanvas.addEventListener('touchstart', this.mouseDown.bind(this)); this.feedbackCanvas.addEventListener('mousemove', this.mouseMove.bind(this)); this.feedbackCanvas.addEventListener('touchmove', this.mouseMove.bind(this)); document.addEventListener('mouseup', this.mouseUp.bind(this)); this.feedbackCanvas.addEventListener('touchend', this.mouseUp.bind(this)); } } exports.Drawer = Drawer; //# sourceMappingURL=drawer.js.map