标签: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