You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现CSS关键帧动画平滑衔接:中途点击从当前状态过渡

解决动画中途点击从当前状态触发关闭的问题

核心思路和你设想的一致,通过JS实时记录元素的当前状态,点击时动态修改动画的起始参数,具体实现步骤如下:

  • 实时捕获当前状态:每次点击触发动画切换前,用getBoundingClientRect()获取元素实时的宽高、位置信息,将这些值存入变量保存。
  • 动态生成关闭动画关键帧:不用固定的CSS关键帧,而是通过JS创建@keyframes规则,把关闭动画的from值设为刚才保存的当前状态,to值设为初始的小矩形尺寸。
  • 重置动画触发逻辑:切换动画前先移除旧的动画类,通过读取offsetWidth强制触发浏览器重排,再添加新的动画类,确保动画从新的起始状态运行。

具体代码示例

// 存储元素实时状态的变量
let currentState = {};

// 点击切换动画的处理函数
const toggleAnimation = () => {
  const box = document.querySelector('.box');
  const isExpanded = box.classList.contains('expanded');
  
  // 获取元素当前的实时位置与尺寸
  const rect = box.getBoundingClientRect();
  currentState = {
    width: `${rect.width}px`,
    height: `${rect.height}px`,
    top: `${rect.top}px`,
    left: `${rect.left}px`
  };
  
  if (isExpanded) {
    // 动态生成关闭动画的关键帧
    const closeKeyframes = `@keyframes close {
      from {
        width: ${currentState.width};
        height: ${currentState.height};
        top: ${currentState.top};
        left: ${currentState.left};
        transform: none;
      }
      to {
        width: 100px;
        height: 100px;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
    }`;
    
    // 插入关键帧到页面样式表
    const styleEl = document.createElement('style');
    styleEl.textContent = closeKeyframes;
    document.head.appendChild(styleEl);
    
    // 重置动画状态,确保从当前状态开始播放
    box.classList.remove('expanded');
    void box.offsetWidth; // 强制触发重排,清除旧动画状态
    box.classList.add('closing');
  } else {
    // 展开动画逻辑,移除关闭类后触发展开动画
    box.classList.remove('closing');
    void box.offsetWidth;
    box.classList.add('expanded');
  }
};

// 绑定点击事件
document.querySelector('.box').addEventListener('click', toggleAnimation);

对应的基础CSS样式:

.box {
  position: fixed;
  width: 100px;
  height: 100px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #2c3e50;
  cursor: pointer;
}

.expanded {
  animation: expand 0.6s forwards;
}

@keyframes expand {
  to {
    width: 100vw;
    height: 100vh;
    top: 0;
    left: 0;
    transform: none;
  }
}

.closing {
  animation: close 0.6s forwards;
}

注意事项

  • 每次生成新关键帧时,可给关键帧名称加时间戳等唯一标识,避免样式冲突;或者在插入新样式前移除旧的样式元素,防止样式表冗余。
  • 若需要支持更复杂的动画属性(比如背景色、圆角),只需在currentState中添加对应属性的实时值,同步到关键帧即可。

内容的提问来源于stack exchange,提问作者HelloToxicity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 04:40:34