├── index.html ├── script.js └── styles.css /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Calculator 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | class Calculator { 2 | constructor(previousOperandTextElement, currentOperandTextElement) { 3 | this.previousOperandTextElement = previousOperandTextElement 4 | this.currentOperandTextElement = currentOperandTextElement 5 | this.clear() 6 | } 7 | 8 | clear() { 9 | this.currentOperand = '' 10 | this.previousOperand = '' 11 | this.operation = undefined 12 | } 13 | 14 | delete() { 15 | this.currentOperand = this.currentOperand.toString().slice(0, -1) 16 | } 17 | 18 | appendNumber(number) { 19 | if (number === '.' && this.currentOperand.includes('.')) return 20 | this.currentOperand = this.currentOperand.toString() + number.toString() 21 | } 22 | 23 | chooseOperation(operation) { 24 | if (this.currentOperand === '') return 25 | if (this.previousOperand !== '') { 26 | this.compute() 27 | } 28 | this.operation = operation 29 | this.previousOperand = this.currentOperand 30 | this.currentOperand = '' 31 | } 32 | 33 | compute() { 34 | let computation 35 | const prev = parseFloat(this.previousOperand) 36 | const current = parseFloat(this.currentOperand) 37 | if (isNaN(prev) || isNaN(current)) return 38 | switch (this.operation) { 39 | case '+': 40 | computation = prev + current 41 | break 42 | case '-': 43 | computation = prev - current 44 | break 45 | case '*': 46 | computation = prev * current 47 | break 48 | case '÷': 49 | computation = prev / current 50 | break 51 | default: 52 | return 53 | } 54 | this.currentOperand = computation 55 | this.operation = undefined 56 | this.previousOperand = '' 57 | } 58 | 59 | getDisplayNumber(number) { 60 | const stringNumber = number.toString() 61 | const integerDigits = parseFloat(stringNumber.split('.')[0]) 62 | const decimalDigits = stringNumber.split('.')[1] 63 | let integerDisplay 64 | if (isNaN(integerDigits)) { 65 | integerDisplay = '' 66 | } else { 67 | integerDisplay = integerDigits.toLocaleString('en', { maximumFractionDigits: 0 }) 68 | } 69 | if (decimalDigits != null) { 70 | return `${integerDisplay}.${decimalDigits}` 71 | } else { 72 | return integerDisplay 73 | } 74 | } 75 | 76 | updateDisplay() { 77 | this.currentOperandTextElement.innerText = 78 | this.getDisplayNumber(this.currentOperand) 79 | if (this.operation != null) { 80 | this.previousOperandTextElement.innerText = 81 | `${this.getDisplayNumber(this.previousOperand)} ${this.operation}` 82 | } else { 83 | this.previousOperandTextElement.innerText = '' 84 | } 85 | } 86 | } 87 | 88 | 89 | const numberButtons = document.querySelectorAll('[data-number]') 90 | const operationButtons = document.querySelectorAll('[data-operation]') 91 | const equalsButton = document.querySelector('[data-equals]') 92 | const deleteButton = document.querySelector('[data-delete]') 93 | const allClearButton = document.querySelector('[data-all-clear]') 94 | const previousOperandTextElement = document.querySelector('[data-previous-operand]') 95 | const currentOperandTextElement = document.querySelector('[data-current-operand]') 96 | 97 | const calculator = new Calculator(previousOperandTextElement, currentOperandTextElement) 98 | 99 | numberButtons.forEach(button => { 100 | button.addEventListener('click', () => { 101 | calculator.appendNumber(button.innerText) 102 | calculator.updateDisplay() 103 | }) 104 | }) 105 | 106 | operationButtons.forEach(button => { 107 | button.addEventListener('click', () => { 108 | calculator.chooseOperation(button.innerText) 109 | calculator.updateDisplay() 110 | }) 111 | }) 112 | 113 | equalsButton.addEventListener('click', button => { 114 | calculator.compute() 115 | calculator.updateDisplay() 116 | }) 117 | 118 | allClearButton.addEventListener('click', button => { 119 | calculator.clear() 120 | calculator.updateDisplay() 121 | }) 122 | 123 | deleteButton.addEventListener('click', button => { 124 | calculator.delete() 125 | calculator.updateDisplay() 126 | }) -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | *, *::before, *::after { 2 | box-sizing: border-box; 3 | font-family: Gotham Rounded, sans-serif; 4 | font-weight: normal; 5 | } 6 | 7 | body { 8 | padding: 0; 9 | margin: 0; 10 | background: linear-gradient(to right, #00AAFF, #00FF6C); 11 | } 12 | 13 | .calculator-grid { 14 | display: grid; 15 | justify-content: center; 16 | align-content: center; 17 | min-height: 100vh; 18 | grid-template-columns: repeat(4, 100px); 19 | grid-template-rows: minmax(120px, auto) repeat(5, 100px); 20 | } 21 | 22 | .calculator-grid > button { 23 | cursor: pointer; 24 | font-size: 2rem; 25 | border: 1px solid white; 26 | outline: none; 27 | background-color: rgba(255, 255, 255, .75); 28 | } 29 | 30 | .calculator-grid > button:hover { 31 | background-color: rgba(255, 255, 255, .9); 32 | } 33 | 34 | .span-two { 35 | grid-column: span 2; 36 | } 37 | 38 | .output { 39 | grid-column: 1 / -1; 40 | background-color: rgba(0, 0, 0, .75); 41 | display: flex; 42 | align-items: flex-end; 43 | justify-content: space-around; 44 | flex-direction: column; 45 | padding: 10px; 46 | word-wrap: break-word; 47 | word-break: break-all; 48 | } 49 | 50 | .output .previous-operand { 51 | color: rgba(255, 255, 255, .75); 52 | font-size: 1.5rem; 53 | } 54 | 55 | .output .current-operand { 56 | color: white; 57 | font-size: 2.5rem; 58 | } --------------------------------------------------------------------------------