Check out this noice light saber progress! Was fun to make. I'll maybe do a series with other famous light sabers!
A Pen by Andy Pagès on CodePen.
<div id="root"></div> |
Check out this noice light saber progress! Was fun to make. I'll maybe do a series with other famous light sabers!
A Pen by Andy Pagès on CodePen.
class DarthVaderSaber extends React.Component { | |
render() { | |
const laserMax = 630 | |
const percent = this.props.percent >= 1 ? 1 : this.props.percent | |
const glowStyle = percent >= 1 ? 'laser-glow laser-glow-active' : 'laser-glow' | |
const width = percent * laserMax | |
const laserStyle = { width: width + 'px' } | |
const laserClass = percent >= 1 ? 'laser laser-active' : 'laser' | |
return ( | |
<div className="saber darth-vader-saber"> | |
<div className="handle"> | |
<div className="tip"></div> | |
<div className="grip grip1"></div> | |
<div className="grip grip2"></div> | |
<div className="grip grip3"></div> | |
<div className="center"></div> | |
<div className="laser"></div> | |
<div className="center-bottom"> | |
<div className="screw"></div> | |
</div> | |
<div className="cables"> | |
<div className="hole hole1"></div> | |
<div className="hole hole2"></div> | |
<div className="cable cable1"></div> | |
<div className="cable cable2"></div> | |
</div> | |
<div className="shadow"></div> | |
<div className={laserClass} style={laserStyle}> | |
<div className={glowStyle}></div> | |
<div className="laser-tip"> | |
<div className={glowStyle}></div> | |
</div> | |
</div> | |
<div className="guard-tip"></div> | |
<div className="guard-rectangle"> | |
<div className="shadow"></div> | |
</div> | |
<div className="guard-triangle"> | |
</div> | |
<div className="guard-triangle-shadow"></div> | |
</div> | |
</div> | |
) | |
} | |
} | |
class Demo extends React.Component { | |
state = { percent: 0 } | |
componentDidMount() { | |
this.interval = setInterval( | |
() => { | |
if (this.state.percent >= 1) { | |
clearInterval(this.interval) | |
} else { | |
this.setState({ percent: this.state.percent + 0.001 }) | |
} | |
}, | |
5 | |
) | |
} | |
render() { | |
const { percent } = this.state | |
return ( | |
<div className="saber-demo"> | |
<h1>Loading</h1> | |
<div className="percent">{(percent * 100).toFixed(0)}%</div> | |
<DarthVaderSaber percent={percent} /> | |
</div> | |
) | |
} | |
} | |
ReactDOM.render(<Demo />, document.getElementById('root')) |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script> |
@font-face { | |
font-family: Starjedi; | |
src: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/718469/Starjedi.ttf); | |
font-weight: normal; | |
} | |
@import url('https://fonts.googleapis.com/css?family=Luckiest+Guy'); | |
body { | |
background-color: white; | |
margin: 0; | |
} | |
.darth-vader-saber { | |
height: 65px; | |
width: 880px; | |
position: relative; | |
.handle { | |
width: 220px; | |
height: 40px; | |
background-color: #BABABA; | |
border-radius: 12px; | |
position: absolute; | |
left: 0; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
.shadow { | |
width: 220px; | |
height: 20px; | |
background-color: rgba(255, 255, 255, 0.2); | |
position: absolute; | |
left: 0; | |
bottom: 0; | |
border-bottom-left-radius: 8px; | |
} | |
.tip { | |
width: 8px; | |
height: 40px; | |
background-color: #363636; | |
border-top-left-radius: 12px; | |
border-bottom-left-radius: 12px; | |
} | |
.grip { | |
width: 80px; | |
height: 10px; | |
background-color: #212121; | |
position: absolute; | |
} | |
.grip1 { | |
left: 8px; | |
top: 0px; | |
} | |
.grip2 { | |
left: 8px; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
} | |
.grip3 { | |
left: 8px; | |
bottom: 0px; | |
} | |
.center { | |
width: 50px; | |
height: 40px; | |
position: absolute; | |
background-color: #212121; | |
left: 110px; | |
top: 0; | |
} | |
.center-bottom { | |
width: 40px; | |
height: 12px; | |
position: absolute; | |
background-color: #363636; | |
left: 115px; | |
bottom: -12px; | |
.screw { | |
width: 5px; | |
height: 5Px; | |
border-radius: 50%; | |
background-color: #BABABA; | |
position: absolute; | |
top: 0; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
margin: auto; | |
} | |
} | |
.cables { | |
.hole { | |
width: 4px; | |
height: 12px; | |
background-color: #444444; | |
position: absolute; | |
top: 20px; | |
margin: auto; | |
border-radius: 30px; | |
} | |
.hole1 { | |
left: 175px; | |
} | |
.hole2 { | |
left: 185px; | |
} | |
.cable { | |
height: 2px; | |
width: 11px; | |
background-color: red; | |
position: absolute; | |
top: 23px; | |
margin: auto; | |
left: 175px; | |
} | |
.cable1 { | |
top: 24px; | |
left: 177px; | |
} | |
.cable2 { | |
top: 26px; | |
left: 177px; | |
background-color: orange; | |
} | |
} | |
.guard-tip { | |
width: 40px; | |
height: 15px; | |
background-color: #212121; | |
position: absolute; | |
top: -5px; | |
left: 180px; | |
} | |
.guard-rectangle { | |
width: 20px; | |
height: 45px; | |
background-color: #212121; | |
position: absolute; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
left: 210px; | |
.shadow { | |
width: 20px; | |
height: 22.5px; | |
background-color: rgba(255, 255, 255, 0.2); | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
} | |
} | |
.guard-triangle { | |
width: 0; | |
height: 0; | |
border-style: solid; | |
border-width: 45px 35px 0 0; | |
border-color: #212121 transparent transparent transparent; | |
position: absolute; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
left: 230px; | |
} | |
.guard-triangle-shadow { | |
width: 0; | |
height: 0; | |
border-style: solid; | |
border-width: 22.5px 17px 0 0; | |
border-color: rgba(255, 255, 255, 0.2) transparent transparent transparent; | |
position: absolute; | |
bottom: -2px; | |
left: 230px; | |
} | |
} | |
.laser-active { | |
box-shadow: 30px 0 30px #FC3030; | |
animation: glowNeon 80ms linear infinite; | |
animation-direction: alternate-reverse; | |
} | |
.laser { | |
height: 35px; | |
background-color: red; | |
position: absolute; | |
left: 220px; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
.laser-glow { | |
width: 100%; | |
height: 20px; | |
background-color: rgba(255, 255, 255, 0.96); | |
position: absolute; | |
left: 0; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
} | |
.laser-glow-active { | |
animation: glow 80ms linear infinite; | |
animation-direction: alternate-reverse; | |
} | |
.laser-tip { | |
height: 35px; | |
width: 30px; | |
background-color: red; | |
position: absolute; | |
right: -30px; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
border-top-right-radius: 50%; | |
border-bottom-right-radius: 50%; | |
.laser-glow { | |
width: 80%; | |
border-top-right-radius: 50%; | |
border-bottom-right-radius: 50%; | |
} | |
} | |
@keyframes glowNeon { | |
from { | |
box-shadow: 30px 0 30px #FC3030; | |
} | |
to { | |
box-shadow: 30px 0 26px #FC3030; | |
} | |
} | |
@keyframes glow { | |
from { | |
background-color: rgba(255, 255, 255, 0.96); | |
} | |
to { | |
background-color: rgba(255, 255, 255, 0.92); | |
} | |
} | |
} | |
} | |
.saber-demo { | |
width: 100%; | |
height: 180px; | |
position: absolute; | |
text-align: center; | |
top: 0; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
margin: auto; | |
h1 { | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
margin: auto; | |
font-family: 'Starjedi'; | |
color: #212121; | |
} | |
.saber, { | |
position: absolute; | |
top: 100px; | |
left: 0; | |
right: 0; | |
margin: auto; | |
} | |
.percent { | |
color: #D2D5D6; | |
position: absolute; | |
top: 60px; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
margin: auto; | |
font-family: 'Luckiest Guy'; | |
font-size: 30px; | |
} | |
} |