## Build Advanced Scientific Calculator Using Math.js Library in Browser Using HTML5 & Javascript Full Project For Beginners

`index.html`

``````<html>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/2.6.0/math.min.js"></script>
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>

<body>
<div class="wrapper">
<h1 style="text-align:center">JS calculator.</h1>
<div class="calc">
<div class="top">
<div class='result'></div>
<div class='screen'><span id="screentext" class="screentext animated"></span><span class="hints"></span></div>
</div>
<div class="keyboard">

<div class="crow">
<div class='cb cbac'>AC</div>
<div class="cb cbpar" key='('>(</div>
<div class="cb cbpar" key=')'>)</div>
<div class='cb cbce'>CE</div>
</div>

<div class="crow">
<div class="cb cbnum" key='pi'>π</div>
<div class="cb cbnum" key='e'>e</div>
<div class="cb cbnum" key='phi'>φ</div>
<div class="cb cbnum" key='tau'>τ</div>
</div>

<div class="crow">
<div class="cb cbinv">Inv</div>
<div class="cb cbfun" key1='sin(' key2="asin(">sin<sup class="inv">-1</sup></div>
<div class="cb cbfun" key1='cos(' key2="acos(">cos<sup class="inv">-1</sup></div>
<div class="cb cbfun" key1='tan(' key2="atan(">tan<sup class="inv">-1</sup></div>
</div>

<div class="crow">
<div class="cb cbfun" key1='log10('>log</div>
<div class="cb cbfun" key1='log('>ln</div>
<div class="cb cbop" key='!' char='!'>!</div>
<div class="cb cbop" key='deg' char='deg'>deg</div>
</div>

<div class="crow">
<div class="cb cbfun" key1='sqrt('>√</div>
<div class="cb cbop" key='^2' char='²'>x²</div>
<div class="cb cbop" key='^3' char='³'>x³</div>
<div class="cb cbop" key='^' char='^'>^</div>
</div>

<div class="crow">
<div class="cb cbnum lighter" key='7'>7</div>
<div class="cb cbnum lighter" key='8'>8</div>
<div class="cb cbnum lighter" key='9'>9</div>
<div class="cb cbop operands" key='/' char='÷'>÷</div>
</div>

<div class="crow">
<div class="cb cbnum lighter" key='4'>4</div>
<div class="cb cbnum lighter" key='5'>5</div>
<div class="cb cbnum lighter" key='6'>6</div>
<div class="cb cbop operands" key='*' char='×'>×</div>
</div>

<div class="crow">
<div class="cb cbnum lighter" key='1'>1</div>
<div class="cb cbnum lighter" key='2'>2</div>
<div class="cb cbnum lighter" key='3'>3</div>
<div class="cb cbop operands" key='-' char='-'>-</div>
</div>

<div class="crow">
<div class="cb cbnum lighter" key='0'>0</div>
<div class="cb cbnum lighter" key='.'>.</div>
<div class="cb cbop lighter" key='E' char='E'>exp</div>
<div class="cb cbop operands" key='+' char='+'>+</div>
</div>

<div class="crow">
<div class="cb cbrnd" style="width:25%">Rnd</div>
<div class="cb cbans" style="width:25%">Ans</div>
<div class="cb enter" style="width:50%">=</div>
</div>

</div>
</div>
</div>
</body>

</html>``````

`style.css`

``````* {
font-family: 'Open Sans', 'Helvetica', 'Arial', sans-serif;
box-sizing: border-box;
}

h1,
h2,
h3,
h4 {
font-weight: 900;
}

body {
background: rgba(252, 208, 122, 1);
font-weight: 300;
margin: 0;
}

.wrapper {
width: 100%;
}

.calc {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
}

.top {
max-width: 400px;
width: 100%;
background: #FFF9F9;
color: #444;
}

.result {
box-sizing: border-box;
width: 100%;
height: 30px;
font-size: 16px;
margin: 0;
text-align: left;
opacity: 0.6;
overflow: hidden;
}

.screen {
width: 100%;
height: 50px;
border: 0;
font-size: 30px;
text-align: right;
display: flex;
align-items: baseline;
justify-content: flex-end;
overflow: hidden;
}

.hints {
opacity: 0.3;
}

.keyboard {
max-width: 400px;
width: 100%;
box-shadow: inset 10px -88px 160px 23px rgba(0, 0, 0, 0.8), 5px 35px 191px -43px rgba(255, 0, 255, 0.5);
margin-bottom: 50px;
}

.crow {
display: flex;
flex-direction: row;
align-items: stretch;
;
justify-content: space-around;
;
width: 100%;
min-height: 50px;
margin: auto;
}

.crow:last-child {
}

.cb {
box-sizing: border-box;
width: 100%;
text-align: center;
background: rgba(255, 228, 240, 1);
color: #444;
cursor: pointer;
outline: 1px solid rgba(136, 14, 79, 0.1);
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
transition: all 0.2s;
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
-o-user-select: none;
}

.cb:hover {
box-shadow: 10px 10px 18px -6px rgba(233, 30, 99, 0.5);
z-index: 1000;
}

.cb:active {
box-shadow: inset 10px 10px 18px -6px rgba(233, 30, 99, 0.5);
}

.screentext {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}

.animated {
position: relative;
top: 0;
animation: movetext1 .2s 1;
}

@keyframes movetext1 {
0% {
top: 100px;
}
100% {
top: 0px;
}
}

sup {
vertical-align: text-top;
font-size: 0.5em;
}

.inv {
display: none;
}

.lighter {
background-color: rgba(255, 235, 238, 1);
font-size: 1.2em;
}

.operands {
background-color: rgba(255, 155, 160, 1);
color: #eee;
font-size: 1.6em;
}

.enter {
background-color: rgba(254, 111, 118, 1);
color: #eee;
font-size: 2em;
}``````

See also  Build a P5.js 2D Snake Eating Apples Game in Browser Using Vanilla Javascript Full Project For Beginners

`script.js`

``````\$(function() {

var expression = '';
var expressionArray = [];
var screenArray = [];
var parentheses = 0;
var ansOnScreen = false;
var ans = null;
var error = false;
var inverted = false;

function defaults() {
expression = '';
expressionArray = [];
screenArray = [];
parentheses = 0;
ansOnScreen = false;
ans = null;
error = false;
inverted = false;
\$('.result').html('');
\$('.screentext').html('');
\$('.hints').html('');
}

function toggleInverted() {
\$('.cbfun .inv').toggle();
inverted = inverted ? false : true;
}

\$('.hints').html(')'.repeat(num));
}

function writeToScreen(mode, text) {

if (mode == 'append') {
if (error) {
screenArray = [];
}
error = false;
screenArray.push(text);
} else if (mode == 'write') {
screenArray = [text];
} else if (mode == 'delete') {
var popped = screenArray.pop();
if (/[(]\$/g.test(popped)) {
parentheses > 0 ? parentheses-- : parentheses = 0;
}
}

\$('.screentext').html(screenArray.join(''));

if (inverted) {
toggleInverted();
}
}

expressionArray.push(text);
expression += text;
}

function removeFromExpression() {
var count = expressionArray.pop().length;
expression = expression.slice(0, -count);
}

// ask for a result ----------------------------------------------------------
\$('.enter').click(
function() {

if (ansOnScreen) {
expressionArray = [ans];
}

try {
math.eval(expressionArray.join('')).toPrecision(8);
} catch (e) {
error = true;
}

if (error) {
defaults();
error = true;
writeToScreen('write', 'Syntax Error');
} else {
\$('.result').html(\$('.screentext').html().replace(/Ans/, ans) + ')'.repeat(parentheses) + ' =');
ans = math.eval(expressionArray.join('')).toPrecision(8);
writeToScreen('write', ans.toString().replace(/(\.0+\$)|(0+\$)/g, ''));
\$('.hints').html('');

var el = \$('#screentext');
var newone = el.clone(true);
el.before(newone);
\$(".animated:last").remove();

ansOnScreen = true;
}
parentheses = 0;
expression = '';
expressionArray = [];
}
);

// clear the screen ----------------------------------------------------------
\$('.cbac').click(
function() {
defaults();
}
);

// add a number to the screen ------------------------------------------------
\$('.cbnum').click(
function() {
var key = \$(this).attr('key');

if (inverted) {
toggleInverted();
}

if (ansOnScreen) {
\$('.result').html('Ans = ' + \$('.screentext').html());
writeToScreen('write', '');
ansOnScreen = false;
}

writeToScreen('append', \$(this).html());
}
);

// add an operator to the screen if there's no other operator ----------------
\$('.cbop').click(
function() {
var key = \$(this).attr('key');
var char = \$(this).attr('char');
if (inverted) {
toggleInverted();
}

if (ansOnScreen) {
\$('.result').html('Ans = ' + \$('.screentext').html());
writeToScreen('write', 'Ans');
expression = ans;
expressionArray = [ans];
parentheses = 0;
\$('.hints').html('');
ansOnScreen = false;
}

if ((/[/]\$|[*]\$/g.test(expression) && (key == '/' || key == '*'))) {
writeToScreen('write', \$('.screentext').html().replace(/[÷]\$|[×]\$/g, char));
removeFromExpression();
} else if (/[+]\$|[-]\$/g.test(expression) && (key == '+' || key == '-')) {
writeToScreen('write', \$('.screentext').html().replace(/[+]\$|[-]\$/g, char));
removeFromExpression();
} else {
writeToScreen('append', char);
}

ansOnScreen = false;
}
);

// add a parentheses both to screen and to a global var ----------------------
\$('.cbpar').click(
function() {
var key = \$(this).attr('key');
if (inverted) {
toggleInverted();
}

if (ansOnScreen) {
writeToScreen('write', '');
ansOnScreen = false;
}

writeToScreen('append', key);

if (key == '(') {
parentheses++;
} else if (key == ')') {
parentheses > 0 ? parentheses-- : parentheses = 0;
}

}

);

// add a function, change parentheses ----------------------------------------
\$('.cbfun').click(
function() {
var key1 = \$(this).attr('key1');
var key2 = \$(this).attr('key2');

if (ansOnScreen) {
writeToScreen('write', '');
ansOnScreen = false;
}

if (!inverted) {
} else {
}

writeToScreen('append', \$(this).html() + '(');

parentheses++;

if (inverted) {
toggleInverted();
}

}
);

// append the old result to the expression-----------------------------------------
\$('.cbans').click(
function() {
if (ansOnScreen) {
writeToScreen('write', '');
ansOnScreen = false;
}
if (!/[Ans]\$|[0-9]\$|[π]\$|[e]\$/g.test(\$('.screentext').html())) {
writeToScreen('append', 'Ans');
}

}
);

// invert trig functions ----------------------------------------------------------
\$('.cbinv').click(
function() {
toggleInverted();
}
);

// backspace -----------------------------------------------------------------------
\$('.cbce').click(
function() {
if (inverted) {
toggleInverted();
}
if (ansOnScreen) {
writeToScreen('write', '');
ansOnScreen = false;
}

if (expressionArray.length) {
removeFromExpression();
writeToScreen('delete', '');
}

}
);

// Insert a random number ---------------------------------------------------------
\$('.cbrnd').click(
function() {
var key = Math.random().toPrecision(8);

if (inverted) {
toggleInverted();
}

if (ansOnScreen) {
\$('.result').html('Ans = ' + \$('.screentext').html());
writeToScreen('write', '');
ansOnScreen = false;
}