zoukankan      html  css  js  c++  java
  • 动画效果

    /* eslint-disable semi */
    let animationId = 0;
    let fnAnimation = null;
    let Container = null;
    let Balls = [];
    
    export function clearBallScreen () {
      setTimeout(() => {
        for (let i = 0; i < Balls.length; i++) {
          Container.removeChild(Balls[i]);
        }
        Balls = [];
      }, 1000);
    }
    
    export function ballCrash (el, classArr, ballNum, diameters) {
      let getFlag = function (id) {
        return document.getElementById(id);
      };
      let extend = function (des, src) {
        for (let p in src) {
          des[p] = src[p];
        }
        return des;
      };
    
      // 球的屏幕初始化配置类
      let Screen = function (cid, config) {
        let self = this;
        if (!(self instanceof Screen)) {
          return new Screen(cid, config);
        }
    
        config = extend(Screen.Config, config);
    
        self.container = getFlag(cid);
    
        if (!self.container) return;
    
        self.ballsnum = config.ballsnum;
    
        self.spring = config.spring;
        self.bounce = config.bounce;
    
        self.gravity = config.gravity;
    
        self.balls = [];
        self.timer = null;
    
        self.L_bound = 0;
        self.R_bound = self.container && self.container.clientWidth;
        self.T_bound = 0;
    
        self.B_bound = self.container && self.container.clientHeight;
      };
    
      Screen.Config = {
        ballsnum: 10,
        spring: 0.8,
        bounce: -1,
        gravity: 0.05
      };
    
      function Ball (classn) {
        let ball = document.createElement('div');
        ball.className = classn;
    
        ball.style.position = 'absolute';
        ball.style.zIndex = '10';
        return ball;
      }
    
      Screen.prototype = {
        initialize: function () {
          if (!this.container) return;
          let self = this;
          self.createBalls();
    
          function animation () {
            animationId = requestAnimationFrame(animation);
    
            self.hitBalls();
          }
    
          fnAnimation = animation;
    
          if (window.requestAnimationFrame) {
            animation();
          } else {
            self.timer = setInterval(function () {
              self.hitBalls();
            }, 30);
          }
        },
        prefix: 'wave_',
        createBalls: function () {
          let self = this;
          let num = self.ballsnum;
          let frag = document.createDocumentFragment();
          for (let i = 0; i < num; i++) {
            let ball = Ball(`${this.prefix}${classArr[i]} wave_ball`);
    
            ball.diameter = diameters[i];
            ball.radius = ball.diameter / 2;
    
            ball.style.left = Math.random() * self.R_bound + 'px';
            ball.style.top = Math.random() * self.B_bound + 'px';
    
            // [定义 每次刷新, 移动多少距离]
            ball.moveX = Math.random() * 6 - 3;
            ball.moveY = Math.random() * 6 - 3;
            frag.appendChild(ball);
            self.balls[i] = ball;
            Balls.push(ball);
          }
    
          Container = self.container;
          self.container.appendChild(frag);
        },
        hitBalls: function () {
          let self = this;
          let num = self.ballsnum;
          let balls = self.balls;
          for (let i = 0; i < num - 1; i++) {
            let ball1 = self.balls[i];
            // [获取圆点位置]
            ball1.x = ball1.offsetLeft + ball1.radius;
            ball1.y = ball1.offsetTop + ball1.radius;
    
            // [循环计算后面的球, 是否碰撞]
            for (let j = i + 1; j < num; j++) {
              let ball2 = self.balls[j];
    
              // [获取下一个球的圆点位置]
              ball2.x = ball2.offsetLeft + ball2.radius;
              ball2.y = ball2.offsetTop + ball2.radius;
    
              // [圆心之间 X  Y]
              let dx = ball2.x - ball1.x;
              let dy = ball2.y - ball1.y;
    
              // [圆心之间的距离]
              let dist = Math.sqrt(dx * dx + dy * dy);
    
              // [圆心之间最小距离]
              let misDist = ball1.radius + ball2.radius;
    
              if (dist < misDist) {
                let angle = Math.atan2(dy, dx);
    
                let tx = ball1.x + Math.cos(angle) * misDist;
                let ty = ball1.y + Math.sin(angle) * misDist;
    
                // 这次渲染移动的距离
                let ax = (tx - ball2.x) * self.spring;
                let ay = (ty - ball2.y) * self.spring;
    
                /** [反弹运动] **/
                ball1.moveX -= ax;
                ball1.moveY -= ay;
                ball2.moveX += ax;
                ball2.moveY += ay;
              }
            }
          }
          for (let i = 0; i < num; i++) {
            self.moveBalls(balls[i]);
          }
        },
        moveBalls: function (ball) {
          let self = this;
          // [重力 0.01]
          ball.moveY += self.gravity;
    
          ball.style.left = ball.offsetLeft + ball.moveX + 'px';
          ball.style.top = ball.offsetTop + ball.moveY + 'px';
          let L = self.L_bound;
          let R = self.R_bound;
          let T = self.T_bound;
          let B = self.B_bound;
          let BC = self.bounce;
    
          // BC是负值, 所以每次碰到边后, moveX moveY 会设置成相反的值, 后续都用这个, 球就会持续反方向运动
          if (ball.offsetLeft < L) {
            ball.style.left = L;
            ball.moveX *= BC;
          } else if (ball.offsetLeft + ball.diameter > R) {
            ball.style.left = R - ball.diameter + 'px';
            ball.moveX *= BC;
          } else if (ball.offsetTop < T) {
            ball.style.top = T;
            ball.moveY *= BC;
          }
          // top 不能大于可视区的高度
          if (ball.offsetTop + ball.diameter > B) {
            ball.style.top = B - ball.diameter + 'px';
            ball.moveY *= BC;
          }
        }
      };
    
      let sc = new Screen(el, {
        ballsnum: ballNum,
        spring: 0.8,
        bounce: -0.9,
        gravity: 0.01
      });
      sc.initialize();
    }
    
    export function stopAnimation () {
      animationId && window.cancelAnimationFrame(animationId);
      animationId = 0;
    }
    
    export function goAnimation () {
      fnAnimation && window.requestAnimationFrame(fnAnimation);
    }
    
    //使用
    import { ballCrash, clearBallScreen } from '../../../util/effect.js'
    
    createBallScreen () {
          ballCrash('lottery-crash', ['one', 'two', 'three', 'four', 'five', 'six', 'seven'], 7, [25, 18, 14, 18, 11, 17, 10])
        }
    

      

  • 相关阅读:
    有关macOS隐藏文件的问题
    AcWing 2548. 大胖子走迷宫(BFS)
    AcWing 1224. 交换瓶子(交换最少次数使得数列有序)
    AcWing 1220. 生命之树(树形DP)
    AcWing 1215. 小朋友排队(树状数组)
    AcWing 1214. 波动数列(推柿子+DP)
    Python文件操作
    远程升级程序过程
    找某个Linux内核可能调用的文件
    linux platform简易的理解
  • 原文地址:https://www.cnblogs.com/dhsz/p/11624520.html
Copyright © 2011-2022 走看看