字节青训营-实现前端动画

5 篇文章 0 订阅

前端动画实现

最近实在太忙了,没有时间写博客,贴一波最近学的动画代码敷衍一下
在这里插入图片描述

演示地址
动画演示

实现下述动画效果:

  • 控制小球匀速移动
  • 控制小球暂停
  • 控制小球动画终止
  • 控制小球动画倒序播放
  • 控制小球速度
<script>
 function animate({easing,draw,duration}){//动画函数

  let start = performance.now();

  let speed = 1 //倍速
  
  //动画状态
  let state = 'cancle';
  let condition = 'order'

  //动画播放进度
  let timeFraction = 0
  let pauseTimeFraction = 0;

  
  const run = function(){

    requestAnimationFrame(function animate(time){

        if( state === 'pause'){

            pauseTimeFraction = timeFraction;
            start = performance.now();
            
        }
        else{
            console.log("开始执行动画了");
            let tmpProgress = ((time - start) / duration) * speed;
            
            if(condition === 'reverse'){
                tmpProgress = -tmpProgress
            }
            timeFraction = pauseTimeFraction + tmpProgress 

            if(timeFraction > 1) timeFraction = 1;
            if(timeFraction < 0) timeFraction = 0;         

            let progress = easing(timeFraction);

            draw(progress); 
            
            if(state === 'cancle'){
                return
            }else{
                if(condition === 'order'){
                    if(timeFraction < 1){
                        requestAnimationFrame(animate);
                    }else{
                        cancle()
                    }
                }else{
                    if(timeFraction > 0){
                        requestAnimationFrame(animate);
                    }else{
                        cancle()
                    }
                }
            }
           
        }
    })

  }
//   run()
  return{
      play(){
          console.log("执行动画");
          state = 'run'
          timeFraction = pauseTimeFraction
          start = performance.now();
          run()
      },        
      pause(){
        console.log("暂停动画");
        state = 'pause'
        start = performance.now();
      },
      cancle(){
        console.log("终止动画");
        state = 'cancle'
        condition = 'order'
        speed = 1
        timeFraction = 0
        pauseTimeFraction = 0
        start = performance.now();
        run()
      },
      reverse(){
        console.log("倒序执行动画");
        condition = 'reverse'
        pauseTimeFraction = timeFraction
        start = performance.now();
      },
      playRate(Speed){
        console.log("切换动画倍速");
        speed = Speed
        start = performance.now();
        pauseTimeFraction = timeFraction
        run()
      }
  }

}
  const ball = document.querySelector('.ball'); //获取球的dom节点
  
  const draw = (progress) => {//画笔函数 使得球水平匀速运动
    ball.style.transform = `translate(${progress}px,0)`  //核心代码,控制球的偏移量
  }

  const animation = animate({
      duration:2000,
      easing(timeFraction){
        return timeFraction*200;
      },
      draw
  })

  //通过使用闭包的特性控制函数内部变量

  const play = () => {
      animation.play()
  }
  const pause = () => {//暂停动画
    animation.pause()
  }
  const cancle = () => {//暂停动画
    animation.cancle()
  }
  const reverse = () => {//倒序执行动画
    animation.reverse()
  }
  const playRate = (speed) => {//切换动画倍速
    animation.playRate(speed)
  }
</script>

完整代码如下
html

完整代码如下

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="container">
        <div class="axisX"></div>
        <div class="axisY"></div>
        <div class="ball"></div>
        <div class="button-container">
          <div class="button" onClick="play()">play</div>
          <div class="button" onClick="pause()">pause</div>
          <div class="button" onClick="cancle()">cancle</div>
          <div class="button" onClick="reverse()">reverse</div>
          <div class="button" onClick="playRate(2)">切换2倍速</div>
        </div>
      </div>
</body>
</html>
function animate({easing,draw,duration}){//动画函数

  let start = performance.now();

  let speed = 1 //倍速
  
  //动画状态
  let state = 'cancle';
  let condition = 'order'

  //动画播放进度
  let timeFraction = 0
  let pauseTimeFraction = 0;

  
  const run = function(){

    requestAnimationFrame(function animate(time){

        if( state === 'pause'){

            pauseTimeFraction = timeFraction;
            start = performance.now();
            
        }
        else{
            console.log("开始执行动画了");
            let tmpProgress = ((time - start) / duration) * speed;
            
            if(condition === 'reverse'){
                tmpProgress = -tmpProgress
            }
            timeFraction = pauseTimeFraction + tmpProgress 

            if(timeFraction > 1) timeFraction = 1;
            if(timeFraction < 0) timeFraction = 0;         

            let progress = easing(timeFraction);

            draw(progress); 
            
            if(state === 'cancle'){
                return
            }else{
                if(condition === 'order'){
                    if(timeFraction < 1){
                        requestAnimationFrame(animate);
                    }else{
                        cancle()
                    }
                }else{
                    if(timeFraction > 0){
                        requestAnimationFrame(animate);
                    }else{
                        cancle()
                    }
                }
            }
           
        }
    })

  }
//   run()
  return{
      play(){
          console.log("执行动画");
          state = 'run'
          timeFraction = pauseTimeFraction
          start = performance.now();
          run()
      },        
      pause(){
        console.log("暂停动画");
        state = 'pause'
        start = performance.now();
      },
      cancle(){
        console.log("终止动画");
        state = 'cancle'
        condition = 'order'
        speed = 1
        timeFraction = 0
        pauseTimeFraction = 0
        start = performance.now();
        run()
      },
      reverse(){
        console.log("倒序执行动画");
        condition = 'reverse'
        pauseTimeFraction = timeFraction
        start = performance.now();
        play()
      },
      playRate(Speed){
        console.log("切换动画倍速");
        speed = Speed
        start = performance.now();
        pauseTimeFraction = timeFraction
        run()
      }
  }

}
  const ball = document.querySelector('.ball'); //获取球的dom节点
  
  const draw = (progress) => {//画笔函数 使得球水平匀速运动
    ball.style.transform = `translate(${progress}px,0)`  //核心代码,控制球的偏移量
  }

  const animation = animate({
      duration:2000,
      easing(timeFraction){
        return timeFraction*200;
      },
      draw
  })

  //通过使用闭包的特性控制函数内部变量

  const play = () => {
      animation.play()
  }
  const pause = () => {//暂停动画
    animation.pause()
  }
  const cancle = () => {//暂停动画
    animation.cancle()
  }
  const reverse = () => {//倒序执行动画
    animation.reverse()
  }
  const playRate = (speed) => {//切换动画倍速
    animation.playRate(speed)
  }
 body {
  margin: 0;
  padding: 0;
}

#container {
  position: absolute;
  width: 100%;
  height: 100vh;
}

.axisX {
  height: 2px;
  background: black;
  width: 100%;
  position: absolute;
  top: 60%;
  transform: translate(0, -1px);
}

.axisY {
  width: 2px;
  background: black;
  height: 100vh;
  position: absolute;
  left: 50%;
  transform: translate(-1px, 0);
}

.ball {
  position: absolute;
  width: 40px;
  height: 40px;
  border-radius: 20px;
  background: red;
  top: calc(60% - 20px);
  left: calc(50% - 20px);
}
   
.ball::before {
  content: "";
  position: absolute;
  left: 10px;
  top: 10px;
  background: yellow;
  width: 10px;
  height: 10px;
  border-radius: 5px;
}

.button-container {
  position: absolute;
  bottom: 50px;
  left: 100px;
}

.button {
  cursor: pointer;
  border: 2px solid black;
  padding: 10px 20px;
  font-size: 20px;
  display: inline-block;
}
.button:hover {
  background: gray;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值