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 相关文章推荐
完美解决AJAX跨域问题
Nov 01 Javascript
用原生js做个简单的滑动效果的回到顶部
Oct 15 Javascript
jQuery插件PageSlide实现左右侧栏导航菜单
Apr 12 Javascript
javascript的正则匹配方法学习
Feb 24 Javascript
jQuery拖拽通过八个点改变div大小
Nov 29 Javascript
详解node服务器中打开html文件的两种方法
Sep 18 Javascript
jqgrid实现简单的单行编辑功能
Sep 30 Javascript
微信小程序实现图片懒加载的示例代码
Dec 13 Javascript
JS实现用特殊符号替换字符串的中间部分区域的实例代码
Jul 24 Javascript
Vue.js中使用iView日期选择器并设置开始时间结束时间校验功能
Aug 12 Javascript
js中对象与对象创建方法的各种方法
Feb 27 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
Nov 15 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 购物车完整实现代码
2014/06/05 PHP
php生成唯一的订单函数分享
2015/02/02 PHP
PHP中的Trait 特性及作用
2016/04/03 PHP
微信支付开发发货通知实例
2016/07/12 PHP
php in_array() 检查数组中是否存在某个值详解
2016/11/23 PHP
php进程(线程)通信基础之System V共享内存简单实例分析
2019/11/09 PHP
JS DOM 操作实现代码
2010/08/01 Javascript
js静态方法与实例方法分析
2011/07/04 Javascript
javascript在IE下trim函数无法使用的解决方法
2014/09/12 Javascript
JavaScript学习笔记之数组的增、删、改、查
2016/03/23 Javascript
总结JavaScript设计模式编程中的享元模式使用
2016/05/21 Javascript
Vue.js使用v-show和v-if的注意事项
2016/12/13 Javascript
使用jQuery操作DOM的方法小结
2017/02/27 Javascript
js实现一个简单的数字时钟效果
2017/03/29 Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
vue移动端使用canvas签名的实现
2020/01/15 Javascript
openlayers实现图标拖动获取坐标
2020/09/25 Javascript
Swiper实现导航栏滚动效果
2020/10/16 Javascript
vue在图片上传的时候压缩图片
2020/11/18 Vue.js
Python中的类与对象之描述符详解
2015/03/27 Python
Python信息抽取之乱码解决办法
2017/06/29 Python
python MySQLdb使用教程详解
2018/03/20 Python
python统计字母、空格、数字等字符个数的实例
2018/06/29 Python
python3+requests接口自动化session操作方法
2018/10/13 Python
Python使用folium excel绘制point
2019/01/03 Python
python日志模块logbook使用方法
2019/09/19 Python
python实现提取str字符串/json中多级目录下的某个值
2020/02/27 Python
keras 解决加载lstm+crf模型出错的问题
2020/06/10 Python
北大青鸟学生求职信
2013/09/24 职场文书
表彰先进的通报
2014/01/31 职场文书
《青蛙看海》教学反思
2014/04/23 职场文书
大学活动总结范文
2014/04/29 职场文书
幼儿园母亲节活动总结
2015/02/10 职场文书
Oracle 临时表空间SQL语句的实现
2021/09/25 Oracle
Django中celery的使用项目实例
2022/07/07 Python
Pytorch中expand()的使用(扩展某个维度)
2022/07/15 Python