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 08 Javascript
倒记时60刷新网页的js代码
Feb 18 Javascript
整理AngularJS中的一些常用指令
Jun 16 Javascript
JS实现Fisheye效果动感放大菜单代码
Oct 21 Javascript
学习javascript面向对象 实例讲解面向对象选项卡
Jan 04 Javascript
js事件处理程序跨浏览器解决方案
Mar 27 Javascript
原生 JS Ajax,GET和POST 请求实例代码
Jun 08 Javascript
js利用appendChild对标签进行排序的实现方法
Oct 16 Javascript
详解获取jq ul第一个li定位的四种解决方案
Nov 23 Javascript
vue数据双向绑定的注意点
Jun 23 Javascript
vue-cli之router基本使用方法详解
Oct 17 Javascript
vue element-ul实现展开和收起功能的实例代码
Nov 25 Vue.js
浅谈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 字符串操作入门教程
2006/12/06 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
2013/04/23 PHP
PHP正则删除HTML代码中宽高样式的方法
2017/06/12 PHP
锋利的jQuery 要点归纳(一) jQuery选择器
2010/03/21 Javascript
Javascript引用指针使用介绍
2012/11/07 Javascript
window.navigate 与 window.location.href 的使用区别介绍
2013/09/21 Javascript
jquery索引在使用中的一些困惑
2013/10/24 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
JS动态创建DOM元素的方法
2015/06/09 Javascript
jQuery文字提示与图片提示效果实现方法
2016/07/04 Javascript
在js代码拼接dom对象到页面上去的模板总结(必看)
2017/02/14 Javascript
JavaScript观察者模式(publish/subscribe)原理与实现方法
2017/03/30 Javascript
浅谈关于angularJs中使用$.ajax的注意点
2017/08/12 Javascript
VS Code转换大小写、修改选中文字或代码颜色的方法
2017/12/15 Javascript
JS处理一些简单计算题
2018/02/24 Javascript
Vue封装一个简单轻量的上传文件组件的示例
2018/03/21 Javascript
微信小程序实现两个页面传值的方法分析
2018/12/11 Javascript
JS学习笔记之闭包小案例分析
2019/05/29 Javascript
vue中使用WX-JSSDK的两种方法(推荐)
2020/01/18 Javascript
[02:21]十步杀一人,千里不留行——DOTA2全新英雄天涯墨客展示
2018/08/29 DOTA
Flask框架学习笔记(一)安装篇(windows安装与centos安装)
2014/06/25 Python
python3+opencv3识别图片中的物体并截取的方法
2018/12/05 Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
2019/01/05 Python
Python OpenCV 使用滑动条来调整函数参数的方法
2019/07/08 Python
通过 Django Pagination 实现简单分页功能
2019/11/11 Python
python将邻接矩阵输出成图的实现
2019/11/21 Python
Python sql注入 过滤字符串的非法字符实例
2020/04/03 Python
pandas中read_csv、rolling、expanding用法详解
2020/04/21 Python
CSS3下的渐变文字效果实现示例
2018/03/02 HTML / CSS
全球最受追捧的运动服品牌领先数字目的地:Stylerunner
2020/11/25 全球购物
《在山的那边》教学反思
2014/02/23 职场文书
启动仪式策划方案
2014/06/14 职场文书
2014物价局群众路线对照检查材料思想汇报
2014/09/21 职场文书
行政执法作风整顿剖析材料
2014/10/11 职场文书
投资合作意向书范本
2015/05/08 职场文书
OpenCV-Python模板匹配人眼的实例
2021/06/08 Python