使用这种缩放动画的方法,第一步就是要知道元素展开和收缩时的尺寸。有些情况下你不能一次就得到所有信息,此时你需要切换不同的类来获取元素的不同状态。如果你这样做的话,需要注意一点:如果与上次运行相比,样式style发生了改变,getBoundingClientRect()(或offsetWidth和offsetHeight)会强制浏览器更新样式和布局styles and layout。
function calculateCollapsedScale (){ // The menu title can act as the marker for the collapsed state. const collapsed = menuTitle.getBoundingClientRect(); // Whereas the menu as a whole (title plus items) can act as // a proxy for the expanded state. const expanded = menu.getBoundingClientRect(); return{ x: collapsed.width / expanded.width, y: collapsed.height / expanded.height } }
function createKeyframeAnimation (){ // Figure out the size of the element when collapsed. let{x, y}=calculateCollapsedScale(); let animation =''; let inverseAnimation =''; for(let step =0; step <=100; step++){ // Remap the step value to an eased one. let easedStep =ease(step /100); // Calculate the scale of the element. const xScale = x +(1- x)* easedStep; const yScale = y +(1- y)* easedStep; animation +=`${step}% { transform: scale(${xScale}, ${yScale}); }`; // And now the inverse for the contents. const invXScale =1/ xScale; const invYScale =1/ yScale; inverseAnimation +=`${step}% { transform: scale(${invXScale}, ${invYScale}); }`; } return` @keyframes menuAnimation { ${animation} } @keyframes menuContentsAnimation { ${inverseAnimation} }`; }