#controllers/index.py import config from bottle import Bottle, template, static_file from models import lesson, practice class Index(Bottle): def __init__(self): super().__init__() self.route('/static/images/<filename>', callback=self.loadImage) self.route('/static/styles/<filename>', callback=self.loadStyle) self.route('/static/scripts/<filename>', callback=self.loadScript) self.route('/static/fonts/<filename>', callback=self.loadFont) self.route('/static/sounds/<filename>', callback=self.loadSound) self.route('/', callback=self.index) self.route('/lesson/<id:int>', callback=self.lesson) self.route('/practice/<id:int>', callback=self.practice) def loadImage(self, filename): return static_file(filename, root='./public/images') def loadStyle(self, filename): return static_file(filename, root='./public/css') def loadScript(self, filename): return static_file(filename, root='./public/js') def loadFont(self, filename): return static_file(filename, root='./public/fonts') def loadSound(self, filename): return static_file(filename, root='./public/sounds') def index(self): config.kdict['blogTitle'] = "រៀនវាយអក្សរខ្មែរ" config.kdict['lesson'] = lesson.lesson1 return template('index', data=config.kdict) def lesson(self, id): config.kdict['blogTitle'] = 'មេរៀនទី '+config.kdict['KhmerNumber'][id] config.kdict['lesson'] = lesson.__dict__['lesson'+str(id)] return template('lesson', data=config.kdict) def practice(self, id): config.kdict['blogTitle'] = 'លំហាត់ទី '+config.kdict['KhmerNumber'][id] config.kdict['practice'] = practice.__dict__['practice'+str(id)] return template('practice', data=config.kdict)
//public/js/practice.js class Typing{ constructor(practice){ this.letters = practice; this.counter = Math.floor(Math.random() * (this.letters).length); this.usedCounter = this.counter; this.nextKey = this.letters[this.counter][0]; this.mistake = 0; this.scoreLetter = 0; this.setClock(); this.setColor(this.nextKey); } setColor(nextKey){ var keys = $(".keyboard-base").children(); for(var index in keys){ if(keys[index].innerHTML == nextKey){ keys[index].focus(); $(keys[index]).css({'color':'teal'}); } if(this.pressedKey && (keys[index].innerHTML == this.pressedKey)){ $(keys[index]).css({'color':'black'}); } } $('#letter').html(this.letters[this.counter][2]); } checkKey(key){ if(key == this.nextKey){ this.scoreLetter += 1; while(true){ this.counter = Math.floor(Math.random() * (this.letters).length); if(this.counter != this.usedCounter){ this.usedCounter = this.counter break; } } this.pressedKey = this.nextKey; this.nextKey = this.letters[this.counter][0]; this.setColor(this.nextKey); }else{ document.getElementById('beep').play(); $('#mistake span').html(this.toKhNum(++this.mistake)); } } toKhNum(number){ const khNum = {'0':'០', '1':'១', '2':'២', '3':'៣', '4':'៤', '5':'៥', '6':'៦', '7':'៧', '8':'៨', '9':'៩'}; var stringNum = number.toString(); var khNumString = ''; for(var i in stringNum){ var char = stringNum.charAt(i); khNumString += khNum[char]; } return khNumString; } setClock(){ var second = 0; var minute = 0; var hour = 0; var minuteTest = 0 setInterval(() => { $('#timelapse .second').html(this.toKhNum(++second)); if(second == 60){ second = 0; $('#timelapse .minute').html(this.toKhNum(++minute)); } if(minute == 60){ minute = 0; ++minuteTest; $('#timelapse .hour').html(this.toKhNum(++hour)); } if((minuteTest <= 3) && (this.scoreLetter >= 720) && (this.mistake == 0)) alert('សូមអបអរសាទដោយអ្នកបានឆ្លងផុតកំរឹតនេះហើយ!!'); }, 1000); } }//end of class
GitHub: https://khmerweb-typing.herokuapp.com
Heroku: https://khmerweb-typing.herokuapp.com/