Posted in Javascript onJuly 10, 2010
核心代码:
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.3water.com/js/bubbling/o_bg1.jpg")'; bound = true; } else { T$('screen').style.backgroundImage = 'url("http://demo.3water.com/js/bubbling/o_bg2.jpg")'; bound = false; } } }
【说明】
程序效率出现了很大瓶颈。需要做的优化还有很多。有时间继续完善。
另:感谢罗浮宫群友逍遥君武和豪情对图片的支持。
【源码下载】
https://3water.com/jiaoben/28295.html
js 模拟气泡屏保效果代码
声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。
Reply on: @reply_date@
@reply_contents@