Pulse anything by wrapping a parent div in a component
A Pen by Mohammad Sabir on CodePen.
ddddddd |
Pulse anything by wrapping a parent div in a component
A Pen by Mohammad Sabir on CodePen.
const Pulse = React.createClass({ | |
propTypes: { | |
delay: React.PropTypes.number | |
}, | |
getDefaultProps() { | |
return { | |
delay: 0 | |
}; | |
}, | |
getInitialState() { | |
return { | |
pulsing: false | |
}; | |
}, | |
componentDidMount() { | |
this.schedulePulse(this.props.delay); | |
}, | |
schedulePulse(delay) { | |
delay = delay || 1000; | |
setTimeout(this.startPulse, delay); | |
}, | |
startPulse() { | |
this.setState({ pulsing: true }); | |
}, | |
onPulseEnd() { | |
$(this.refs.pulse).addClass('reset'); | |
this.setState({ pulsing: false }); | |
this.schedulePulse(); | |
}, | |
render() { | |
return ( | |
<div ref="pulse" onTransitionEnd={this.onPulseEnd} className={this.getPulseClasses()}> | |
{this.props.children} | |
{this.renderPulse()} | |
</div> | |
); | |
}, | |
renderPulse() { | |
return ( | |
<div className="shape-pulse"> | |
{this.getClonedChild()} | |
</div> | |
); | |
}, | |
getPulseClasses() { | |
return `shape-wrapper${this.state.pulsing ? ' pulsing' : ''}`; | |
}, | |
getClonedChild() { | |
return React.cloneElement(this.props.children); | |
} | |
}); | |
const Root = React.createClass({ | |
render() { | |
return ( | |
<div id="root-element"> | |
{this.renderCircle()} | |
{this.renderHeart()} | |
{this.renderSquare()} | |
</div> | |
); | |
}, | |
renderCircle() { | |
return ( | |
<div className="shape-container"> | |
<Pulse delay={1000}> | |
<div className="shape circle"/> | |
</Pulse> | |
</div> | |
); | |
}, | |
renderHeart() { | |
return ( | |
<div className="shape-container"> | |
<Pulse delay={1200}> | |
<div className="shape heart"> | |
<div/> | |
<div/> | |
<div/> | |
</div> | |
</Pulse> | |
</div> | |
); | |
}, | |
renderSquare() { | |
return ( | |
<div className="shape-container"> | |
<Pulse delay={1400}> | |
<div className="shape square"/> | |
</Pulse> | |
</div> | |
); | |
} | |
}); | |
ReactDOM.render(<Root/>, document.body); |
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js"></script> |
@import "compass/css3"; | |
$icon-size: 2.5em; | |
$color1: rgb(05, 19, 25); | |
$color2: rgb(225, 121, 25); | |
$color3: rgb(72, 195, 225); | |
$color4: rgb(180, 20, 110); | |
$shape-color: $color2; | |
html { height: 100% } | |
body { | |
display: flex; | |
font-family: 'Open Sans', sans-sarif; | |
font-size: 16px; | |
background-color: $color1; | |
height: 100%; | |
width: 100%; | |
} | |
#root-element { | |
display: flex; | |
flex-direction: row; | |
align-items: center; | |
justify-content: center; | |
width: 100%; | |
} | |
.shape-container { | |
display: flex; | |
width: 8em; | |
height: 8em; | |
align-items: center; | |
justify-content: center; | |
} | |
.shape { | |
width: $icon-size; | |
height: $icon-size; | |
} | |
.circle { | |
background-color: $shape-color; | |
border-radius: $icon-size; | |
} | |
.heart { | |
position: relative; | |
& > div { | |
background-color: $color4; | |
position: absolute; | |
width: 55%; | |
height: 55%; | |
&:nth-child(1) { | |
border-radius: 50%; | |
left: 0; | |
top: 11%; | |
} | |
&:nth-child(2) { | |
position: absolute; | |
border-radius: 50%; | |
top: 11%; | |
right: 0; | |
} | |
&:nth-child(3) { | |
position: absolute; | |
transform: rotate(45deg); | |
border-radius: 15% 0 15% 0; | |
width: 58%; | |
height: 58%; | |
right: 21%; | |
bottom: 11%; | |
} | |
} | |
} | |
.square { | |
background-color: $color3; | |
border-radius: 15%; | |
} | |
.shape-wrapper { | |
position: relative; | |
&.reset { | |
.shape-pulse { | |
transition: none; | |
transform: scale(1,1); | |
opacity: 1; | |
} | |
} | |
&.pulsing { | |
.shape-pulse { | |
transform: scale(2.3,2.3); | |
opacity: 0; | |
} | |
} | |
} | |
.shape-pulse { | |
transition: transform 1s ease-in-out, opacity 1s ease-in-out; | |
position: absolute; | |
opacity: 0.5; | |
transform: scale(1,1); | |
top: 0; | |
left: 0; | |
} |