This App Will Guess The Letter You draw using Machine Learning
A Pen by abhishek chaudhary on CodePen.
This App Will Guess The Letter You draw using Machine Learning
A Pen by abhishek chaudhary on CodePen.
<!doctype html> | |
<html lang="en"> | |
<head> | |
<title>Guess The Letter</title> | |
<meta charset="utf-8" /> | |
<link rel="canonical" href="/character"> | |
<meta name="keywords" content="TheAbbie, Abhishek chaudhary, FCRIT, Fr conceicao rodrigues institute of technology"> | |
<meta property="og:locale" content="en_US" /> | |
<link rel="manifest" href="/manifest.json"> | |
<link rel="shortcut icon" type="image/x-icon" href="https://theabbie.github.io/files/logo.png"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<meta name="mobile-web-app-capable" content="yes"> | |
<meta name="description" content="This App Will Guess The Letter You draw using Machine Learning" /> | |
<meta property="og:type" content="website"> | |
<meta property="og:title" content="Guess The Letter"> | |
<meta property="og:description" content="This App Will Guess The Letter You draw using Machine Learning"> | |
<meta property="og:image" content="https://theabbie.github.io/blog/assets/share.jpg"> | |
<meta property="og:url" content="https://theabbie.github.io"> | |
<meta property="twitter:url" content="https://theabbie.github.io/"> | |
<meta name="twitter:title" content="Guess The Letter"> | |
<meta name="twitter:description" content="This App Will Guess The Letter You draw using Machine Learning"> | |
<meta name="twitter:image" content="https://theabbie.github.io/blog/assets/share.jpg"> | |
<meta name="twitter:card" content="summary_large_image"> | |
<link rel="apple-touch-icon" sizes="180x180" href="/files/favicons/apple-touch-icon.png"> | |
<link rel="icon" type="image/png" sizes="32x32" href="/files/favicons/favicon-32x32.png"> | |
<link rel="icon" type="image/png" sizes="194x194" href="/files/favicons/favicon-194x194.png"> | |
<link rel="icon" type="image/png" sizes="192x192" href="/files/favicons/android-chrome-192x192.png"> | |
<link rel="icon" type="image/png" sizes="16x16" href="/files/favicons/favicon-16x16.png"> | |
<link rel="mask-icon" href="/files/favicons/safari-pinned-tab.svg" color="#000000"> | |
<link rel="shortcut icon" href="/files/favicons/favicon.ico"> | |
<meta name="msapplication-TileColor" content="#000000"> | |
<meta name="msapplication-TileImage" content="/files/favicons/mstile-144x144.png"> | |
<meta name="msapplication-config" content="/files/favicons/browserconfig.xml"> | |
<meta name="theme-color" content="#ffffff"> | |
<style> | |
@font-face { | |
font-family: 'Martel Sans'; | |
font-style: normal; | |
font-weight: 400; | |
font-display: swap; | |
src: local('Martel Sans Regular'), local('MartelSans-Regular'), url(https://fonts.gstatic.com/s/martelsans/v6/h0GsssGi7VdzDgKjM-4d8hjYx-4.woff2) format('woff2'); | |
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; | |
} | |
* { | |
font-family: 'Martel Sans', sans-serif; | |
font-size: 15px; | |
letter-spacing: 6px; | |
word-spacing: 12px; | |
line-height: 125%; | |
} | |
body { | |
margin: 0px; | |
padding: 20px; | |
} | |
*:focus { | |
outline: none; | |
} | |
h1, | |
h2, | |
h3 { | |
display: block; | |
padding: 15px; | |
font-weight: bolder; | |
font-size: 30px; | |
margin: 0px; | |
} | |
h2 { | |
margin-left: 10px; | |
} | |
h3 { | |
margin-left: 20px; | |
} | |
svg { | |
width: 100%; | |
max-width: 600px; | |
margin: auto; | |
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); | |
border: none; | |
border-radius: 18px; | |
display: block; | |
touch-action: none; | |
} | |
rect { | |
fill:transparent; | |
stroke:rgb(50,50,50); | |
stroke-width:0.5; | |
opacity:1; | |
} | |
polyline { | |
stroke: rgb(0,0,0); | |
stroke-width: 5px; | |
fill: none; | |
} | |
.controls { | |
margin: 30px 7px 30px 15px; | |
} | |
button { | |
display: inline-block; | |
border: none; | |
padding: 8px 12px 8px 12px; | |
background: purple; | |
color: white; | |
font-weight: bolder; | |
font-size: 24px; | |
margin: 6px; | |
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); | |
border-radius: 8px; | |
transition: 0.25s; | |
} | |
button:active { | |
padding: 10px; | |
} | |
.message { | |
background: rgb(50,50,50); | |
color: white; | |
font-size: 18px; | |
letter-spacing: 4px; | |
word-spacing: 9px; | |
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); | |
padding: 15px 15px 15px 15px; | |
display: block; | |
position: fixed; | |
z-index: 2; | |
bottom: -50px; | |
transition: 0.3s; | |
width: 100%; | |
margin-left: -20px; | |
} | |
</style> | |
<script src="https://cdn.jsdelivr.net/npm/mathjs@6.0.4/dist/math.min.js"></script> | |
<script src="https://www.gstatic.com/firebasejs/7.3.0/firebase-app.js"></script> | |
<script src="https://www.gstatic.com/firebasejs/7.4.0/firebase-database.js"></script> | |
<script> | |
var firebaseConfig = { | |
apiKey: "AIzaSyBECQksrlWkWOTP4jriMmA9thfcKgbHyuE", | |
authDomain: "codrcrew.firebaseapp.com", | |
databaseURL: "https://codrcrew.firebaseio.com", | |
projectId: "codrcrew", | |
storageBucket: "codrcrew.appspot.com", | |
messagingSenderId: "517463115484", | |
appId: "1:517463115484:web:93ce55f61c78b015371619" | |
}; | |
firebase.initializeApp(firebaseConfig); | |
</script> | |
<script> | |
function loader(data) { | |
window.ldata = Object.values(data); | |
} | |
</script> | |
<script src="https://codrcrew.firebaseio.com/main/letters.json?callback=loader"> | |
<script type="application/ld+json"> | |
{ | |
"@context": "http://schema.org", | |
"@type": "WebPage", | |
"name": "Guess The Letter", | |
"description": "This App Will Guess The Letter You draw using Machine Learning", | |
"publisher": { | |
"@type": "ProfilePage", | |
"name": "TheAbbie" | |
} | |
} | |
</script> | |
</head> | |
<body> | |
<h1>Guess The Letter</h1> | |
<svg> | |
<rect /> | |
</svg> | |
<button class="done" style="display: block; margin: 30px auto 30px auto;">DONE</button> | |
<button onclick="location.reload()" style="margin-left: 21px;">↻</button> | |
<div class="controls"> | |
<button onclick="train('a')" id="small_a">a</button> | |
<button onclick="train('A')" id="capital_A">A</button> | |
<button onclick="train('b')" id="small_b">b</button> | |
<button onclick="train('B')" id="capital_B">B</button> | |
<button onclick="train('c')" id="small_c">c</button> | |
<button onclick="train('C')" id="capital_C">C</button> | |
<button onclick="train('d')" id="small_d">d</button> | |
<button onclick="train('D')" id="capital_D">D</button> | |
<button onclick="train('e')" id="small_e">e</button> | |
<button onclick="train('E')" id="capital_E">E</button> | |
<button onclick="train('f')" id="small_f">f</button> | |
<button onclick="train('F')" id="capital_F">F</button> | |
<button onclick="train('g')" id="small_g">g</button> | |
<button onclick="train('G')" id="capital_G">G</button> | |
<button onclick="train('h')" id="small_h">h</button> | |
<button onclick="train('H')" id="capital_H">H</button> | |
<button onclick="train('i')" id="small_i">i</button> | |
<button onclick="train('I')" id="capital_I">I</button> | |
<button onclick="train('j')" id="small_j">j</button> | |
<button onclick="train('J')" id="capital_J">J</button> | |
<button onclick="train('k')" id="small_k">k</button> | |
<button onclick="train('K')" id="capital_K">K</button> | |
<button onclick="train('l')" id="small_l">l</button> | |
<button onclick="train('L')" id="capital_L">L</button> | |
<button onclick="train('m')" id="small_m">m</button> | |
<button onclick="train('M')" id="capital_M">M</button> | |
<button onclick="train('n')" id="small_n">n</button> | |
<button onclick="train('N')" id="capital_N">N</button> | |
<button onclick="train('o')" id="small_o">o</button> | |
<button onclick="train('O')" id="capital_O">O</button> | |
<button onclick="train('p')" id="small_p">p</button> | |
<button onclick="train('P')" id="capital_P">P</button> | |
<button onclick="train('q')" id="small_q">q</button> | |
<button onclick="train('Q')" id="capital_Q">Q</button> | |
<button onclick="train('r')" id="small_r">r</button> | |
<button onclick="train('R')" id="capital_R">R</button> | |
<button onclick="train('s')" id="small_s">s</button> | |
<button onclick="train('S')" id="capital_S">S</button> | |
<button onclick="train('t')" id="small_t">t</button> | |
<button onclick="train('T')" id="capital_T">T</button> | |
<button onclick="train('u')" id="small_u">u</button> | |
<button onclick="train('U')" id="capital_U">U</button> | |
<button onclick="train('v')" id="small_v">v</button> | |
<button onclick="train('V')" id="capital_V">V</button> | |
<button onclick="train('w')" id="small_w">w</button> | |
<button onclick="train('W')" id="capital_W">W</button> | |
<button onclick="train('x')" id="small_x">x</button> | |
<button onclick="train('X')" id="capital_X">X</button> | |
<button onclick="train('y')" id="small_y">y</button> | |
<button onclick="train('Y')" id="capital_Y">Y</button> | |
<button onclick="train('z')" id="small_z">z</button> | |
<button onclick="train('Z')" id="capital_Z">Z</button> | |
<button onclick="train(0)" id="number_0">0</button> | |
<button onclick="train(1)" id="number_1">1</button> | |
<button onclick="train(2)" id="number_2">2</button> | |
<button onclick="train(3)" id="number_3">3</button> | |
<button onclick="train(4)" id="number_4">4</button> | |
<button onclick="train(5)" id="number_5">5</button> | |
<button onclick="train(6)" id="number_6">6</button> | |
<button onclick="train(7)" id="number_7">7</button> | |
<button onclick="train(8)" id="number_8">8</button> | |
<button onclick="train(9)" id="number_9">9</button> | |
</div> | |
<div class="message"></div> | |
</body> | |
<script> | |
var art; | |
var data = {"x": [], "y": []}; | |
var tx,ty; | |
var plist = []; | |
var wid = window.innerWidth; | |
var hit = window.innerHeight; | |
var svg = document.querySelector("svg"); | |
var oh = window.scrollY + svg.getBoundingClientRect().top; | |
var ol = window.scrollX + svg.getBoundingClientRect().left; | |
svg.style.height = svg.clientWidth + "px"; | |
var frame = document.querySelector("rect"); | |
svg.addEventListener('touchstart', function(e) { | |
art = document.createElementNS("http://www.w3.org/2000/svg","polyline"); | |
svg.appendChild(art); | |
art.setAttribute("class", "draw"); | |
tx = e.touches[0].clientX-ol; | |
ty = e.touches[0].clientY-oh; | |
data.x.push(tx); | |
data.y.push(ty); | |
art.setAttribute("points",art.getAttribute('points')+tx+","+ty+" "); | |
},false); | |
svg.addEventListener('touchmove', function(e) { | |
tx = e.touches[0].clientX-ol; | |
ty = e.touches[0].clientY-oh; | |
data.x.push(tx); | |
data.y.push(ty); | |
art.setAttribute("points",art.getAttribute('points')+tx+","+ty+" "); | |
},false); | |
document.querySelector(".done").addEventListener('click', function(e) { | |
document.querySelector(".done").disabled = true; | |
frame.setAttribute("x",Math.min(...data.x)); | |
frame.setAttribute("y",Math.min(...data.y)); | |
frame.setAttribute("width",Math.max(...data.x)-Math.min(...data.x)); | |
frame.setAttribute("height",Math.max(...data.y)-Math.min(...data.y)); | |
plist.push([Math.floor(data.x[0]),Math.floor(data.y[0])]); | |
var peaks = Math.floor(data.x[0])+","+Math.floor(data.y[0])+" "; | |
for (i=2; i<data.x.length-3; i++) { | |
if ((data.x[i] > data.x[i-2] && data.x[i] > data.x[i+2]) || (data.x[i] < data.x[i-2] && data.x[i] < data.x[i+2]) || (data.y[i] > data.y[i-2] && data.y[i] > data.y[i+2]) || (data.y[i] < data.y[i-2] && data.y[i] < data.y[i+2])) { | |
if (Math.abs(data.x[i]-plist[plist.length-1][0])+Math.abs(data.y[i]-plist[plist.length-1][1]) >= 60) { | |
plist.push([Math.floor(data.x[i]),Math.floor(data.y[i])]); | |
peaks += Math.floor(data.x[i])+","+Math.floor(data.y[i])+" "; | |
} | |
} | |
} | |
plist.push([Math.floor(data.x[data.x.length-1]),Math.floor(data.y[data.y.length-1])]); | |
peaks += Math.floor(data.x[data.x.length-1])+","+Math.floor(data.y[data.y.length-1]); | |
document.querySelectorAll(".draw").forEach(x => {x.style.display="none";}); | |
art = document.createElementNS("http://www.w3.org/2000/svg","polyline"); | |
svg.appendChild(art); | |
art.setAttribute("points",peaks); | |
plist = plist.map(x => [Math.floor(1000*(x[0]-Math.min(...data.x))/(Math.max(...data.x)-Math.min(...data.x))),Math.floor(1000*(x[1]-Math.min(...data.y))/(Math.max(...data.y)-Math.min(...data.y)))]); | |
var guess = math.mode(ldata.sort(function(a,b) {return score(a[1],plist)-score(b[1],plist);}).map(x=>x[0]).slice(0,3)); | |
message("I think it's " + guess); | |
},false); | |
function train(x) { | |
if (plist.length > 0) { | |
firebase.database().ref("main/letters").push([x,plist]); | |
message("You Trained It "+x); | |
} | |
else { | |
message("Please click <strong>DONE</strong>"); | |
} | |
} | |
function message(x) { | |
document.querySelector(".message").innerHTML = x; | |
document.querySelector(".message").style.bottom = "0px"; | |
setTimeout(function() { | |
document.querySelector(".message").innerHTML = ""; | |
document.querySelector(".message").style.bottom = "-50px"; | |
},2000); | |
} | |
function score(x,plist) { | |
var sc = 0; | |
var small = x.length<plist.length?x:plist; | |
var big = x.length>plist.length?x:plist; | |
small.forEach(function(p1) { | |
sc += math.sum(big.sort(function(a,b) { | |
return math.sum(math.abs(math.subtract(a,p1)))-math.sum(math.abs(math.subtract(b,p1))); | |
})[0]); | |
}); | |
return sc; | |
} | |
window.onerror = function (errorMsg, url, lineNumber) { | |
message('Error: ' + errorMsg + ' Script: ' + url + ' Line: ' + lineNumber); | |
} | |
</script> | |
</html> |