js 模拟气泡屏保效果代码


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
Javascript 相关文章推荐
从javascript语言本身谈项目实战
Dec 27 Javascript
js bind 函数 使用闭包保存执行上下文
Dec 26 Javascript
jquery实现图片渐变切换兼容ie6/Chrome/Firefox
Aug 02 Javascript
JQuery中的html()、text()、val()区别示例介绍
Sep 01 Javascript
一个JavaScript获取元素当前高度的实例
Oct 29 Javascript
用AngularJS的指令实现tabs切换效果
Aug 31 Javascript
Vue.js组件通信的几种姿势
Oct 23 Javascript
Angular移动端页面input无法输入的解决方法
Nov 14 Javascript
vue.js 嵌套循环、if判断、动态删除的实例
Mar 07 Javascript
深入Vue-Router路由嵌套理解
Aug 13 Javascript
Vue中nprogress页面加载进度条的方法实现
Nov 13 Javascript
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
Feb 23 Vue.js
浅谈javascript的数据类型检测
Jul 10 #Javascript
jquery nth-child()选择器的简单应用
Jul 10 #Javascript
SWFObject 2.1以上版本语法介绍
Jul 10 #Javascript
加载jQuery后$冲突的解决办法
Jul 09 #Javascript
在javascript将NodeList作为Array数组处理的方法
Jul 09 #Javascript
jquery multiSelect 多选下拉框
Jul 09 #Javascript
IE8 chrome中table隔行换色解决办法
Jul 09 #Javascript
You might like
PHPMailer的主要功能特点和简单使用说明
2014/02/17 PHP
PHP数据库操作二:memcache用法分析
2017/08/16 PHP
GreyBox技术总结(转)
2010/11/23 Javascript
js使用for循环与innerHTML获取选中tr下td值
2014/09/26 Javascript
jQuery+css实现的切换图片功能代码
2016/01/27 Javascript
JS文件上传神器bootstrap fileinput详解
2021/01/28 Javascript
基于javascript实现最简单选项卡切换
2017/02/01 Javascript
使用Dropzone.js上传的示例代码
2017/10/10 Javascript
初探Vue3.0 中的一大亮点Proxy的使用
2018/12/06 Javascript
详解js常用分割取字符串的方法
2019/05/15 Javascript
微信小程序自定义navigationBar顶部导航栏适配所有机型(附完整案例)
2020/04/26 Javascript
举例详解Python中threading模块的几个常用方法
2015/06/18 Python
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
一步步解析Python斗牛游戏的概率
2016/02/12 Python
Matplotlib 生成不同大小的subplots实例
2018/05/25 Python
朴素贝叶斯分类算法原理与Python实现与使用方法案例
2018/06/26 Python
用sqlalchemy构建Django连接池的实例
2019/08/29 Python
python:批量统计xml中各类目标的数量案例
2020/03/10 Python
Python txt文件常用读写操作代码实例
2020/08/03 Python
python删除文件、清空目录的实现方法
2020/09/23 Python
Python爬虫代理池搭建的方法步骤
2020/09/28 Python
python实现测试工具(一)——命令行发送get请求
2020/10/19 Python
基于OpenCV的网络实时视频流传输的实现
2020/11/15 Python
jurlique茱莉蔻英国官网:澳洲天然护肤品
2018/08/03 全球购物
医生实习工作总结的自我评价
2013/09/27 职场文书
电焊工工作岗位职责
2014/02/06 职场文书
五好党支部事迹材料
2014/02/06 职场文书
初中班主任经验交流材料
2014/05/16 职场文书
学校教研活动总结
2014/07/02 职场文书
吃空饷专项整治方案
2014/10/27 职场文书
2014年工人工作总结
2014/11/25 职场文书
作文评语怎么写
2014/12/25 职场文书
学会掌握自己命运的十条黄金法则:
2019/08/08 职场文书
浅谈Python中的函数(def)及参数传递操作
2021/05/25 Python
Python数据可视化之绘制柱状图和条形图
2021/05/25 Python
Mysql索引失效 数据库表中有索引还是查询很慢
2022/05/15 MySQL