<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
<div id="app"></div>
body {
background-image: url("https://as2.ftcdn.net/v2/jpg/03/16/66/51/1000_F_316665148_kVX47Jb06tVnzL14TYs1mEpur9bBnQsN.jpg");
background-size: cover;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
font-family: "VT323", monospace;
font-size: 30px;
}
* {
box-sizing: border-box;
}
#calculator {
width: 250px;
min-height: 400px;
border: 2px solid red;
background-color: #730545;
color: white;
display: flex;
flex-direction: column;
border-radius: 5px;
box-shadow: 0 10px 20px 3px red;
}
h4 {
margin: 0;
margin-bottom: 10px;
color: red;
}
#display {
border: 2px solid black;
min-height: 80px;
max-height: 100px;
margin: 5px;
padding: 5px;
text-align: end;
background-color: #ffea03;
border: 4px solid black;
color: black;
word-wrap: break-word;
}
#prevOp {
font-size: 20px;
opacity: 75%;
}
button {
font-size: 25px;
border: none;
border-radius: 50%;
height: 50px;
width: 50px;
margin: 5px;
background-color: black;
color: yellow;
border: 2px solid yellow;
font-family: "VT323", monospace;
font-size: 30px;
box-shadow: 0 3px 0 2px black;
}
button:active {
transform: scale(95%);
box-shadow: 0 1px 0 2px black;
}
button:hover {
opacity: 75%;
cursor: pointer;
}
button:focus {
outline: none;
}
#buttons {
display: flex;
height: 75%;
margin-bottom: 5px;
margin-top: 15px;
position: relative;
}
#num-box {
width: 75%;
display: flex;
flex-wrap: wrap;
align-items: center;
}
#op-box {
width: 25%;
}
#op-box button {
background-color: #14a307;
color: black;
}
.span-two-h {
width: 110px;
border-radius: 50px;
}
.span-two-v {
height: 110px;
border-radius: 50px;
}
.multiplication {
position: absolute;
right: 65px;
}
#clear {
margin-right: 50px;
background-color: #a60202;
}
. {
width: 300px;
}
const nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const operators = ["*", "-", "+", "/"];
const revNums = nums.reverse();
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
num: 0,
last: "",
evaluated: false,
};
this.handleResetClick = this.handleResetClick.bind(this);
this.handlePointClick = this.handlePointClick.bind(this);
this.handleEqualsClick = this.handleEqualsClick.bind(this);
}
//everything is erased
handleResetClick(e) {
this.setState({
num: 0,
last: "",
evaluated: true
})
}
//this.state.last value goes to API call and we get the answer
handleEqualsClick() {
this.setState({
num: math.evaluate(this.state.last),
last: `${this.state.last}=${math.evaluate(this.state.last)}`,
evaluated: true,
})
}
//concatination of whatever we have written and decimal point
handlePointClick(e) {
this.setState({
num: this.state.num + e.target.innerText,
last: this.state.last + e.target.innerText
})
}
render() {
const { num, last, evaluated } = this.state;
//main logic is here whenever most buttons are pressed
const handleClick = (e) => {
const value = e.target.innerText;
//for some reason this last condition doesn't work and passes 0 multiple times
this.setState(
this.state.num === 0 || isNaN(this.state.num) || evaluated || (this.state.num === 0 && value === "0")
? ({num: value, evaluated: false})
: ({num: this.state.num + value})
);
this.setState(
this.state.last === "" || evaluated
? ({last: value, evaluated: false})
: ({last: this.state.last + value})
)
}
return (
<div>
<h4>Calculator By JakChi</h4>
<div id="calculator">
<div id="display">
<div id="prevOp">{last}</div>
<div id="currentOp">{num}</div>
</div>
<div id="buttons">
<div id="num-box">
{/*this is reset button*/}
<button
id="clear"
className="span-two-h"
onClick={(e) => this.handleResetClick(e)}
>
AC
</button>
{/*all numbers on calculator are rendered by map method*/}
{revNums.map((num, key) => {
return (
<button
className={`${num === 0 ? "span-two-h" : null}`}
onClick={handleClick}
key={key}
>
{num}
</button>
);
})}
{/*decimal point*/}
<button
id="decimal"
style={{ backgroundColor: "green" }}
onClick={(e) => this.handlePointClick(e)}
>
.
</button>
</div>
{/*this are all signs from operators*/}
<div id="op-box">
{operators.map((op, key) => (
<button
className={`${op === "*" ? "multiplication" : null }`}
onClick={handleClick}
key={key}
>
{op}
</button>
))}
{/*Equals operator*/}
<button
id="equals"
onClick = {(e) => this.handleEqualsClick(e)}
className = "span-two-v"
>
=
</button>
</div>
</div>
</div>
</div>
);
}
}
const calculateValue = (current, prev, operation) => {
const currentNum = parseInt(current);
const prevNum = parseInt(prev);
const result = 0;
switch (operation) {
case "*":
result = prevNum * currentNum;
break;
case "+":
result = prevNum + currentNum;
break;
case "-":
result = prevNum - currentNum;
break;
case "/":
result = prevNum / currentNum;
break;
default:
result = "0000";
}
return result.toString();
};
ReactDOM.render(<App />, document.getElementById("app"));
View Compiled
This Pen doesn't use any external CSS resources.