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 相关文章推荐
各浏览器对link标签onload/onreadystatechange事件支持的差异分析
Apr 27 Javascript
javascript垃圾收集机制与内存泄漏详细解析
Nov 11 Javascript
Array 重排序方法和操作方法的简单实例
Jan 24 Javascript
在JavaScript应用中实现延迟加载的方法
Jun 25 Javascript
JS模式之单例模式基本用法
Jun 30 Javascript
jQuery 自定义下拉框(DropDown)附源码下载
Jul 22 Javascript
详解Jquery的事件操作和文档操作
Dec 19 Javascript
Vue.js 2.0 移动端拍照压缩图片预览及上传实例
Apr 27 Javascript
详解webpack自定义loader初探
Aug 29 Javascript
JS滚轮控制图片缩放大小和拖动的实例代码
Nov 20 Javascript
微信小程序实现bindtap等事件传参
Apr 08 Javascript
JS脚本实现定时到网站上签到/签退功能
Apr 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边学边教》(02.Apache+PHP环境配置――下篇)
2006/12/13 PHP
php 高效率写法 推荐
2010/02/21 PHP
ThinkPHP3.1的Widget新用法
2014/06/19 PHP
WordPress开发中的get_post_custom()函数使用解析
2016/01/04 PHP
php基于Redis消息队列实现的消息推送的方法
2018/11/28 PHP
PHP开发api接口安全验证操作实例详解
2020/03/26 PHP
?牟┛途W扣了一??效果出?? target=
2007/05/27 Javascript
javascript 类型判断代码分析
2010/03/28 Javascript
一张表格告诉你windows.onload()与$(document).ready()的区别
2014/05/16 Javascript
Javascript基础教程之比较操作符
2015/01/18 Javascript
js鼠标悬浮出现遮罩层的方法
2015/01/28 Javascript
SpringMVC restful 注解之@RequestBody进行json与object转换
2015/12/10 Javascript
javascript实现checkbox复选框实例代码
2016/01/10 Javascript
js方法数据验证的简单实例
2016/09/17 Javascript
JavaScript实现的CRC32函数示例
2016/11/23 Javascript
vue2滚动条加载更多数据实现代码
2017/01/10 Javascript
Angularjs使用指令做表单校验的方法
2017/03/31 Javascript
jQuery 实现鼠标画框并对框内数据选中的实例代码
2017/08/29 jQuery
js将日期格式转换为YYYY-MM-DD HH:MM:SS
2020/09/18 Javascript
[11:57]《一刀刀一天》第十七期:TI中国军团加油!
2014/05/26 DOTA
python虚拟环境virtualenv的使用教程
2017/10/20 Python
python实现键盘控制鼠标移动
2020/11/27 Python
python paramiko利用sftp上传目录到远程的实例
2019/01/03 Python
Python 函数list&amp;read&amp;seek详解
2019/08/28 Python
Python中logging日志库实例详解
2020/02/19 Python
纯CSS3实现绘制各种图形实现代码详细整理
2012/12/26 HTML / CSS
TUMI香港官网:国际领先的行李箱、背囊品牌
2021/03/01 全球购物
培训演讲稿范文
2014/01/12 职场文书
婚礼新郎父母答谢词
2014/01/16 职场文书
党员廉洁自律承诺书
2014/05/26 职场文书
服务行业演讲稿
2014/09/02 职场文书
升国旗演讲稿
2014/09/05 职场文书
学校师德师风自我剖析材料
2014/09/29 职场文书
永远是春天观后感
2015/06/12 职场文书
2015年初中教务处工作总结
2015/07/21 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书