|
| 1 | +var canvas, ctx; |
| 2 | +var lastX, lastY, mouseDown = 0; |
| 3 | +var touchX, touchY; |
| 4 | +let model; |
| 5 | + |
| 6 | +// Initialize canvas and set up event listeners for mouse and touch interactions |
| 7 | +function init() { |
| 8 | + canvas = document.getElementById("sketchpad"); |
| 9 | + ctx = canvas.getContext("2d"); |
| 10 | + ctx.fillStyle = "black"; |
| 11 | + ctx.fillRect(0, 0, canvas.width, canvas.height); |
| 12 | + |
| 13 | + if (ctx) { |
| 14 | + // Mouse event listeners for desktop |
| 15 | + canvas.addEventListener("mousedown", sketchpad_mouseDown, false); |
| 16 | + canvas.addEventListener("mousemove", sketchpad_mouseMove, false); |
| 17 | + window.addEventListener("mouseup", sketchpad_mouseUp, false); |
| 18 | + |
| 19 | + // Touch event listeners for mobile |
| 20 | + canvas.addEventListener("touchstart", sketchpad_touchStart, false); |
| 21 | + canvas.addEventListener("touchmove", sketchpad_touchMove, false); |
| 22 | + window.addEventListener("touchend", sketchpad_touchEnd, false); |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +// Drawing function for canvas |
| 27 | +function draw(ctx, x, y, isDown) { |
| 28 | + if (isDown) { |
| 29 | + ctx.beginPath(); |
| 30 | + ctx.strokeStyle = "white"; |
| 31 | + ctx.lineWidth = 15; |
| 32 | + ctx.lineJoin = ctx.lineCap = "round"; |
| 33 | + ctx.moveTo(lastX, lastY); |
| 34 | + ctx.lineTo(x, y); |
| 35 | + ctx.stroke(); |
| 36 | + } |
| 37 | + lastX = x; |
| 38 | + lastY = y; |
| 39 | +} |
| 40 | + |
| 41 | +// Mouse event handlers |
| 42 | +function sketchpad_mouseDown(e) { |
| 43 | + mouseDown = 1; |
| 44 | + getMousePos(e); |
| 45 | + draw(ctx, mouseX, mouseY, false); |
| 46 | +} |
| 47 | + |
| 48 | +function sketchpad_mouseUp() { |
| 49 | + mouseDown = 0; |
| 50 | +} |
| 51 | + |
| 52 | +function sketchpad_mouseMove(e) { |
| 53 | + getMousePos(e); |
| 54 | + if (mouseDown) draw(ctx, mouseX, mouseY, true); |
| 55 | +} |
| 56 | + |
| 57 | +// Get mouse position relative to canvas |
| 58 | +function getMousePos(e) { |
| 59 | + var rect = canvas.getBoundingClientRect(); |
| 60 | + mouseX = e.clientX - rect.left; |
| 61 | + mouseY = e.clientY - rect.top; |
| 62 | +} |
| 63 | + |
| 64 | +// Touch event handlers for mobile |
| 65 | +function sketchpad_touchStart(e) { |
| 66 | + mouseDown = 1; |
| 67 | + getTouchPos(e); |
| 68 | + draw(ctx, touchX, touchY, false); |
| 69 | + e.preventDefault(); |
| 70 | +} |
| 71 | + |
| 72 | +function sketchpad_touchMove(e) { |
| 73 | + getTouchPos(e); |
| 74 | + if (mouseDown) draw(ctx, touchX, touchY, true); |
| 75 | + e.preventDefault(); |
| 76 | +} |
| 77 | + |
| 78 | +function sketchpad_touchEnd() { |
| 79 | + mouseDown = 0; |
| 80 | +} |
| 81 | + |
| 82 | +// Get touch position relative to canvas |
| 83 | +function getTouchPos(e) { |
| 84 | + var rect = canvas.getBoundingClientRect(); |
| 85 | + touchX = e.touches[0].clientX - rect.left; |
| 86 | + touchY = e.touches[0].clientY - rect.top; |
| 87 | +} |
| 88 | + |
| 89 | +// Clear canvas |
| 90 | +document.getElementById("clear_button").addEventListener("click", function () { |
| 91 | + ctx.clearRect(0, 0, canvas.width, canvas.height); |
| 92 | + ctx.fillStyle = "black"; |
| 93 | + ctx.fillRect(0, 0, canvas.width, canvas.height); |
| 94 | +}); |
| 95 | + |
| 96 | +// Load the model |
| 97 | +(async function () { |
| 98 | + model = await tf.loadLayersModel("https://maneprajakta.github.io/Digit_Recognition_Web_App/models/model.json"); |
| 99 | +})(); |
| 100 | + |
| 101 | +// Preprocess the canvas image for model input |
| 102 | +function preprocessCanvas(image) { |
| 103 | + let tensor = tf.browser |
| 104 | + .fromPixels(image) |
| 105 | + .resizeNearestNeighbor([28, 28]) |
| 106 | + .mean(2) |
| 107 | + .expandDims(2) |
| 108 | + .expandDims() |
| 109 | + .toFloat(); |
| 110 | + return tensor.div(255.0); |
| 111 | +} |
| 112 | + |
| 113 | +// Predict digit on "Predict" button click |
| 114 | +document.getElementById("predict_button").addEventListener("click", async function () { |
| 115 | + let tensor = preprocessCanvas(canvas); |
| 116 | + let predictions = await model.predict(tensor).data(); |
| 117 | + displayLabel(predictions); |
| 118 | +}); |
| 119 | + |
| 120 | +// Display prediction results |
| 121 | +function displayLabel(data) { |
| 122 | + var max = data[0]; |
| 123 | + var maxIndex = 0; |
| 124 | + for (var i = 1; i < data.length; i++) { |
| 125 | + if (data[i] > max) { |
| 126 | + maxIndex = i; |
| 127 | + max = data[i]; |
| 128 | + } |
| 129 | + } |
| 130 | + document.getElementById("result").innerHTML = maxIndex; |
| 131 | + document.getElementById("confidence").innerHTML = "Confidence: " + (max * 100).toFixed(2) + "%"; |
| 132 | +} |
0 commit comments