js 模拟气泡屏保效果代码

  核心代码:

  

复制代码 代码如下:

  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.glzy8.com/js/bubbling/o_bg1.jpg")';

  bound = true;

  } else {

  T$('screen').style.backgroundImage = 'url("http://demo.glzy8.com/js/bubbling/o_bg2.jpg")';

  bound = false;

  }

  }

  }

  【说明】

  程序效率出现了很大瓶颈。需要做的优化还有很多。有时间继续完善。

  另:感谢罗浮宫群友逍遥君武和豪情对图片的支持。

  【源码下载】

  http://www.glzy8.com/jiaoben/28295.html