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 相关文章推荐
不要小看注释掉的JS 引起的安全问题
Dec 27 Javascript
IE和firefox浏览器的event事件兼容性汇总
Dec 06 Javascript
javascript 定义新对象方法
Feb 20 Javascript
JavaScript的单例模式 (singleton in Javascript)
Jun 11 Javascript
情人节之礼 js项链效果
Feb 13 Javascript
jquery属性选择器not has怎么写 行悬停高亮显示
Nov 13 Javascript
JS之Date对象和获取系统当前时间详解
Jan 13 Javascript
Angular 4依赖注入学习教程之组件服务注入(二)
Jun 04 Javascript
原生JS实现图片无缝滚动方法(附带封装的运动框架)
Oct 01 Javascript
vue.js整合vux中的上拉加载下拉刷新实例教程
Jan 09 Javascript
原生js实现贪食蛇小游戏的思路详解
Nov 26 Javascript
openlayers4.6.5实现距离量测和面积量测
Sep 25 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
高分R级DC动画剧《哈莉·奎茵》第二季正式预告首发
2020/04/09 欧美动漫
php中判断一个字符串包含另一个字符串的方法
2007/03/19 PHP
更改localhost为其他名字的方法
2014/02/10 PHP
php分割合并两个字符串的函数实例
2015/06/19 PHP
微信自定义分享php代码分析
2016/11/24 PHP
jQuery中bind,live,delegate与one方法的用法及区别解析
2013/12/30 Javascript
javaScript中的this示例学习详解及工作原理
2014/01/13 Javascript
JavaScript简介
2015/02/15 Javascript
jQuery实现限制textarea文本框输入字符数量的方法
2015/05/28 Javascript
javascript中new关键字详解
2015/12/14 Javascript
ES2015 Symbol 一种绝不重复的值
2016/12/25 Javascript
创建简单的node服务器实例(分享)
2017/06/23 Javascript
微信小程序实现倒计时60s获取验证码
2020/04/17 Javascript
百度小程序之间的页面通信过程详解
2019/07/18 Javascript
ES6实现图片切换特效代码
2020/01/14 Javascript
Vue实现图片轮播组件思路及实例解析
2020/05/11 Javascript
微信小程序反编译的实现
2020/12/10 Javascript
Vuex实现简单购物车
2021/01/10 Vue.js
[02:14]2016国际邀请赛中国区预选赛Ehome晋级之路
2016/07/01 DOTA
Python采集腾讯新闻实例
2014/07/10 Python
python脚本内运行linux命令的方法
2015/07/02 Python
详解 Python 与文件对象共事的实例
2017/09/11 Python
PyQt5每天必学之组合框
2018/04/20 Python
django ajax json的实例代码
2018/05/29 Python
django框架ModelForm组件用法详解
2019/12/11 Python
python名片管理系统开发
2020/06/18 Python
递归实现回文判断(如:abcdedbca就是回文,判断一个面试者对递归理解的简单程序)
2013/04/28 面试题
什么是用户模式(User Mode)与内核模式(Kernel Mode) ?
2014/07/21 面试题
运动会广播稿150字
2014/02/19 职场文书
岗位职责风险点
2014/03/12 职场文书
解放思想大讨论活动心得体会
2014/09/11 职场文书
迎七一演讲稿
2014/09/12 职场文书
我为党旗添光彩演讲稿
2014/09/13 职场文书
我的中国梦主题教育活动总结
2015/05/07 职场文书
八一建军节主持词
2015/07/01 职场文书
演讲稿:态度决定一切
2019/04/02 职场文书