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 相关文章推荐
基于jquery的滑动样例代码
Nov 20 Javascript
Javascript图像处理思路及实现代码
Dec 25 Javascript
判断文档离浏览器顶部的距离的方法
Jan 08 Javascript
原生javascript实现的分页插件pagenav
Aug 28 Javascript
JavaSacript中charCodeAt()方法的使用详解
Jun 05 Javascript
简介JavaScript中getUTCMonth()方法的使用
Jun 10 Javascript
详解JavaScript中的表单验证
Jun 16 Javascript
异步安全加载javascript文件的方法
Jul 21 Javascript
JavaScript_object基础入门(必看篇)
Jun 13 Javascript
js html5 css俄罗斯方块游戏再现
Oct 17 Javascript
webpack4.x下babel的安装、配置及使用详解
Mar 07 Javascript
node命令行工具之实现项目工程自动初始化的标准流程
Aug 12 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 __autoload()方法真的影响性能吗?
2012/03/30 PHP
PHP的压缩函数实现:gzencode、gzdeflate和gzcompress的区别
2016/01/27 PHP
laravel 时间格式转时间戳的例子
2019/10/11 PHP
javascript 特殊字符串
2009/02/25 Javascript
JavaScript Timer实现代码
2010/02/17 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
通过url查找a元素应用案例
2014/04/29 Javascript
js中取得变量绝对值的方法
2015/01/03 Javascript
JavaScript模块化开发之SeaJS
2015/12/13 Javascript
基于zepto.js简单实现上传图片
2016/06/21 Javascript
Vue.js实现一个自定义分页组件vue-paginaiton
2016/09/05 Javascript
AngularJS 实现JavaScript 动画效果详解
2016/09/08 Javascript
如何利用模板将HTML从JavaScript中抽离
2016/10/08 Javascript
JS使用正则截取两个字符串之间的字符串实现方法详解
2017/01/06 Javascript
Ionic + Angular.js实现验证码倒计时功能的方法
2017/06/12 Javascript
原生JS实现的放大镜特效示例【测试可用】
2018/12/08 Javascript
vue 设置 input 为不可以编辑的实现方法
2019/09/19 Javascript
layer 关闭指定弹出层的例子
2019/09/25 Javascript
JS实现压缩上传图片base64长度功能
2019/12/03 Javascript
Vue实现验证码功能
2019/12/03 Javascript
微信小程序实现转盘抽奖
2020/09/21 Javascript
详解Django框架中的视图级缓存
2015/07/23 Python
python中将函数赋值给变量时需要注意的一些问题
2017/08/18 Python
详谈Python中列表list,元祖tuple和numpy中的array区别
2018/04/18 Python
Selenium定时刷新网页的实现代码
2018/10/31 Python
Python面向对象程序设计之类的定义与继承简单示例
2019/03/18 Python
Python urlopen()和urlretrieve()用法解析
2020/01/07 Python
Converse匡威法国官网:美国著名帆布鞋品牌
2018/12/05 全球购物
教师实习自我鉴定
2013/12/14 职场文书
三好学生自我鉴定
2013/12/17 职场文书
商务英语专业大学生职业生涯规划书
2014/09/14 职场文书
和谐家庭事迹材料
2014/12/20 职场文书
2015年员工工作表现评语
2015/03/25 职场文书
欢送会主持词
2015/07/01 职场文书
前端学习——JavaScript原生实现购物车案例
2021/03/31 Javascript
Java 关于String字符串原理上的问题
2022/04/07 Java/Android