const buttons = document.querySelectorAll('.button'); const displayText = document.querySelector('.display-text'); let currentInput = ''; let characterSpans = []; // Array to track all spans for proper positioning let isResultDisplayed = false; // Track if the result is displayed let resultSpan; // For showing the result buttons.forEach(button => { button.addEventListener('click', () => { const value = button.textContent; if (value === 'AC') { resetCalculator(); } else if (value === '=') { calculateResult(); } else { if (isResultDisplayed) { resetCalculator(); // Reset after "=" is pressed } if (currentInput === 'Error') currentInput = ''; // Clear on error currentInput += value; appendCharacter(value); // Append with animation } }); }); function appendCharacter(char) { // Create new span element for the character const newChar = document.createElement('span'); newChar.textContent = char; displayText.appendChild(newChar); characterSpans.push(newChar); // Add the new span to the array // Move all characters smoothly updateCharacterPositions(); // Animate the new character in from the right anime({ targets: newChar, opacity: [0, 1], translateY: [0, -25], // Animating into place scale: [0, 1], duration: 500, easing: 'easeOutExpo' }); } function updateCharacterPositions() { const totalWidth = displayText.offsetWidth; // Width of the display let currentOffset = totalWidth; // Start from the rightmost edge // Loop through characters in reverse (so newest appears at the right) for (let i = characterSpans.length - 1; i >= 0; i--) { const span = characterSpans[i]; const spanWidth = span.offsetWidth; // Get the width of each character currentOffset -= spanWidth + 5; // Move left by the width of the character + some margin anime({ targets: span, right: (totalWidth - currentOffset - spanWidth) + 'px', // Keep them aligned right duration: 300, easing: 'easeOutQuint' }); } } function calculateResult() { const equation = characterSpans.map(span => span.textContent).join(''); let result; try { result = eval(equation.replace('÷', '/').replaceAll('×', '*')).toString(); } catch (error) { result = 'Error'; } characterSpans.forEach(span => { span.style.fontSize = '1.5rem'; }); const totalWidth = displayText.offsetWidth; // Width of the display let currentOffset = totalWidth; // Start from the rightmost edge // Animate the equation upwards // Loop through characters in reverse (so newest appears at the right) for (let i = characterSpans.length - 1; i >= 0; i--) { const span = characterSpans[i]; const spanWidth = span.offsetWidth; // Get the width of each character currentOffset -= spanWidth + 3; // Move left by the width of the character + some margin anime({ targets: span, translateY: -45, opacity: [1, 0.4], right: (totalWidth - currentOffset - spanWidth) + 'px', // Keep them aligned right duration: 800, easing: 'easeOutExpo' }); } resultSpan = document.createElement('span'); // Create a new span for the result resultSpan.textContent = `= ${result}`; displayText.appendChild(resultSpan); // Animate the result to appear from below anime({ targets: resultSpan, opacity: [0, 1], translateY: [50, -10], // Animating upwards translateX: -5, scale: [0, 1], duration: 500, easing: 'easeOutExpo' }); // Set a flag to reset on the next key press isResultDisplayed = true; } function clearDisplay() { // Remove all current characters (spans) characterSpans.forEach(span => span.remove()); characterSpans = []; } function resetCalculator() { currentInput = ''; characterSpans = []; displayText.innerHTML = ''; // Clear the display isResultDisplayed = false; // Reset the result display flag } function updateDisplay(value) { // Clear existing spans and reset positions displayText.innerHTML = ''; characterSpans = []; [...value].forEach(char => { appendCharacter(char); // Append each character }); }