A modern, secure, and feature-rich calculator application built with vanilla JavaScript. Features a custom Shunting-yard algorithm for safe expression evaluation, calculation history, memory functions, and a beautiful dark theme with smooth animations.
- Secure Calculation Engine: Uses a custom Shunting-yard algorithm parser instead of
eval(), ensuring secure and accurate processing of mathematical expressions - Negative Numbers: Toggle the sign of the current value with the
±button, with full unary minus support in expressions (e.g.-5 + 3) - Percentage Operations: Context-aware
%key that is relative for addition and subtraction (100 + 10 % = 110) and divides by 100 for multiplication, division, and standalone values - Calculation History: View past calculations in a slide-out panel, click to reuse results, persisted in localStorage
- Memory Functions: Full memory support with MC (Clear), MR (Recall), M+ (Add), and M- (Subtract) operations
- Ripple Animations: Beautiful Material Design-inspired ripple effect on button press
- Sound Effects: Satisfying click sounds generated with Web Audio API (toggleable)
- Haptic Feedback: Vibration feedback on mobile devices for tactile response
- Swipe Gestures: Swipe left on display to delete, swipe right on history panel to close
- Full Keyboard Support: Complete keyboard navigation for desktop users
- Accessibility (a11y): ARIA labels on every control and keyboard-operable history entries (focusable with Enter and Space)
- Responsive Design: Optimized layout for both mobile and desktop devices
- Modern Dark Theme: Eye-friendly dark interface with gradient backgrounds and smooth transitions
- HTML5: Semantic markup with ARIA labels for accessibility
- CSS3: Modern styling with CSS Variables, Flexbox, Grid, and custom animations
- Vanilla JavaScript (ES6+): Object-Oriented architecture with custom tokenizer and RPN evaluator
- Web Audio API: Dynamic sound effect generation without external audio files
- LocalStorage API: Persistent storage for calculation history and user preferences
- Vibration API: Native haptic feedback for mobile devices
- Clone the repository
git clone https://github.com/Serkanbyx/basic-calculator.git- Navigate to the project directory
cd basic-calculator- Run the application
You can open the index.html file directly in your browser, or use a local server:
Using Python:
python -m http.server 3000Using Node.js:
npx serveUsing VS Code:
- Install "Live Server" extension
- Right-click on
index.html→ "Open with Live Server"
- Open in browser
Navigate to http://localhost:3000 (or the port shown in your terminal)
- Basic Calculations: Click number buttons or use keyboard (0-9) to enter numbers
- Operations: Use +, -, ×, ÷ buttons or keyboard operators (+, -, *, /)
- Calculate: Press = button or Enter key to see the result
- Clear: AC button or Escape key clears all input
- Delete: DEL button, Backspace key, or swipe left on display to delete last character
- Negate: Press the
±button to switch the current value between positive and negative - Percentage: Press
%(e.g.100 + 10 %gives110,200 × 50 %gives100) - View History: Click the clock icon (top-right) or swipe to open history panel
- Use Memory: MC/MR/M+/M- buttons to store and recall values
- Toggle Sound: Click the speaker icon to enable/disable click sounds
The calculator uses Dijkstra's Shunting-yard algorithm to safely parse and evaluate mathematical expressions without using JavaScript's eval() function:
// 1. Tokenize the expression
"12 + 8 * 2" → ["12", "+", "8", "*", "2"]
// 2. Convert to Reverse Polish Notation (RPN)
["12", "+", "8", "*", "2"] → [12, 8, 2, "*", "+"]
// 3. Evaluate RPN using a stack
// Stack operations: push 12, push 8, push 2, pop 2 & 8 → multiply → push 16, pop 16 & 12 → add → push 28
// Result: 28| Operator | Precedence |
|---|---|
* / |
3 (High) |
+ - |
2 (Low) |
The tokenizer distinguishes a binary subtraction from a leading negative sign. A - is treated as part of a negative number when it starts the expression or directly follows another operator:
// Binary minus stays an operator
"5 - 3" → [5, "-", 3] // = 2
// Unary minus is merged into the following number
"-5 + 3" → [-5, "+", 3] // = -2
"5 * -3" → [5, "*", -3] // = -15The % operator is context-aware. For addition and subtraction it is relative to the running total, while for multiplication, division, and standalone values it simply divides by 100:
"100 + 10 %" → 100 + (100 * 0.10) = 110
"100 - 10 %" → 100 - (100 * 0.10) = 90
"200 * 50 %" → 200 * (50 / 100) = 100
"50 %" → 50 / 100 = 0.5| Button | Function |
|---|---|
| MC | Memory Clear - Clears stored memory value |
| MR | Memory Recall - Retrieves stored value to display |
| M+ | Memory Add - Adds current display value to memory |
| M− | Memory Subtract - Subtracts current display value from memory |
| Key | Action |
|---|---|
0-9 |
Enter numbers |
. |
Decimal point |
+ - * / |
Operations |
% |
Percentage |
Enter or = |
Calculate result |
Backspace |
Delete last character |
Escape |
Clear all / Close history |
Edit the CSS variables in style.css:
:root {
--bg-color: #1a1a2e;
--calc-body-color: #16213e;
--display-bg: #0f0f23;
--btn-bg: #1f4068;
--accent-color: #e94560;
--text-color: #eaeaea;
--memory-color: #4ecca3;
}For reduced motion preferences, animations are automatically disabled:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}- ✅ Basic arithmetic operations (+, -, ×, ÷)
- ✅ Negative numbers via ± sign toggle and unary minus parsing
- ✅ Decimal number support
- ✅ Operator precedence (PEMDAS)
- ✅ Percentage calculations (context-aware for +/- and ÷ by 100 otherwise)
- ✅ Calculation history with localStorage persistence
- ✅ Memory functions (MC, MR, M+, M-)
- ✅ Keyboard support
- ✅ Responsive design
- ✅ Ripple animations
- ✅ Sound effects (Web Audio API)
- ✅ Haptic feedback (mobile)
- ✅ Swipe gestures
- ✅ Error handling (division by zero)
- Parentheses support for grouped expressions
- Scientific calculator mode (sin, cos, tan, log)
- Light/Dark theme toggle
- PWA support for offline use
- Export history to CSV
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
Contributions are welcome! Please read the Contributing Guide and the Code of Conduct before getting started, and report security issues following the Security Policy.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes using conventional commits:
feat:- New featurefix:- Bug fixdocs:- Documentation changesstyle:- Code style changesrefactor:- Code refactoring
- Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is open source and available under the MIT License.
Serkan Bayraktar
- 🌐 Website: serkanbayraktar.com
- 💻 GitHub: @Serkanbyx
- 📧 Email: serkanbyx1@gmail.com
- Dijkstra's Shunting-yard algorithm for expression parsing
- Material Design for ripple animation inspiration
- Web Audio API documentation for sound synthesis
- 🐛 Found a bug? Open an issue
- 📧 Email: serkanbyx1@gmail.com
- 🌐 Website: serkanbayraktar.com
⭐ If you like this project, don't forget to give it a star!