// ==UserScript==
// @name Cool Calculator
// @namespace http://tampermonkey.net/
// @version 3.0
// @description Draggable, resizable, fullscreen scientific calculator with pink-purple gradient, animations, and full scientific functions by Leon Luk
// @author Leon Luk
// @match *://*/*
// @grant none
// @license Proprietary
// ==/UserScript==
(function() {
'use strict';
const STORAGE_POS = 'leonluk_calc_pos';
const STORAGE_OPEN = 'leonluk_calc_open';
const STORAGE_FULLSCREEN = 'leonluk_calc_fullscreen';
const STORAGE_SCALE = 'leonluk_calc_scale';
// Create the toggle button
const button = document.createElement('button');
button.innerText = '🧮 Calculator';
Object.assign(button.style, {
position: 'fixed',
top: '50%',
left: '10px',
transform: 'translateY(-50%)',
zIndex: '999999',
padding: '10px 15px',
fontSize: '14px',
background: 'linear-gradient(135deg,#d946ef,#7c3aed)',
color: 'white',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
boxShadow: '0 2px 8px rgba(0,0,0,0.3)',
transition: 'opacity 0.3s ease'
});
button.onmouseenter = () => button.style.opacity = '0.8';
button.onmouseleave = () => button.style.opacity = '1';
document.body.appendChild(button);
// Create calculator container
const calc = document.createElement('div');
Object.assign(calc.style, {
position: 'fixed',
top: '50%',
left: '-350px',
width: '320px',
height: 'auto',
padding: '15px',
background: 'linear-gradient(135deg,#ec4899,#8b5cf6)',
color: 'white',
borderRadius: '10px',
boxShadow: '4px 0 15px rgba(0,0,0,0.6)',
zIndex: '1000000',
transition: 'left 0.5s cubic-bezier(0.25,1,0.3,1), width 0.3s, height 0.3s',
fontFamily: 'monospace',
opacity: '0.97',
cursor: 'grab',
overflow: 'hidden'
});
document.body.appendChild(calc);
const savedPos = JSON.parse(localStorage.getItem(STORAGE_POS));
const savedOpen = localStorage.getItem(STORAGE_OPEN);
const savedFullscreen = localStorage.getItem(STORAGE_FULLSCREEN);
if (savedPos) {
calc.style.left = savedPos.left + 'px';
calc.style.top = savedPos.top + 'px';
calc.style.width = (savedPos.width || 320) + 'px';
calc.style.height = (savedPos.height || 'auto') + 'px';
calc.style.transform = 'none';
}
// Calculator HTML
calc.innerHTML = `
<div id="calc-header" style="display:flex;justify-content:space-between;align-items:center;font-weight:bold;margin-bottom:5px;cursor:move;font-size:16px;">
<span>Calculator</span>
<div>
<button id="fullscreen-btn" style="background:none;border:none;color:white;font-size:18px;cursor:pointer;line-height:1;padding:0;margin-right:5px;">🗖</button>
<button id="minimize-btn" style="background:none;border:none;color:white;font-size:20px;cursor:pointer;line-height:1;padding:0;">—</button>
</div>
</div>
<input type="text" id="calc-display" readonly style="width:100%;padding:10px;font-size:18px;border:none;border-radius:5px;text-align:right;background:rgba(0,0,0,0.3);color:white;margin-bottom:5px;">
<div id="calc-buttons" style="display:grid;grid-template-columns:repeat(6,1fr);gap:5px;margin-bottom:5px;"></div>
<div style="text-align:right;font-size:10px;opacity:0.8;">by Leon Luk</div>
`;
const display = calc.querySelector('#calc-display');
const buttonsContainer = calc.querySelector('#calc-buttons');
const minimizeBtn = calc.querySelector('#minimize-btn');
const fullscreenBtn = calc.querySelector('#fullscreen-btn');
// Scientific buttons
const buttons = [
'7','8','9','/','C','(',
'4','5','6','*','^',')',
'1','2','3','-','√','x²',
'0','.','=','+','%','+/-',
'sin','cos','tan','asin','acos','atan',
'log','ln','pi','e'
];
buttons.forEach(key => {
const btn = document.createElement('button');
btn.innerText = key;
Object.assign(btn.style, {
padding: '10px',
fontSize: '14px',
border: 'none',
borderRadius: '5px',
background: 'rgba(255,255,255,0.15)',
color: 'white',
cursor: 'pointer',
transition: 'background 0.2s ease, transform 0.1s ease'
});
btn.onmouseenter = () => btn.style.background = 'rgba(255,255,255,0.25)';
btn.onmouseleave = () => btn.style.background = 'rgba(255,255,255,0.15)';
btn.onmousedown = () => btn.style.transform = 'scale(0.95)';
btn.onmouseup = () => btn.style.transform = 'scale(1)';
btn.addEventListener('click', () => {
try {
if(key==='C'){ display.value=''; }
else if(key==='='){
let expr = display.value
.replace(/\^/g,'**')
.replace(/√/g,'Math.sqrt')
.replace(/pi/g,'Math.PI')
.replace(/e/g,'Math.E')
.replace(/sin/g,'Math.sin')
.replace(/cos/g,'Math.cos')
.replace(/tan/g,'Math.tan')
.replace(/asin/g,'Math.asin')
.replace(/acos/g,'Math.acos')
.replace(/atan/g,'Math.atan')
.replace(/log/g,'Math.log10')
.replace(/ln/g,'Math.log');
display.value = eval(expr);
}
else if(key==='x²'){ display.value += '**2'; }
else if(key==='+/-'){ display.value = display.value.startsWith('-') ? display.value.slice(1) : '-' + display.value; }
else { display.value += key; }
} catch {
display.value = 'Error';
}
});
buttonsContainer.appendChild(btn);
});
// Open/Close and Fullscreen logic
let isOpen = false;
if(savedOpen === 'true'){ isOpen = true; calc.style.left = '70px'; }
let isFullscreen = false;
if(savedFullscreen === 'true'){
isFullscreen = true;
calc.style.left='0';
calc.style.top='0';
calc.style.width=window.innerWidth+'px';
calc.style.height=window.innerHeight+'px';
}
button.addEventListener('click', () => {
isOpen = !isOpen;
calc.style.left = isOpen ? '70px':'-350px';
localStorage.setItem(STORAGE_OPEN,isOpen);
});
minimizeBtn.addEventListener('click', () => {
calc.style.left = '-350px';
isOpen = false;
localStorage.setItem(STORAGE_OPEN,isOpen);
});
fullscreenBtn.addEventListener('click', () => {
isFullscreen = !isFullscreen;
if(isFullscreen){
const scaleWidth = window.innerWidth;
const scaleHeight = window.innerHeight;
calc.style.left = '0';
calc.style.top = '0';
calc.style.width = scaleWidth + 'px';
calc.style.height = scaleHeight + 'px';
} else {
const pos = JSON.parse(localStorage.getItem(STORAGE_POS)) || {left:70,top:50,width:320,height:'auto'};
calc.style.left = pos.left+'px';
calc.style.top = pos.top+'px';
calc.style.width = pos.width+'px';
calc.style.height = pos.height;
}
localStorage.setItem(STORAGE_FULLSCREEN,isFullscreen);
});
// Dragging
const header = calc.querySelector('#calc-header');
let dragging=false,offsetX=0,offsetY=0;
header.addEventListener('mousedown',e=>{
dragging=true;
offsetX=e.clientX-calc.getBoundingClientRect().left;
offsetY=e.clientY-calc.getBoundingClientRect().top;
calc.style.transition='none';
calc.style.cursor='grabbing';
});
document.addEventListener('mousemove',e=>{
if(!dragging) return;
e.preventDefault();
if(!isFullscreen){
calc.style.left=(e.clientX-offsetX)+'px';
calc.style.top=(e.clientY-offsetY)+'px';
calc.style.transform='none';
}
});
document.addEventListener('mouseup',()=>{
if(dragging){
dragging=false;
calc.style.cursor='grab';
calc.style.transition='left 0.5s cubic-bezier(0.25,1,0.3,1)';
localStorage.setItem(STORAGE_POS,JSON.stringify({
left:parseInt(calc.style.left),
top:parseInt(calc.style.top),
width:parseInt(calc.style.width),
height:calc.style.height
}));
}
});
// Resizer
const resizer = document.createElement('div');
Object.assign(resizer.style,{
width:'10px', height:'10px', position:'absolute',
right:0, bottom:0, cursor:'se-resize', background:'rgba(255,255,255,0.2)'
});
calc.appendChild(resizer);
let resizing=false;
resizer.addEventListener('mousedown',e=>{resizing=true;e.preventDefault();});
document.addEventListener('mousemove',e=>{
if(!resizing) return;
e.preventDefault();
calc.style.width=(e.clientX-calc.getBoundingClientRect().left)+'px';
calc.style.height=(e.clientY-calc.getBoundingClientRect().top)+'px';
});
document.addEventListener('mouseup',()=>{
if(resizing){
resizing=false;
localStorage.setItem(STORAGE_POS,JSON.stringify({
left:parseInt(calc.style.left),
top:parseInt(calc.style.top),
width:parseInt(calc.style.width),
height:calc.style.height
}));
}
});
})();