标签:abs 定义 ati out diameter conf extend src 动画
/* 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]) }
标签:abs 定义 ati out diameter conf extend src 动画
原文地址:https://www.cnblogs.com/dhsz/p/11624520.html