HTML CSS动画笔记

Nenge123 note

HTML CSS动画接口主要有两个,先做个基础了解

事件

  • transition事件

    常见的悬浮操作: run(新)->start->cancel->run(旧)->start->end
    事件驱动: run->start->end

      sequenceDiagram
          原始状态->>过渡过程:    run
          过渡过程->>最后状态:    start
          过渡过程->>最后状态:    end
          原始状态->>过渡过程:    cancel <br>1.display:none<br>2.transition-property属性变化
    
  • animation事件

    悬停间隔短循环播放: start->iteration->start->iteration....->cancel
    悬停时间短于动画播放 start->cancel
    循环一次的完整事件 start->end

      sequenceDiagram
          动画开始->>动画结束:    start
          动画结束->>最后状态:    end         <br>终止动画,停止后续
          动画开始->>动画结束:    cancel      <br>意外终止,停止后续,常见悬停
          动画结束->>最后状态:    iteration   <br>动画循环下一个start
    

基本样式

  • transition样式

    transition:transition-property(属性) transition-duration(持续时间) | transition-timing-function(速率变化函数) | transition-delay(延时执行)
    多个属性变化逗号隔开.
    transition: margin-right 4s ease-in-out 1s; margin-right变化需要4s延迟1s执行.
    transition: margin-right 4s, color 1s; margin-right变化需要4s,颜色1s完成变化.

  • animation样式

  • animation js API控制动画

          function animateScroll(size){
              let eH = document.documentElement,
                  st = eH.scrollTop,sh = eH.scrollHeight-window.innerHeight,sy=st+size>=sh?sh-st:size;;
              let keyframes = [
                      { transform: "translateY("+(0-sy)+"px)" },//from
                      { transform: "translateY("+sy+"px)" },//to
              ];
              let options = {
                      //delay 延迟开始动画多少ms 默认值0
                      //endDelay 动画结束后延时多少ms
                      easing:"ease-out",//速率 linear,ease-in
                      duration: 300,//动画所需ms
                      iterations: 1,//循环次数
              };
              document.documentElement.scrollTo(0,st+sy);
              let _Animation = document.body.animate(keyframes,options);
              ["cancel","finish","remove"].forEach(v=>_Animation.addEventListener(v,e=>console.log(e.type)));
              //let _Animation = new Animation(new KeyframeEffect(document.body,keyframes, options));
              _Animation.addEventListener('finish',e=>{ });
              //_Animation.play();
              //_Animation.cancel();
              //_Animation.pause();
              //_Animation.finish();
          }
          animateScroll(500); //向下滚动500px
    
    

后记

如果子容器在发生动画事件,主容器监听也会触发的.好比点击子元素会冒泡到document.body.避免这种情况,用this==event.target判断是否当前对象.
这些事件可用实现动画之间套娃,比起使用setTimeout()好用多了.例如A碰到B时,B才打C,是不是有点人机检测内味?

    let on = (o,...a)=>o && Reflect.apply(addEventListener, o, a),
        $ = s=>document.querySelector(s);
    var A,B,C;
    on($(A),'animationend',e=>{
        let A=e.target,size = A.getBoundingClientRect();
        let B = document.elementFromPoint(size.x,size.y);
        if(B){
            A.classList.remove('active');
            A.hidden = true;
            //A消失了
            B.classList.add('active');
            //抓到B了 给B上眼药
        }
        else console.log('打跑A抓不到B');
    });
    on($(B),'animationend',e=>{
        let A=e.target,size = A.getBoundingClientRect();
        let B = document.elementFromPoint(size.x,size.y);
        if(B==$(C)){
            A.classList.remove('active');
            A.hidden = true;
            //B消失了
            B.classList.add('active');
            //抓到C了
            console.log('恭喜你拳打A,脚踢B,一巴打在C身上');
        }else console.log('功亏一篑!');
    });

animation事件例子1

animation事件例子2 滚动顶部

transition交互例子

简单结构实现bootstrap菜单效果,transition实践自适应导航菜单

  • 交互脚本html

      <button id="nav-btn">
          <span id="nav-icon"></span>
      </button>
      <nav id="nav-body">
          <div class="nav-item"><a class="nav-item-a" href="/">首页</a></div>
          <div class="nav-item"><a class="nav-item-a" href="/emulator/helppage/">手机模拟器下载</a></div>
          <div class="nav-item"><a class="nav-item-a" href="/emulator/app/emujs/">模拟器讨论</a></div>
          <div class="nav-item"><a class="nav-item-a" href="Jekyll.html">Jekyll安装</a></div>
      </nav>
    
  • 交互脚本javascript

      !(function(){
          let on = (o,...a)=>o && Reflect.apply(addEventListener, o, a),
              $ = s=>document.querySelector(s),
              setStyle = (a,b)=>Object.entries(b).forEach(v=>a.style[(v[1]===false?'remove':'set')+'Property'](v[0],v[1]));
          on(
              //绑定按钮事件
              $('#nav-btn'),
              'click',
              function(){
                  let nb = $('#nav-body');
                  setStyle(nb,{'--nav-height':nb.scrollHeight+'px'});
                  //设置#nav-body原始高度,否则动画不知到高度
                  // --nav-height 把高度存进CSS变量中调用,避免直接用height覆盖属性
                  this.classList.toggle('active');
              }
          );
      })();
    

评论