<div id="root" class="root">
<div class="container">
<div class="header">
<div class="menu">
<span class="hamb">
<span class="row"></span>
<span class="row"></span>
<span class="row"></span>
</span>
</div>
<svg class="curve-background">
<path class="curve-open"
fill="#313131"
d="M740,60 L740,0 680,0 C690,50, 690,50 740,60"/>
<path class="curve-close"
fill="#FFD34E"
d="M0,405 L0,405 740,405 740,405 C370,440 370,440 740,405"/>
</svg>
<div class="search">
<svg class="search-icon" enable-background="new 0 0 50 50" height="34px"
viewBox="0 0 50 50" width="34px">
<rect fill="none" height="50" width="50"/>
<circle cx="21" cy="20" fill="none" r="15" stroke="#fff" stroke-width="5"/>
<line class="search-line" fill="none" stroke="#fff" stroke-width="5" x1="32.229" x2="49.9" y1="32.229" y2="49.9"/>
</svg>
<span class="close">✖</span>
</div>
</div>
<div class="text">
<h1 class="search-text">search</h1>
<input type="text" class="search-input"/>
</div>
<div class="intro">
<h1>Click Search Button</h1>
</div>
<div class="footer">
<ul class="list">
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
</ul>
</div>
</div>
</div>
$containerWidth = 740px
$containerHeight = 435px
$buttonWidth = 60px
$footerHeight = 30px
@import url(https://fonts.googleapis.com/css?family=Roboto:500,500italic,400,400italic,300,300italic);
@keyframes search-open {
50% {
transform translate3d(-350px, 187px,0) rotate(180deg)
}
100% {
transform translate3d(-225px, 187px,0) rotate(360deg)
}
}
@keyframes search-close {
0%{
transform translate3d(-225px, 187px,0) rotate(0deg)
}
100%{
transform translate3d(0px,0px,0) rotate(360deg)
}
}
*
box-sizing border-box
html
body
height 100%
body
margin 0
padding 0
background #FFD34E
font-family 'Roboto', serif
#root
display flex
height inherit
.container
width $containerWidth
height $containerHeight
background #FFD34E
margin auto
box-shadow 0 0 20px 5px rgba(0,0,0,.2)
display flex
flex-direction column
justify-content space-between
position relative
.curve-background
overflow hidden
position absolute
width $containerWidth
left 0
height $containerHeight - $footerHeight
/.search-open & .curve-close
opacity 0
/.search-close & .curve-close
opacity 1
.header
display flex
justify-content space-between
.menu
.search
width $buttonWidth
height $buttonWidth
background #313131
transition background .5s ease-out 0s
z-index 50
position relative
cursor pointer
/.search-open &
background #FFD34E
/.search-close &
background #313131
.close
opacity 0
font-size 2.5rem
color white
position absolute
left 15px
top 0
/.search-open &
opacity 1
/.search-close &
opacity 0
.menu
border-bottom-right-radius 50%
text-align center
line-height 70px
.hamb
display inline-block
width 30px
height 18px
line-height 0
.row
display inherit
background #fff
height 4px
margin-bottom 3px
width 100%
.search
border-bottom-left-radius 50%
text-align center
padding 13px 0
circle
.search-line
stroke white
transition stroke .4s ease-out
/.search-open & .search-icon
animation search-open 1s forwards
circle
.search-line
stroke #313131
/.search-close & .search-icon
animation search-close .5s forwards
circle
.search-line
stroke white
.text
text-align center
color white
z-index 10
font-size 1.3rem
margin-top -90px
transition opacity .5s ease-in
.search-input
height 40px
border none
border-radius 3px
width 0
transition all .5s ease-out .4s
padding 0
/.search-open &
width 270px
/.search-close &
transition all 0s
width 0
.search-text
transform translate(0, 40px)
margin 0
transition all .5s ease-out .4s
opacity 0
margin-bottom 10px
/.search-open &
opacity 1
transform translate(0,0)
/.search-close &
transition all 0s
transform translate(0, 40px)
opacity 0
.intro
color white
text-align center
position absolute
top 165px
width 100%
transition opacity .3s ease-in
/.search-open &
opacity 0
/.search-close &
opacity 1
.footer
background white
height $footerHeight
text-align center
line-height @height
.list
margin 0
padding 0
display inline-block
list-style none
.list-item
display inline-block
width 7px
height 7px
border-radius 7px
margin-right 15px
background silver
View Compiled
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
window.onload = ()=>{
let $search = document.querySelector('.search');
let $root = document.querySelector('.root');
let $curveOpen = document.querySelector('.curve-open');
let $curveClose = document.querySelector('.curve-close');
let stateOpen = {topPointX:680,
bottomPointY:60,
curvePointX:690,
curvePointY:50};
let propsOpen = {topPointX:-150,
bottomPointY:500,
curvePointX:-150,
curvePointY:450};
let stateClose = {
leftPointY:405,
rightPointY:405,
curvePointY:500
};
let propsClose = {
leftPointY:0,
rightPointY:0,
curvePointY:0
};
let drawClose = ({leftPointY,rightPointY,curvePointY}) =>{
$curveClose.setAttribute('d',`M0,${leftPointY} L0,405 740,405 740,${rightPointY} C370,${curvePointY} 370,${curvePointY} 0,${leftPointY}`)
};
let drawOpen = ({topPointX, bottomPointY, curvePointX, curvePointY})=>{
$curveOpen.setAttribute('d',`M740,${bottomPointY} L740,0 ${topPointX},0 C${curvePointX},${curvePointY} ${curvePointX},${curvePointY} 740,${bottomPointY}`)
};
$search.addEventListener('click',()=>{
let classes = $root.classList;
if(classes.contains('search-open') && classes.contains('search-close')){
classes.remove('search-close');
animate(300, drawOpen, stateOpen, propsOpen);
}else if(classes.contains('search-open')){
classes.add('search-close');
animate(300, drawClose, stateClose, propsClose);
}else{
classes.add('search-open');
animate(300, drawOpen, stateOpen, propsOpen);
}
});
let animate = (time, draw, state, props) =>{
let fCount = 1;
let start = performance.now();
let framesCount = time/(1000 / 60);
let keys = Object.keys(props);
let deltaState = {};
let stepState = {};
keys.map((i)=>{
(state[i] < props[i])?
deltaState[i] = (props[i] - state[i])
:deltaState[i] = -(state[i] - props[i])
});
let _animate = (timestamp) =>{
if((timestamp - start) < time){
keys.map((j)=>{
stepState[j] = state[j] + (deltaState[j]*(fCount/framesCount))
});
draw(stepState);
fCount++;
requestAnimFrame(_animate)
}else{
if(fCount <= framesCount){
draw(props);
}
}
};
requestAnimFrame(_animate);
}
};
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.