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定义类和对象的方法
Nov 26 Javascript
28个常用JavaScript方法集锦
Jan 14 Javascript
jQuery实现的Div窗口震动效果实例
Aug 07 Javascript
jQuery实现的简单提示信息插件
Dec 08 Javascript
jQuery限制图片大小的方法
May 25 Javascript
BootStrap modal模态弹窗使用小结
Oct 26 Javascript
js实现五星评价功能
Mar 08 Javascript
单行 JS 实现移动端金钱格式的输入规则
May 22 Javascript
JavaScript用200行代码制作打飞机小游戏实例
Jun 21 Javascript
js定时器实现倒计时效果
Nov 05 Javascript
JavaScript fetch接口案例解析
Aug 30 Javascript
ES6基础之数组和对象的拓展实例详解
Aug 22 Javascript
浅谈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
php cookie 作用范围?不要在当前页面使用你的cookie
2009/03/24 PHP
php中++i 与 i++ 的区别
2012/08/08 PHP
php验证手机号码(支持归属地查询及编码为UTF8)
2013/02/01 PHP
PHP按行读取、处理较大CSV文件的代码实例
2014/04/09 PHP
PHP面向对象详解(三)
2015/12/07 PHP
win10环境PHP 7 安装配置【教程】
2016/05/09 PHP
javascript实现的元素拖动函数宿主为浏览器
2014/07/21 Javascript
Javascript获取当前日期的农历日期代码
2014/10/08 Javascript
JavaScript中的类数组对象介绍
2014/12/30 Javascript
js实现鼠标悬浮给图片加边框的方法
2015/01/30 Javascript
javascript实现页面刷新时自动清空表单并选中的方法
2015/07/18 Javascript
常用javascript表单验证汇总
2020/07/20 Javascript
KnockoutJS 3.X API 第四章之事件event绑定
2016/10/10 Javascript
详解如何使用webpack打包多页jquery项目
2019/02/01 jQuery
详解vue 动态加载并注册组件且通过 render动态创建该组件
2019/05/30 Javascript
vue滑动吸顶及锚点定位的示例代码
2020/05/10 Javascript
Vue 3自定义指令开发的相关总结
2021/01/29 Vue.js
python实现倒计时的示例
2014/02/14 Python
让python在hadoop上跑起来
2016/01/27 Python
Python request设置HTTPS代理代码解析
2018/02/12 Python
python中的变量如何开辟内存
2018/06/26 Python
Python 获取主机ip与hostname的方法
2018/12/17 Python
Python使用numpy模块实现矩阵和列表的连接操作方法
2019/06/26 Python
Django连接数据库并实现读写分离过程解析
2019/11/13 Python
python里反向传播算法详解
2020/11/22 Python
HTML5 window/iframe跨域传递消息 API介绍
2013/08/26 HTML / CSS
Html5 语法与规则简要概述
2014/07/29 HTML / CSS
加拿大服装和鞋类零售商:Mark’s
2021/01/04 全球购物
工商技校毕业生自荐信
2013/11/15 职场文书
求职信内容怎么写
2014/05/26 职场文书
个人批评与自我批评发言稿
2014/09/28 职场文书
县政协领导班子群众路线教育实践活动四风问题整改方案
2014/10/26 职场文书
检讨书格式
2015/01/23 职场文书
2016北大自主招生自荐信模板
2016/01/28 职场文书
2019年入党思想汇报格式与要求
2019/06/25 职场文书
Python中使用subprocess库创建附加进程
2021/05/11 Python