计算器8.2动画测试版edit icon

Fork(复制)
下载
嵌入
设置
BUG反馈
index.html
现在支持上传本地图片了!
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计算器8.2动画测试版</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        :root {
            --primary-bg: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
            --calculator-bg: rgba(255, 255, 255, 0.15);
            --display-bg: rgba(0, 0, 0, 0.3);
            --btn-bg: rgba(255, 255, 255, 0.1);
            --btn-hover: rgba(255, 255, 255, 0.25);
            --btn-active: rgba(255, 255, 255, 0.4);
            --operator-bg: rgba(255, 215, 0, 0.3);
            --operator-hover: rgba(255, 215, 0, 0.4);
            --equals-bg: rgba(255, 87, 34, 0.4);
            --equals-hover: rgba(255, 87, 34, 0.6);
            --text-color: white;
            --shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
            --border-radius: 20px;
            --transition: all 0.3s ease;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background: var(--primary-bg);
            padding: 20px;
            transition: background 1s ease;
        }

        .calculator-container {
            width: 100%;
            max-width: 400px;
            padding: 25px;
            background: var(--calculator-bg);
            backdrop-filter: blur(10px);
            border-radius: var(--border-radius);
            box-shadow: var(--shadow);
            border: 1px solid rgba(255, 255, 255, 0.2);
            transform: translateY(0);
            animation: float 3s ease-in-out infinite;
        }

        @keyframes float {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-10px); }
        }

        .theme-selector {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin-bottom: 25px;
        }

        .theme-btn {
            width: 35px;
            height: 35px;
            border-radius: 50%;
            border: 2px solid white;
            cursor: pointer;
            transition: var(--transition);
            box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
        }

        .theme-btn:hover {
            transform: scale(1.1);
        }

        .theme-1 { background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); }
        .theme-2 { background: linear-gradient(135deg, #ff416c 0%, #ff4b2b 100%); }
        .theme-3 { background: linear-gradient(135deg, #00b09b 0%, #96c93d 100%); }
        .theme-4 { background: linear-gradient(135deg, #654ea3 0%, #da98b4 100%); }
        .theme-5 { background: linear-gradient(135deg, #141e30 0%, #243b55 100%); }

        .display {
            background: var(--display-bg);
            border-radius: 15px;
            padding: 20px;
            margin-bottom: 25px;
            text-align: right;
            position: relative;
            overflow: hidden;
            min-height: 120px;
            box-shadow: inset 0 4px 10px rgba(0, 0, 0, 0.2);
        }

        .display::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 4px;
            background: linear-gradient(90deg, #ff8a00, #e52e71, #00b3ff);
            animation: gradientBG 3s ease infinite;
            background-size: 300% 300%;
        }

        @keyframes gradientBG {
            0% { background-position: 0% 50%; }
            50% { background-position: 100% 50%; }
            100% { background-position: 0% 50%; }
        }

        .previous-operand {
            color: rgba(255, 255, 255, 0.7);
            font-size: 1.2rem;
            min-height: 24px;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .current-operand {
            color: var(--text-color);
            font-size: 2.5rem;
            font-weight: 600;
            margin-top: 10px;
            min-height: 42px;
            overflow: hidden;
            text-overflow: ellipsis;
            transition: transform 0.2s;
        }

        .buttons-grid {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 12px;
        }

        .btn {
            border: none;
            border-radius: 15px;
            padding: 18px 0;
            font-size: 1.3rem;
            font-weight: 600;
            color: var(--text-color);
            background: var(--btn-bg);
            cursor: pointer;
            transition: var(--transition);
            position: relative;
            overflow: hidden;
            backdrop-filter: blur(5px);
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
        }

        .btn::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(255, 255, 255, 0.1);
            transform: translateX(-100%);
            transition: transform 0.3s ease;
        }

        .btn:hover {
            background: var(--btn-hover);
            transform: translateY(-3px);
            box-shadow: 0 7px 20px rgba(0, 0, 0, 0.2);
        }

        .btn:hover::before {
            transform: translateX(100%);
        }

        .btn:active {
            transform: translateY(1px);
            background: var(--btn-active);
        }

        .btn.operator {
            background: var(--operator-bg);
        }

        .btn.operator:hover {
            background: var(--operator-hover);
        }

        .btn.span-two {
            grid-column: span 2;
        }

        .btn.equals {
            background: var(--equals-bg);
        }

        .btn.equals:hover {
            background: var(--equals-hover);
        }

        .btn.clear {
            background: rgba(255, 99, 132, 0.3);
        }

        .btn.clear:hover {
            background: rgba(255, 99, 132, 0.5);
        }

        .btn.delete {
            background: rgba(54, 162, 235, 0.3);
        }

        .btn.delete:hover {
            background: rgba(54, 162, 235, 0.5);
        }

        .ripple {
            position: absolute;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.4);
            transform: scale(0);
            animation: ripple 0.6s linear;
            pointer-events: none;
        }

        @keyframes ripple {
            to {
                transform: scale(2.5);
                opacity: 0;
            }
        }

        .animation-text {
            animation: textScale 0.3s ease;
        }

        @keyframes textScale {
            0% { transform: scale(1.2); opacity: 0; }
            100% { transform: scale(1); opacity: 1; }
        }

        .calculator-title {
            text-align: center;
            color: white;
            font-size: 1.8rem;
            margin-bottom: 20px;
            font-weight: 600;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
        }

        .calculator-subtitle {
            text-align: center;
            color: rgba(255, 255, 255, 0.8);
            margin-bottom: 25px;
            font-size: 1rem;
        }

        @media (max-width: 480px) {
            .calculator-container {
                padding: 20px 15px;
            }
            
            .btn {
                padding: 16px 0;
                font-size: 1.2rem;
            }
            
            .current-operand {
                font-size: 2rem;
            }
        }
    </style>
</head>
<body>
    <div class="calculator-container">
        <h1 class="calculator-title">计算器8.2动画测试版</h1>
        <p class="calculator-subtitle"></p>
        
        <div class="theme-selector">
            <div class="theme-btn theme-1" data-theme="1"></div>
            <div class="theme-btn theme-2" data-theme="2"></div>
            <div class="theme-btn theme-3" data-theme="3"></div>
            <div class="theme-btn theme-4" data-theme="4"></div>
            <div class="theme-btn theme-5" data-theme="5"></div>
        </div>
        
        <div class="display">
            <div class="previous-operand" id="previous-operand"></div>
            <div class="current-operand" id="current-operand">0</div>
        </div>
        
        <div class="buttons-grid">
            <button class="btn clear span-two" data-action="clear">AC</button>
            <button class="btn delete" data-action="delete">DEL</button>
            <button class="btn operator" data-operation="÷">÷</button>
            
            <button class="btn" data-number="7">7</button>
            <button class="btn" data-number="8">8</button>
            <button class="btn" data-number="9">9</button>
            <button class="btn operator" data-operation="*">×</button>
            
            <button class="btn" data-number="4">4</button>
            <button class="btn" data-number="5">5</button>
            <button class="btn" data-number="6">6</button>
            <button class="btn operator" data-operation="-">−</button>
            
            <button class="btn" data-number="1">1</button>
            <button class="btn" data-number="2">2</button>
            <button class="btn" data-number="3">3</button>
            <button class="btn operator" data-operation="+">+</button>
            
            <button class="btn" data-number="0">0</button>
            <button class="btn" data-number=".">.</button>
            <button class="btn equals" data-action="calculate">=</button>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // 计算器状态
            let currentOperand = '0';
            let previousOperand = '';
            let operation = undefined;
            let resetScreen = false;
            // DOM 元素
            const currentOperandElement = document.getElementById('current-operand');
            const previousOperandElement = document.getElementById('previous-operand');
            const buttons = document.querySelectorAll('.btn');
            // 更新显示
            function updateDisplay() {
                currentOperandElement.textContent = currentOperand;
                if (operation != null) {
                    previousOperandElement.textContent = 
                        `${previousOperand} ${getOperationSymbol(operation)}`;
                } else {
                    previousOperandElement.textContent = previousOperand;
                }
            }
            // 获取操作符的显示符号
            function getOperationSymbol(op) {
                switch(op) {
                    case '+': return '+';
                    case '-': return '−';
                    case '*': return '×';
                    case '÷': return '÷';
                    default: return op;
                }
            }
            // 添加数字
            function appendNumber(number) {
                if (currentOperand === '0' || resetScreen) {
                    currentOperand = number;
                    resetScreen = false;
                } else {
                    // 防止输入多个小数点
                    if (number === '.' && currentOperand.includes('.')) return;
                    currentOperand += number;
                }
                
                animateText(currentOperandElement);
            }
            
            // 选择操作
            function chooseOperation(op) {
                if (currentOperand === '') return;
                if (previousOperand !== '') {
                    calculate();
                }
                
                operation = op;
                previousOperand = currentOperand;
                resetScreen = true;
                
                animateText(previousOperandElement);
            }
            
            // 计算
            function calculate() {
                let computation;
                const prev = parseFloat(previousOperand);
                const current = parseFloat(currentOperand);
                
                if (isNaN(prev) || isNaN(current)) return;
                
                switch (operation) {
                    case '+':
                        computation = prev + current;
                        break;
                    case '-':
                        computation = prev - current;
                        break;
                    case '*':
                        computation = prev * current;
                        break;
                    case '÷':
                        if (current === 0) {
                            computation = "错误";
                        } else {
                            computation = prev / current;
                        }
                        break;
                    default:
                        return;
                }
                
                currentOperand = computation.toString();
                operation = undefined;
                previousOperand = '';
                resetScreen = true;
                
                animateResult(currentOperandElement);
            }
            
            // 清除
            function clear() {
                currentOperand = '0';
                previousOperand = '';
                operation = undefined;
            }
            
            function deleteNumber() {
                currentOperand = currentOperand.toString().slice(0, -1);
                if (currentOperand === '') {
                    currentOperand = '0';
                }
                
                animateText(currentOperandElement);
            }
            
            function animateText(element) {
                element.classList.remove('animation-text');
                void element.offsetWidth;
                element.classList.add('animation-text');
            }
            
            function animateResult(element) {
                element.style.transform = 'scale(1.2)';
                setTimeout(() => {
                    element.style.transform = 'scale(1)';
                }, 300);
            }
            
            function createRipple(event) {
                const button = event.currentTarget;
                const circle = document.createElement('span');
                const diameter = Math.max(button.clientWidth, button.clientHeight);
                const radius = diameter / 2;
                circle.style.width = circle.style.height = `${diameter}px`;
                circle.style.left = `${event.clientX - button.getBoundingClientRect().left - radius}px`;
                circle.style.top = `${event.clientY - button.getBoundingClientRect().top - radius}px`;
                circle.classList.add('ripple');
                
                const ripple = button.getElementsByClassName('ripple')[0];
                if (ripple) {
                    ripple.remove();
                }
                
                button.appendChild(circle);
            }
            
            document.querySelectorAll('.theme-btn').forEach(btn => {
                btn.addEventListener('click', () => {
                    const theme = btn.getAttribute('data-theme');
                    changeTheme(theme);
                });
            });
            
            function changeTheme(theme) {
                document.documentElement.style.setProperty('--primary-bg', getThemeGradient(theme));
                document.documentElement.style.setProperty('--operator-bg', getThemeOperator(theme));
                document.documentElement.style.setProperty('--equals-bg', getThemeEquals(theme));
            }
            
            function getThemeGradient(theme) {
                switch(theme) {
                    case '1': return 'linear-gradient(135deg, #6a11cb 0%, #2575fc 100%)';
                    case '2': return 'linear-gradient(135deg, #ff416c 0%, #ff4b2b 100%)';
                    case '3': return 'linear-gradient(135deg, #00b09b 0%, #96c93d 100%)';
                    case '4': return 'linear-gradient(135deg, #654ea3 0%, #da98b4 100%)';
                    case '5': return 'linear-gradient(135deg, #141e30 0%, #243b55 100%)';
                    default: return 'linear-gradient(135deg, #6a11cb 0%, #2575fc 100%)';
                }
            }
            
            function getThemeOperator(theme) {
                switch(theme) {
                    case '1': return 'rgba(255, 215, 0, 0.3)';
                    case '2': return 'rgba(255, 193, 7, 0.3)';
                    case '3': return 'rgba(76, 175, 80, 0.3)';
                    case '4': return 'rgba(156, 39, 176, 0.3)';
                    case '5': return 'rgba(33, 150, 243, 0.3)';
                    default: return 'rgba(255, 215, 0, 0.3)';
                }
            }
            
            function getThemeEquals(theme) {
                switch(theme) {
                    case '1': return 'rgba(255, 87, 34, 0.4)';
                    case '2': return 'rgba(244, 67, 54, 0.4)';
                    case '3': return 'rgba(139, 195, 74, 0.4)';
                    case '4': return 'rgba(233, 30, 99, 0.4)';
                    case '5': return 'rgba(63, 81, 181, 0.4)';
                    default: return 'rgba(255, 87, 34, 0.4)';
                }
            }
            
            // 按钮事件
            buttons.forEach(button => {
                button.addEventListener('click', () => {
                    createRipple(event);
                    
                    if (button.hasAttribute('data-number')) {
                        appendNumber(button.getAttribute('data-number'));
                    } else if (button.hasAttribute('data-operation')) {
                        chooseOperation(button.getAttribute('data-operation'));
                    } else if (button.getAttribute('data-action') === 'calculate') {
                        calculate();
                    } else if (button.getAttribute('data-action') === 'clear') {
                        clear();
                    } else if (button.getAttribute('data-action') === 'delete') {
                        deleteNumber();
                    }
                    
                    updateDisplay();
                });
            });
            
            document.addEventListener('keydown', event => {
                if (event.key >= 0 && event.key <= 9) appendNumber(event.key);
                if (event.key === '.') appendNumber('.');
                if (event.key === '=' || event.key === 'Enter') calculate();
                if (event.key === 'Backspace') deleteNumber();
                if (event.key === 'Escape') clear();
                if (event.key === '+' || event.key === '-' || event.key === '*' || event.key === '/') {
                    chooseOperation(event.key === '/' ? '÷' : event.key);
                }
                updateDisplay();
            });
            
            updateDisplay();
        });
    </script>
</body>
</html>
        
预览
控制台