React
by Abdul Ahmad
HTML
<div id="app"></div>
SCSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
.health-bar {
width: 100px;
height: 20px;
position: relative;
border: 1px solid darken(red, 5%);
border-radius: 20px;
overflow: hidden;
.bar-fill {
position: absolute;
background: lighten(red, 30%);
width: 100%;
height: 100%;
top: 0;
left: 0;
&.animate {
transition: all 1s ease 0.3s;
}
&.instant {
background: red;
z-index: 2;
}
}
.health-bar-status {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 3;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
}
.damage-text {
position: absolute;
font-size: 14px;
color: yellow;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 5px;
box-sizing: border-box;
z-index: 10;
width: 100%;
height: 100%;
top: 0;
left: 0;
span {
letter-spacing: 1px;
text-shadow:
1px 0 0 black,
-1px 0 0 black,
0 1px 0 black,
0 -1px 0 black,
1px 1px black,
-1px -1px 0 black,
1px -1px 0 black,
-1px 1px 0 black;
}
}
}
.button {
margin-top: 10px;
}
React
class TodoApp extends React.Component {
healthBarTextTimeoutId;
state = {
health: 100,
healthBarText: '',
lastHealthbarTextType: '',
};
applyDamage = () => {
clearTimeout(this.healthBarTextTimeoutId);
this.setState(s => {
let newHealth = s.health - 30;
if (newHealth < 0) newHealth = 0;
const healthDiff = s.health - newHealth;
let healthBarText = '';
if (healthDiff > 0) healthBarText = '-' + healthDiff;
return {
health: newHealth,
healthBarText,
lastHealthbarTextType: 'damage',
};
}, () => {
this.healthBarTextTimeoutId = setTimeout(() => {
this.setState({ healthBarText: '' });
}, 1000);
});
};
applyHeal = () => {
clearTimeout(this.healthBarTextTimeoutId);
this.setState(s => {
let newHealth = s.health + 30;
if (newHealth > 100) newHealth = 100;
const healthDiff = newHealth - s.health;
let healthBarText = '';
if (healthDiff > 0) healthBarText = '+' + healthDiff;
return {
health: newHealth,
healthBarText,
lastHealthbarTextType: 'heal',
};
}, () => {
this.healthBarTextTimeoutId = setTimeout(() => {
this.setState({ healthBarText: '' });
}, 1000);
});
};
render() {
const animClassTopFill = this.state.lastHealthbarTextType === 'heal' ? 'animate' : '';
const animClassBotFill = this.state.lastHealthbarTextType === 'damage' ? 'animate' : '';
return (
<div>
<div className='health-bar'>
<div
className={'bar-fill ' + animClassBotFill}
style={{
width: this.state.health + '%',
}}
/>
<div
className={'bar-fill instant ' + animClassTopFill}
style={{
width: this.state.health + '%',
}}
/>
<div className='health-bar-status'>
...