Compact Scientific Calculator

Compact scientific calculator for Mathswatch

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Compact Scientific Calculator
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  Compact scientific calculator for Mathswatch
// @author       frozled
// @match        *://*.mathswatch.co.uk/*
// @grant        GM_addStyle
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Compact styles
    const styles = `
        .calculator-container {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 350px;
            background: #f0f4f8;
            border-radius: 10px;
            box-shadow: 0 10px 25px rgba(0,0,0,0.3);
            z-index: 9999;
            font-family: 'Arial', sans-serif;
            transition: all 0.3s ease;
        }
        .calculator-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 8px 12px;
            background: #e9ecef;
            border-top-left-radius: 10px;
            border-top-right-radius: 10px;
        }
        .calculator-header h3 {
            margin: 0;
            font-size: 14px;
        }
        .close-calculator {
            background: none;
            border: none;
            color: #666;
            font-size: 20px;
            cursor: pointer;
            padding: 0;
            line-height: 1;
        }
        .calculator-tabs {
            display: flex;
            background: #dee2e6;
        }
        .calculator-tab {
            flex: 1;
            padding: 8px;
            text-align: center;
            cursor: pointer;
            font-size: 12px;
            transition: all 0.2s;
        }
        .calculator-tab.active {
            background: #007bff;
            color: white;
        }
        .calculator-content {
            padding: 10px;
        }
        .calculator-display {
            width: 100%;
            height: 40px;
            margin-bottom: 10px;
            text-align: right;
            padding: 5px;
            font-size: 18px;
            border: 1px solid #ced4da;
            border-radius: 5px;
            background: white;
        }
        .calculator-buttons {
            display: grid;
            grid-template-columns: repeat(5, 1fr);
            gap: 5px;
        }
        .calculator-button {
            padding: 8px;
            border: 1px solid #dee2e6;
            background: white;
            cursor: pointer;
            border-radius: 4px;
            transition: all 0.2s;
            font-size: 12px;
        }
        .calculator-button:hover {
            background: #e9ecef;
        }
        .memory-panel {
            display: flex;
            justify-content: space-around;
            margin-top: 8px;
        }
    `;

    // Inject styles
    const styleSheet = document.createElement('style');
    styleSheet.textContent = styles;
    document.head.appendChild(styleSheet);

    // Calculator HTML
    const calculatorHTML = `
        <div class="calculator-container" id="advanced-calculator">
            <div class="calculator-header">
                <h3>Scientific Calculator</h3>
                <button class="close-calculator">×</button>
            </div>
            <div class="calculator-tabs">
                <div class="calculator-tab active" data-tab="standard">Standard</div>
                <div class="calculator-tab" data-tab="scientific">Scientific</div>
            </div>
            <div class="calculator-content">
                <input type="text" class="calculator-display" readonly>

                <!-- Standard Calculator Buttons -->
                <div class="calculator-buttons standard-buttons">
                    <button class="calculator-button clear">C</button>
                    <button class="calculator-button function">( )</button>
                    <button class="calculator-button function">%</button>
                    <button class="calculator-button operator">÷</button>
                    <button class="calculator-button function">⌫</button>

                    <button class="calculator-button">7</button>
                    <button class="calculator-button">8</button>
                    <button class="calculator-button">9</button>
                    <button class="calculator-button operator">×</button>
                    <button class="calculator-button operator">^</button>

                    <button class="calculator-button">4</button>
                    <button class="calculator-button">5</button>
                    <button class="calculator-button">6</button>
                    <button class="calculator-button operator">-</button>
                    <button class="calculator-button function">√</button>

                    <button class="calculator-button">1</button>
                    <button class="calculator-button">2</button>
                    <button class="calculator-button">3</button>
                    <button class="calculator-button operator">+</button>
                    <button class="calculator-button equals">=</button>

                    <button class="calculator-button">0</button>
                    <button class="calculator-button">.</button>
                    <button class="calculator-button function">±</button>
                </div>

                <!-- Scientific Calculator Buttons -->
                <div class="calculator-buttons scientific-buttons" style="display:none;">
                    <button class="calculator-button function">sin</button>
                    <button class="calculator-button function">cos</button>
                    <button class="calculator-button function">tan</button>
                    <button class="calculator-button function">log</button>
                    <button class="calculator-button function">ln</button>

                    <button class="calculator-button function">sin⁻¹</button>
                    <button class="calculator-button function">cos⁻¹</button>
                    <button class="calculator-button function">tan⁻¹</button>
                    <button class="calculator-button function">10^x</button>
                    <button class="calculator-button function">e^x</button>

                    <button class="calculator-button function">π</button>
                    <button class="calculator-button function">e</button>
                    <button class="calculator-button function">!</button>
                    <button class="calculator-button function">√</button>
                    <button class="calculator-button function">∛</button>
                </div>

                <!-- Memory Functions -->
                <div class="memory-panel">
                    <button class="calculator-button memory-clear">MC</button>
                    <button class="calculator-button memory-recall">MR</button>
                    <button class="calculator-button memory-store">MS</button>
                    <button class="calculator-button memory-add">M+</button>
                    <button class="calculator-button memory-subtract">M-</button>
                </div>
            </div>
        </div>
    `;

    // Inject calculator to page
    document.body.insertAdjacentHTML('beforeend', calculatorHTML);

    // Get DOM elements
    const calculator = document.getElementById('advanced-calculator');
    const closeBtn = document.querySelector('.close-calculator');
    const display = document.querySelector('.calculator-display');
    const tabs = document.querySelectorAll('.calculator-tab');
    const standardButtons = document.querySelector('.standard-buttons');
    const scientificButtons = document.querySelector('.scientific-buttons');

    // Draggability functionality
    let isDragging = false;
    let currentX;
    let currentY;
    let initialX;
    let initialY;
    let xOffset = 0;
    let yOffset = 0;

    // Drag start
    calculator.querySelector('.calculator-header').addEventListener('mousedown', dragStart);
    document.addEventListener('mousemove', drag);
    document.addEventListener('mouseup', dragEnd);

    function dragStart(e) {
        initialX = e.clientX - xOffset;
        initialY = e.clientY - yOffset;

        if (e.target === calculator.querySelector('.calculator-header')) {
            isDragging = true;
        }
    }

    function drag(e) {
        if (isDragging) {
            e.preventDefault();
            currentX = e.clientX - initialX;
            currentY = e.clientY - initialY;
            xOffset = currentX;
            yOffset = currentY;

            setTranslate(currentX, currentY, calculator);
        }
    }

    function setTranslate(xPos, yPos, el) {
        el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
    }

    function dragEnd() {
        initialX = currentX;
        initialY = currentY;
        isDragging = false;
    }

    // Close calculator
    closeBtn.addEventListener('click', () => {
        calculator.style.display = 'none';
    });

    // Tab switching
    tabs.forEach(tab => {
        tab.addEventListener('click', () => {
            // Remove active class and hide all button sets
            tabs.forEach(t => t.classList.remove('active'));
            tab.classList.add('active');

            // Hide all calculator sections
            standardButtons.style.display = 'none';
            scientificButtons.style.display = 'none';

            // Show selected tab's content
            switch(tab.dataset.tab) {
                case 'standard':
                    standardButtons.style.display = 'grid';
                    break;
                case 'scientific':
                    scientificButtons.style.display = 'grid';
                    break;
            }
        });
    });

    // Calculation logic (same as previous version)
    let currentExpression = '';
    let memoryStore = 0;

    // Memory functions
    const memoryButtons = document.querySelectorAll('.memory-panel button');
    memoryButtons.forEach(button => {
        button.addEventListener('click', () => {
            const value = parseFloat(display.value) || 0;
            switch(button.classList[1]) {
                case 'memory-clear':
                    memoryStore = 0;
                    break;
                case 'memory-recall':
                    display.value = memoryStore;
                    break;
                case 'memory-store':
                    memoryStore = value;
                    break;
                case 'memory-add':
                    memoryStore += value;
                    break;
                case 'memory-subtract':
                    memoryStore -= value;
                    break;
            }
        });
    });

    // Keyboard support
    document.addEventListener('keydown', (event) => {
        const key = event.key;
        const validKeys = '0123456789.+-*/()^%';

        if (validKeys.includes(key)) {
            currentExpression += key;
            display.value = currentExpression;
        } else if (key === 'Backspace') {
            currentExpression = currentExpression.slice(0, -1);
            display.value = currentExpression;
        } else if (key === 'Enter' || key === '=') {
            calculateResult();
        }
    });

    // Advanced calculation function
    function calculateResult() {
        try {
            let expression = currentExpression
                .replace(/×/g, '*')
                .replace(/÷/g, '/')
                .replace(/\^/g, '**')
                .replace(/√/g, 'Math.sqrt')
                .replace(/sin\(/g, 'Math.sin(')
                .replace(/cos\(/g, 'Math.cos(')
                .replace(/tan\(/g, 'Math.tan(')
                .replace(/log\(/g, 'Math.log10(')
                .replace(/ln\(/g, 'Math.log(')
                .replace(/π/g, 'Math.PI')
                .replace(/e\^/g, 'Math.exp')
                .replace(/!\(/g, 'factorial(');

            // Custom factorial function
            function factorial(n) {
                if (n < 0) return NaN;
                if (n === 0 || n === 1) return 1;
                return n * factorial(n - 1);
            }

            const result = eval(expression);
            display.value = result;
            currentExpression = result.toString();
        } catch (error) {
            display.value = 'Error';
            currentExpression = '';
        }
    }

    // Bind calculation to main buttons
    const buttons = document.querySelectorAll('.calculator-button');
    buttons.forEach(button => {
        button.addEventListener('click', () => {
            const value = button.textContent;

            if (value === 'C') {
                currentExpression = '';
                display.value = '';
            } else if (value === '=') {
                calculateResult();
            } else if (value === '⌫') {
                currentExpression = currentExpression.slice(0, -1);
                display.value = currentExpression;
            } else if (value === '±') {
                currentExpression = currentExpression.startsWith('-')
                    ? currentExpression.slice(1)
                    : `-${currentExpression}`;
                display.value = currentExpression;
            } else {
                currentExpression += value;
                display.value = currentExpression;
            }
        });
    });
})();