js 模拟气泡屏保效果代码
程序员文章站
2022-04-12 11:35:53
核心代码:复制代码 代码如下:var t$ = function(id) { return document.getelementbyid(id); }var $exten...
核心代码:
var t$ = function(id) { return document.getelementbyid(id); }
var $extend = function(des, src) { for (var p in src) { des[p] = src[p]} return des; }
var bubble = function() {
// 小球随机样式
var clss = ['ball_one', 'ball_two', 'ball_three', 'ball_four', 'ball_five', 'ball_six'];
var ball = function(radius, clsname) {
var ball = document.createelement('div');
ball.classname = clsname;
with(ball.style) {
width = height = (radius || 10) + 'px'; position = 'absolute';
}
return ball;
};
// 屏保主类
var screen = function(cid, config) {
var self = this;
if (!(self instanceof screen)) {
return new screen(cid, config);
}
self.container = t$(cid);
if (!self.container) return;
config = $extend(screen.config, config || {});
// 配置属性
self.ballsnum = config.ballsnum;
self.diameter = 55;
self.radius = self.diameter / 2;
self.bounce = config.bounce;
self.spring = config.spring;
self.gravity = config.gravity;
self.balls = [];
self.timer = null;
// 上下左右边界
self.t_bound = 0;
self.b_bound = self.container.clientheight;
self.l_bound = 0;
self.r_bound = self.container.clientwidth;
};
// 静态属性
screen.config = {
ballsnum: 5, // 小球数目
spring: 0.8, // 弹力加速度
bounce: -0.95, // 反弹
gravity: 0.1 // 重力
};
screen.prototype = {
initialize: function() {
var self = this;
// 生成小球
self.createballs();
// 侦听碰撞
self.timer = setinterval(function() {
self.hittest();
}, 32);
},
createballs: function() {
var self = this, num = self.ballsnum, i = 0;
var frag = document.createdocumentfragment();
for (; i < num; i++) {
var ball = new ball(self.diameter, clss[math.floor(math.random() * (clss.length - 1))]);
ball.radius = self.radius;
ball.diameter = self.diameter;
ball.style.left = (math.random() * self.b_bound) + 'px';
ball.style.top = (math.random() * self.r_bound) + 'px';
ball.vx = math.random() * 6 - 3;
ball.vy = math.random() * 6 - 3;
frag.appendchild(ball);
self.balls[i] = ball;
}
self.container.appendchild(frag);
},
// 碰撞检测
hittest: function() {
var self = this, num = self.ballsnum, balls = self.balls;
for (var i = 0; i < num - 1; i++) {
var ball0 = balls[i];
ball0.x = ball0.offsetleft + ball0.radius;
ball0.y = ball0.offsettop + ball0.radius;
for (var j = i + 1; j < num; j++) {
var ball1 = balls[j];
ball1.x = ball1.offsetleft + ball1.radius;
ball1.y = ball1.offsettop + ball1.radius;
var dx = ball1.x - ball0.x;
var dy = ball1.y - ball0.y;
var dist = math.sqrt(dx * dx + dy * dy);
var misdist = ball0.radius + ball1.radius;
if (dist < misdist) {
var angle = math.atan2(dy, dx);
var tx = ball0.x + math.cos(angle) * misdist;
var ty = ball0.y + math.sin(angle) * misdist;
var ax = (tx - ball1.x) * self.spring;
var ay = (ty - ball1.y) * self.spring;
ball0.vx -= ax;
ball0.vy -= ay;
ball1.vx += ax;
ball1.vy += ay;
}
}
}
for (var i = 0; i < num; i++) {
self.move(balls[i]);
}
},
// 气泡运动
move: function(ball) {
var self = this;
ball.vy += self.gravity;
ball.style.left = (ball.offsetleft + ball.vx) + 'px';
ball.style.top = (ball.offsettop + ball.vy) + 'px';
// 边界检测
var t = self.t_bound, b = self.b_bound, l = self.l_bound, r = self.r_bound, bc = self.bounce;
if (ball.offsetleft + ball.diameter > r) {
ball.style.left = r - ball.diameter + 'px';
ball.vx *= bc;
} else if (ball.offsetleft < l) {
ball.style.left = l + 'px';
ball.vx *= bc;
}
if (ball.offsettop + ball.diameter > b) {
ball.style.top = b - ball.diameter + 'px';
ball.vy *= bc;
} else if (ball.offsettop < t) {
ball.style.top = t + 'px';
ball.vy *= bc;
}
}
};
return { screen: screen }
}();
window.onload = function() {
var sc = null;
t$('start').onclick = function() {
document.getelementbyid('inner').innerhtml = '';
sc = bubble.screen('inner', { ballsnum: 5, spring: 0.8, bounce: -0.95, gravity: 0.1});
sc.initialize();
};
t$('stop').onclick = function() { clearinterval(sc.timer); }
var bound = false
t$('change').onclick = function() {
if (!bound) {
t$('screen').style.backgroundimage = 'url("http://demo.jb51.net/js/bubbling/o_bg1.jpg")';
bound = true;
} else {
t$('screen').style.backgroundimage = 'url("http://demo.jb51.net/js/bubbling/o_bg2.jpg")';
bound = false;
}
}
}
【说明】
程序效率出现了很大瓶颈。需要做的优化还有很多。有时间继续完善。
另:感谢罗浮宫群友逍遥君武和豪情对图片的支持。
【源码下载】
复制代码 代码如下:
var t$ = function(id) { return document.getelementbyid(id); }
var $extend = function(des, src) { for (var p in src) { des[p] = src[p]} return des; }
var bubble = function() {
// 小球随机样式
var clss = ['ball_one', 'ball_two', 'ball_three', 'ball_four', 'ball_five', 'ball_six'];
var ball = function(radius, clsname) {
var ball = document.createelement('div');
ball.classname = clsname;
with(ball.style) {
width = height = (radius || 10) + 'px'; position = 'absolute';
}
return ball;
};
// 屏保主类
var screen = function(cid, config) {
var self = this;
if (!(self instanceof screen)) {
return new screen(cid, config);
}
self.container = t$(cid);
if (!self.container) return;
config = $extend(screen.config, config || {});
// 配置属性
self.ballsnum = config.ballsnum;
self.diameter = 55;
self.radius = self.diameter / 2;
self.bounce = config.bounce;
self.spring = config.spring;
self.gravity = config.gravity;
self.balls = [];
self.timer = null;
// 上下左右边界
self.t_bound = 0;
self.b_bound = self.container.clientheight;
self.l_bound = 0;
self.r_bound = self.container.clientwidth;
};
// 静态属性
screen.config = {
ballsnum: 5, // 小球数目
spring: 0.8, // 弹力加速度
bounce: -0.95, // 反弹
gravity: 0.1 // 重力
};
screen.prototype = {
initialize: function() {
var self = this;
// 生成小球
self.createballs();
// 侦听碰撞
self.timer = setinterval(function() {
self.hittest();
}, 32);
},
createballs: function() {
var self = this, num = self.ballsnum, i = 0;
var frag = document.createdocumentfragment();
for (; i < num; i++) {
var ball = new ball(self.diameter, clss[math.floor(math.random() * (clss.length - 1))]);
ball.radius = self.radius;
ball.diameter = self.diameter;
ball.style.left = (math.random() * self.b_bound) + 'px';
ball.style.top = (math.random() * self.r_bound) + 'px';
ball.vx = math.random() * 6 - 3;
ball.vy = math.random() * 6 - 3;
frag.appendchild(ball);
self.balls[i] = ball;
}
self.container.appendchild(frag);
},
// 碰撞检测
hittest: function() {
var self = this, num = self.ballsnum, balls = self.balls;
for (var i = 0; i < num - 1; i++) {
var ball0 = balls[i];
ball0.x = ball0.offsetleft + ball0.radius;
ball0.y = ball0.offsettop + ball0.radius;
for (var j = i + 1; j < num; j++) {
var ball1 = balls[j];
ball1.x = ball1.offsetleft + ball1.radius;
ball1.y = ball1.offsettop + ball1.radius;
var dx = ball1.x - ball0.x;
var dy = ball1.y - ball0.y;
var dist = math.sqrt(dx * dx + dy * dy);
var misdist = ball0.radius + ball1.radius;
if (dist < misdist) {
var angle = math.atan2(dy, dx);
var tx = ball0.x + math.cos(angle) * misdist;
var ty = ball0.y + math.sin(angle) * misdist;
var ax = (tx - ball1.x) * self.spring;
var ay = (ty - ball1.y) * self.spring;
ball0.vx -= ax;
ball0.vy -= ay;
ball1.vx += ax;
ball1.vy += ay;
}
}
}
for (var i = 0; i < num; i++) {
self.move(balls[i]);
}
},
// 气泡运动
move: function(ball) {
var self = this;
ball.vy += self.gravity;
ball.style.left = (ball.offsetleft + ball.vx) + 'px';
ball.style.top = (ball.offsettop + ball.vy) + 'px';
// 边界检测
var t = self.t_bound, b = self.b_bound, l = self.l_bound, r = self.r_bound, bc = self.bounce;
if (ball.offsetleft + ball.diameter > r) {
ball.style.left = r - ball.diameter + 'px';
ball.vx *= bc;
} else if (ball.offsetleft < l) {
ball.style.left = l + 'px';
ball.vx *= bc;
}
if (ball.offsettop + ball.diameter > b) {
ball.style.top = b - ball.diameter + 'px';
ball.vy *= bc;
} else if (ball.offsettop < t) {
ball.style.top = t + 'px';
ball.vy *= bc;
}
}
};
return { screen: screen }
}();
window.onload = function() {
var sc = null;
t$('start').onclick = function() {
document.getelementbyid('inner').innerhtml = '';
sc = bubble.screen('inner', { ballsnum: 5, spring: 0.8, bounce: -0.95, gravity: 0.1});
sc.initialize();
};
t$('stop').onclick = function() { clearinterval(sc.timer); }
var bound = false
t$('change').onclick = function() {
if (!bound) {
t$('screen').style.backgroundimage = 'url("http://demo.jb51.net/js/bubbling/o_bg1.jpg")';
bound = true;
} else {
t$('screen').style.backgroundimage = 'url("http://demo.jb51.net/js/bubbling/o_bg2.jpg")';
bound = false;
}
}
}
【说明】
程序效率出现了很大瓶颈。需要做的优化还有很多。有时间继续完善。
另:感谢罗浮宫群友逍遥君武和豪情对图片的支持。
【源码下载】