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 不只是脚本
May 30 Javascript
JavaScript中两种链式调用实现代码
Jan 12 Javascript
js获得指定控件输入光标的坐标兼容IE,Chrome,火狐等多种主流浏览器
May 21 Javascript
js实现幻灯片效果(基于jquery插件)
Nov 05 Javascript
使用JQUERY进行后台页面布局控制DIV实现左右式
Jan 07 Javascript
avalon js实现仿google plus图片多张拖动排序附源码下载
Sep 24 Javascript
jQuery侧边栏实现代码
May 06 Javascript
30分钟快速掌握Bootstrap框架
May 24 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
Dec 05 Javascript
Vue.js学习之计算属性
Jan 22 Javascript
JS中使用media实现响应式布局
Aug 04 Javascript
vue print.js打印支持Echarts图表操作
Nov 13 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 执行系统外部命令 system() exec() passthru()
2009/08/11 PHP
通过缓存数据库结果提高PHP性能的原理介绍
2012/09/05 PHP
ThinkPHP中pathinfo的访问模式、路径访问模式及URL重写总结
2014/08/23 PHP
PHP根据图片色界在不同位置加水印的方法
2015/07/01 PHP
php中array_multisort对多维数组排序的方法
2020/06/21 PHP
php fread函数使用方法总结
2019/05/28 PHP
用Javascript读取中文COOKIE的解决办法
2007/02/15 Javascript
childNodes.length与children.length的区别
2009/05/14 Javascript
Web表单提交之disabled问题js解决方法
2015/01/13 Javascript
jQuery入门之层次选择器实例简析
2015/12/11 Javascript
一个字符串中出现次数最多的字符 统计这个次数【实现代码】
2016/04/29 Javascript
详解JavaScript中this关键字的用法
2016/05/26 Javascript
微信JS接口大全
2016/08/25 Javascript
js当前页面登录注册框,固定div,底层阴影的实例代码
2016/10/04 Javascript
jquery 实现回车登录详解及实例代码
2016/10/23 Javascript
jQuery实现简单的下拉菜单导航功能示例
2017/12/07 jQuery
详解小程序输入框闪烁及重影BUG解决方案
2018/08/31 Javascript
小程序接入腾讯位置服务的详细流程
2020/03/03 Javascript
antd-DatePicker组件获取时间值,及相关设置方式
2020/10/27 Javascript
[05:02]2014DOTA2 TI中国区预选赛精彩TOPPLAY第三弹
2014/06/25 DOTA
Python的加密模块md5、sha、crypt使用实例
2014/09/28 Python
python提取字典key列表的方法
2015/07/11 Python
Python2/3中urllib库的一些常见用法
2017/12/19 Python
python实现用户管理系统
2018/01/10 Python
基于数据归一化以及Python实现方式
2018/07/11 Python
Python配置文件处理的方法教程
2019/08/29 Python
python框架flask入门之路由及简单实现方法
2020/06/07 Python
python不同系统中打开方法
2020/06/23 Python
详解torch.Tensor的4种乘法
2020/09/03 Python
让IE支持CSS3的不完全兼容方案
2014/09/19 HTML / CSS
详解canvas.toDataURL()报错的解决方案全都在这了
2020/03/31 HTML / CSS
小学门卫岗位职责
2013/12/17 职场文书
春节活动策划方案
2014/01/24 职场文书
挂科检讨书范文
2014/02/20 职场文书
故宫英文导游词
2015/01/31 职场文书
python b站视频下载的五种版本
2021/05/27 Python