Reputation: 241
My goal: Achieve a smooth animation of sidemenu as this one of google (use button at top left corner on mobile version). (Animation smoothness i measure with a non high-end phone.)
I decided to test the absolutely most simple animation possible, and so created a draft at jsbin. Since then (several days) am really puzzled from the results - the ultimately most simple animation performs drastically worse than google's. (Ive tested mine on a dedicated url, so jsbin is not messing anything.)
Additionally there is the yandex translator with a similar menu (button is at top right). For sure there are other such good animations on the internet, but how do they play smoother than the most minimal setup?
I would set a bounty on this question as it is really important for me, but ... not enough reputation.
And second additionally - when testing my animations with 24 children in the animatables, results have no difference. I always thought that children count is important to be kept low.
[Ignore the following, stackoverflow forces me to paste it]
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Sideanimations 0 children">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Sideanimations</title>
</head>
<body>
<div class='buttonsholder'>
<button onclick='ff1()'>by size</button>
<button onclick='ff2()'>by position</button>
<button onclick='ff3()'>both + rounded</button>
</div>
<div id='fikmic1'></div>
<div id='fikmic2'></div>
<div id='fikmic3'></div>
<style>
body{
width:100vw;
height:100vh;
overflow:hidden;
}
.buttonsholder{
position:absolute;
bottom:50vh;
right:0px;
width:0px;
}
button{
display:block;
float:right;
text-align:right;
padding:0px 1vw;
margin:.5vw 1vw;
}
#fikmic1{
display:none;
position:absolute;
top:0vh;
left:0vw;
width:0vw;
height:100vh;
background-color:#777;
transition:.7s;
}
#fikmic2{
display:none;
position:absolute;
top:0vh;
left:-80vw;
width:80vw;
height:100vh;
background-color:#333;
transition:.7s;
}
#fikmic3{
display:none;
position:absolute;
top:50vh;
left:0vw;
width:0vw;
height:0vh;
background-color:#aaa;
border-radius:100%;
transition:.7s;
}
</style>
<script>
function ff1(){
var c = document.getElementById('fikmic1');
if(c.getAttribute('gefikt') === null){
c.setAttribute('gefikt', '');
c.style.display = 'block';
setTimeout(function(){
c.style.width = '80vw';
}, 50);
}
else{
c.removeAttribute('gefikt');
c.style.width = '0vw';
setTimeout(function(){
c.style.display = 'none';
}, 700);
}
}
function ff2(){
var c = document.getElementById('fikmic2');
if(c.getAttribute('gefikt') === null){
c.setAttribute('gefikt', '');
c.style.display = 'block';
setTimeout(function(){
c.style.left = '0vw';
}, 50);
}
else{
c.removeAttribute('gefikt');
c.style.left = '-80vw';
setTimeout(function(){
c.style.display = 'none';
}, 700);
}
}
function ff3(){
var c = document.getElementById('fikmic3');
if(c.getAttribute('gefikt') === null){
c.setAttribute('gefikt', '');
c.style.display = 'block';
setTimeout(function(){
c.style.top = (((window.innerHeight/100) * 50) - ((window.innerWidth/100) * 80)) + 'px';
c.style.left = '-80vw';
c.style.width = '160vw';
c.style.height = '160vw';
}, 50);
}
else{
c.removeAttribute('gefikt');
c.style.top = ((window.innerHeight/100) * 50) + 'px';
c.style.left = '0vw';
c.style.width = '0vw';
c.style.height = '0vw';
setTimeout(function(){
c.style.display = 'none';
}, 700);
}
}
</script>
</body>
</html>
Upvotes: 2
Views: 311
Reputation: 3217
Animating a CSS transform
will be much more efficient than animating left
, width
, etc. "Modern browsers can animate four things really cheaply: position, scale, rotation and opacity."
When animating your first side menu, set the transform-origin
property to left
, so that the animation is centered on the left side of the menu. (The default origin is center
, which isn't what you want in this case.)
I made a revised version of your JS Bin, and also posted it as a snippet below.
function ff1(){
var c = document.getElementById('fikmic1');
if(c.getAttribute('gefikt') === null){
c.setAttribute('gefikt', '');
c.style.display = 'block';
setTimeout(function(){
c.style.transform = 'scaleX(1)';
}, 50);
}
else{
c.removeAttribute('gefikt');
c.style.transform = 'scaleX(0)';
setTimeout(function(){
c.style.display = 'none';
}, 700);
}
}
function ff2(){
var c = document.getElementById('fikmic2');
if(c.getAttribute('gefikt') === null){
c.setAttribute('gefikt', '');
c.style.display = 'block';
setTimeout(function(){
c.style.transform = 'translateX(0vw)';
}, 50);
}
else{
c.removeAttribute('gefikt');
c.style.transform = 'translateX(-80vw)';
setTimeout(function(){
c.style.display = 'none';
}, 700);
}
}
function ff3(){
var c = document.getElementById('fikmic3');
if(c.getAttribute('gefikt') === null){
c.setAttribute('gefikt', '');
c.style.display = 'block';
setTimeout(function(){
c.style.transform = 'scale(1)';
}, 50);
}
else{
c.removeAttribute('gefikt');
c.style.transform = 'scale(0)';
setTimeout(function(){
c.style.display = 'none';
}, 700);
}
}
body{
width:100vw;
height:100vh;
overflow:hidden;
}
.buttonsholder{
display:flex;
flex-direction:column;
align-items:flex-end;
justify-content:center;
height:100%;
}
button{
width:4rem;
text-align:right;
padding:0 .2rem;
margin:.4rem .8rem;
}
#fikmic1{
display:none;
position:absolute;
top:0vh;
left:0vw;
width:80vw;
height:100vh;
transform:scaleX(0);
transform-origin:left;
background-color:#777;
transition:.7s;
}
#fikmic2{
display:none;
position:absolute;
top:0vh;
left:0vw;
width:80vw;
height:100vh;
transform:translateX(-80vw);
background-color:#333;
transition:.7s;
}
#fikmic3{
display:none;
position:absolute;
top:calc(50vh - 80vw);
left:-80vw;
width:160vw;
height:160vw;
transform:scale(0);
background-color:#aaa;
border-radius:100%;
transition:.7s;
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Sideanimations by transform">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Sideanimations</title>
</head>
<body>
<div class='buttonsholder'>
<button onclick='ff1()'>by size</button>
<button onclick='ff2()'>by position</button>
<button onclick='ff3()'>both + rounded</button>
</div>
<div id='fikmic1'></div>
<div id='fikmic2'></div>
<div id='fikmic3'></div>
</body>
</html>
Upvotes: 1