itutor-mathlive
Version:
Beautifully typeset math made easy
282 lines (268 loc) • 11.1 kB
HTML
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>MathLive Four Operation Calculator</title>
<link rel="stylesheet" href="../../dist/mathlive.core.css">
<link rel="stylesheet" href="../../dist/mathlive.css">
<style>
body {
font-family: sans-serif;
color: #444;
background-color: #f9f9f9;
}
main {
max-width: 820px;
margin: auto;
}
.mathfield {
font-size: 32px;
border: 1px solid #ddd;
padding:5px;
margin: 10px 0 10px 0;
border-radius:5px;
background-color: #fff;
}
#result {
background: #ddd;
padding: 1em;
font-size: 32px;
box-shadow: 2px 1px 3px rgba(0, 0, 0, .5);
border: 1px solid #c5c5c5;
}
#output {
padding:1em;
margin: 2em 0 10px 0;
border-radius:5px;
border: 1px solid #000;
font-family: "Source Code Pro", Menlo, "Bitstream Vera Sans Mono", Monaco, Courier, "Andale Mono", monospace;
color: #f0c674;
background: #35434e;
}
</style>
</head>
<body>
<main>
<h1>MathLive Four Function Calculator</h1>
<div class="mathfield" id='mf' ></div>
<div id='result'></div>
<div id='output'></div>
</main>
<script src="../../dist/mathlive.js"></script>
<script>
(function() {
const mf = MathLive.makeMathField('mf', {
onContentDidChange: updateOutput,
virtualKeyboardMode: 'manual',
customVirtualKeyboardLayers: {
'four-op': `
<div class='rows'>
<ul><li class='keycap'>7</li>
<li class='keycap' >8</li>
<li class='keycap' >9</li>
<li class='keycap' data-insert='\\frac{#0}{#?}'>÷</li>
<li class='separator'/>
<li class='separator w20'/>
</ul>
<ul><li class='keycap '>4</li>
<li class='keycap' >5</li>
<li class='keycap' >6</li>
<li class='keycap' data-insert='\\times '>×</li>
<li class='separator'/>
<li class='separator w20'/>
</ul>
<ul><li class='keycap '>1</li>
<li class='keycap' >2</li>
<li class='keycap' >3</li>
<li class='keycap' >-</li>
<li class='separator w15'/>
<li class='action font-glyph bottom right w15' data-command='"deletePreviousChar"'>⌫</li></ul>
</ul>
<ul><li class='keycap' data-key='0'>0</li>
<li class='keycap' >.</li>
<li class='keycap' data-insert='\\pi '>π</li>
<li class='keycap'>+</li>
<li class='action' data-command='"moveToPreviousChar"'><svg><use xlink:href='#svg-arrow-left' /></svg></li>
<li class='action' data-command='"moveToNextChar"'><svg><use xlink:href='#svg-arrow-right' /></svg></li>
<li class='action' data-command='"moveToNextPlaceholder"'><svg><use xlink:href='#svg-tab' /></svg></li>
</ul>
</div>
</div>`,
'hp': `
<style>
.calculator-backdrop {
width: 768px;
padding-top: 20px;
padding-bottom: 20px;
display: flex;
align-self: center;
justify-content: center;
}
.calculator-frame {
width: 500px;
background: #1e1e1e;
padding-top: 20px;
padding-bottom: 20px;
border-radius: 4px;
border: 1px solid #222;
border-bottom: 1px solid #000;
align-self: center;
box-shadow: 0 4px 5px rgba(0, 0, 0, .5);
margin-bottom: 20px;
}
#ML__keyboard div.rows.calculator {
background: #1e1e1e;
width: 450px;
border-radius: 2px;
border: 4px solid #cdcdcd;
border-bottom: 12px solid #cdcdcd
}
#ML__keyboard div.rows.calculator ul {
height: 78px;
margin: 0;
}
div#ML__keyboard div div.rows.calculator ul li.btn,
div#ML__keyboard div div.rows.calculator ul li.btn:hover,
div#ML__keyboard.material div div.rows.calculator ul li.keycap:not([data-key=' ']):hover {
background: url(btn.png);
background-size: 70px;
border: 0;
border-radius: 0;
margin: 0;
background-position-y: 2px;
background-position-x: 5px;
background-repeat: no-repeat;
width: 78px;
max-width: 78px;
height: 78px;
padding: 0;
color: #b1afaf;
text-shadow: 0 1px 0px rgba(0, 0, 0, .5);
box-shadow: none;
}
#ML__keyboard div.rows.calculator ul li.btn aside.above {
color: #d97845;
font-size: 16px;
margin-bottom: 5px;
opacity: .9;
}
#ML__keyboard div.rows.calculator ul li.btn span {
margin-bottom: 10px;
}
#ML__keyboard div.rows.calculator ul li.btn aside.below {
color: rgb(49,113,173);
font-size: 14px;
font-weight: 600;
margin-top: -5px;
opacity: .8;
}
div#ML__keyboard div div.rows.calculator ul li.btn:hover:active,
div#ML__keyboard div div.rows.calculator ul li.btn:active {
background: url(btn-pressed.png);
background-position-y: 2px;
background-position-x: 5px;
// padding-top: 3px;
background-size: 70px;
transform: none;
// clip: rect(0px,70px,80px,0px);
overflow: hidden;
}
div#ML__keyboard div div.rows.calculator ul li.btn:hover:active aside.below,
div#ML__keyboard div div.rows.calculator ul li.btn:active aside.below,
div#ML__keyboard div div.rows.calculator ul li.btn:hover:active > span,
div#ML__keyboard div div.rows.calculator ul li.btn:active > span {
position: relative;
top: 2px;
}
</style>
<div class='calculator-backdrop'>
<div class='calculator-frame'>
<div class='calculator rows'>
<ul><li class='keycap btn '><span>7</span></li>
<li class='keycap btn' ><span>8</span></li>
<li class='keycap btn' ><span>9</span></li>
<li class='keycap btn' data-insert='\\frac{#0}{#?}'><span>÷</span></li>
</ul>
<ul><li class='keycap btn '><span>4</span></li>
<li class='keycap btn' ><span>5</span></li>
<li class='keycap btn' ><span>6</span></li>
<li class='keycap btn' data-insert='\\times '>×</li>
</ul>
<ul><li class='keycap btn '><span>1</span></li>
<li class='keycap btn' ><span>2</span></li>
<li class='keycap btn' ><span>3</span></li>
<li class='keycap btn' ><span>-</span></li>
</ul>
<ul><li class='keycap btn ' data-key='0'>
<aside class='above tex'><i>x</i> !</aside>
<span>0</span>
<aside class='below'>TEST</aside>
</li>
<li class='keycap btn' ><span>.</span></li>
<li class='keycap btn' data-insert='\\pi '><span>π</span></li>
<li class='keycap btn'><span>+</span></li>
</ul>
</div>
</div>
</div>`,
},
customVirtualKeyboards: {
'hp': {
tooltip: 'hp15c',
layer: 'hp',
label: 'hp',
classes: '',
layers: ['hp']
},
'basic': {
label: 'Basic',
tooltip: 'Four Operation Keyboard',
layer: 'four-op'
},
},
virtualKeyboards: 'hp basic',
});
function escapeHtml (string) {
const ENTITIES = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/',
'`': '`',
'=': '=',
};
return String(string).replace(/[&<>"'`=/]/g, function (s) {
return ENTITIES[s];
});
}
function evaluate(ast) {
if (ast === undefined) return NaN;
if (typeof ast === 'number') return ast;
if (ast.num !== undefined) return evaluate(ast.num);
if (typeof ast === 'string') {
if (ast === 'π') {
return Math.PI;
}
return parseFloat(ast);
}
if (ast.op === '*') {
return evaluate(ast.lhs) * evaluate(ast.rhs);
} else if (ast.op === '/') {
return evaluate(ast.lhs) / evaluate(ast.rhs);
} else if (ast.op === '-') {
return evaluate(ast.lhs) - evaluate(ast.rhs);
} else if (ast.op === '+') {
return evaluate(ast.lhs) + evaluate(ast.rhs);
}
return NaN;
}
function updateOutput(mathfield) {
const ast = MathLive.latexToAST(mathfield.latex());
document.getElementById('result').innerHTML = evaluate(ast).toString();
document.getElementById('output').innerHTML =
escapeHtml(JSON.stringify(ast))
}
})();
</script>
</body></html>