zoukankan      html  css  js  c++  java
  • js动画框架设计

    当你不再依赖JQuery时,当你已经厌倦了引入js类库实现一些动画效果的方式,当你想实现一个简单而实用的动画框架......下面介绍下愚人设计的动画框架:支持动画缓动算法函数,如Linear、Cubic、Back、Bounce,支持改变高度,宽度,透明度,边框,外边距的基本动画,支持动画的回调函数,如开始、暂停、完成的callback等。

     
     
    Section One
    游戏动画,Flash动画里一个比较重要的概念是帧频,即每秒播放多少帧动画,一般动画是30帧/秒,单位为fps(frames per second)。
     
    对于匀速运动来说:如果一个动画的持续时间duration为500ms,帧频frequence为30fps,则总帧数frames为(500/1000)*30 = 15,即该动画过程有15个“画面”,每走一帧,都计算出一个画面:画面当前位置 = 开始位置 + (当前帧/总帧数)(结束位置-开始位置),如果当前帧是最后一帧,则动画结束。其中setTimeout或setInterval每隔(500/15)ms时间段调用一次函数,即计算一个画面。
     
    来看下线性运动Linear缓动算法函数,t表示当前帧,b表示开始位置,c表示发生偏移的距离值,即当前位置-开始位置,d表示总帧数,符合上面的推理解释,对于其他的算法函数,道理其实都是一样,只不过在运动过程中的曲线不同,有些呈现抛物线,有些呈现线性指数,对于数学感兴趣的可以研究下这些算法函数,我也是略知皮毛:
     
    Linear: function (t, b, c, d) {
    return c * t / d + b;
    }
    清楚了以上问题后,对于js的动画框架设计,就迎刃而解了,废话不多说,来个 demo 先。
     
    Section Two
    代码总体结构,具体说明看注释,需注意的问题:1)在私有作用域里定义的变量,要在外部能访问到,需挂在window全局对象下,如window.Anim = Anim;2)动画元素需要设置定位position属性;3)传入的外边距参数需要驼峰式命名,并且当同时设置targetPos(元素目标位置)和外边距时,外边距的值会覆盖targetPos的值,如marginLeft的值会覆盖targetPos.left的值,因为外边距实现动画的原理也是利用元素的left、top值:
     
     
     
    (function(window) {
        /*
         * 工具对象
         * 包含基本的dom操作,event操作
         */
        var util = {};
        util.dom = {
            // 获取元素计算样式
            getPropValue: function(element, propName) {
            },
            // 设置透明度
            setOpacity: function(obj, num) {
                document.all ? obj.filters.alpha.opacity = num : obj.style.opacity = num / 100;
            }
            // ......
        };
        util.event = {
            // 获取事件对象
            getEvent: function(event) {
            },
            // 获取事件源目标
            getTarget: function(event) {
            },
            // 注册事件
            addEvent: function(element, event, handler) {
            },
            // 删除事件
            removeEvent: function(element, event, handler) {
            },
            // 阻止默认行为
            preventDefault: function(event) {
            },
            // 阻止事件冒泡
            stopPropagation: function(event) {
            }
            // ......
        };
     
        /*
        * 动画缓动函数
        */
        var Tween = {
            Linear: function (t, b, c, d) { return c * t / d + b; },
            Quad: {
                easeIn: function (t, b, c, d) {
                    return c * (t /= d) * t + b;
                },
                easeOut: function (t, b, c, d) {
                    return -c * (t /= d) * (t - 2) + b;
                },
                easeInOut: function (t, b, c, d) {
                    if ((t /= d / 2) < 1) return c / 2 * t * t + b;
                    return -c / 2 * ((--t) * (t - 2) - 1) + b;
                }
            },
            // ...
        };
     
        /*
         * 核心动画
         * @elem 要执行动画的元素
         * @options left、top、opacity、width、height、border、marginLeft、marginRight、marginTop、marginBottom
         */
        function Anim(elem, options) {
            this.elem = elem;
            this.options = options;
            // 默认样式属性
            this.defaults = {
            };
        }
        Anim.prototype = {
            constructor: Anim,
            // 初始化动画
            init: function() {
                this.isStart = false;
                this.isStop = false;
                this.isComplete = false;
                this.isBack = false;
                this.start();
            },
            // 初始化数据
            before: function() {
            },
            // 开始动画
            start: function() {
            },
            // 动画过程
            run: function() {
                this.before();
                // 动画参数匹配
                this.match();
                // 原路返回
                if (this.isBack) {
                    // ...
                }
                if (this.isStart) {
                    this.onStart.call(this.elem);
                    // 计算动画
                    this.count();
                }
            },
            // 匹配动画的参数
            match: function() {
            },
            // 计算动画
            count: function() {
            },
            // 原路返回
            back: function() {
            },
            // 停止动画
            stop: function() {
            },
            // 重置元素
            reset: function() {
            }
        };
     
        // 全局使用
        if (!window.util) {
            window.util = util;
        }
        if (!window.Anim) {
            window.Anim = Anim;
        }
        if (!window.Tween) {
            window.Tween = Tween;
        }
     
    })(window);
     
    Last
    使用非常简单,初始化参数对象,然后调用构造函数Anim即可:
     
    // 动画参数设置
    var options = {
        duration: 2000, // 动画持续时间
        frequence: 30, // 帧频
        tweenFunc: Tween.Linear, // 动画缓动函数
        targetPos: {left: 400, top: 300}, // 元素目标位置
        opacity: 40, // 透明度(可选)
        80, // 宽度(可选)
        height: 80, // 高度(可选)
        // marginTop: 100, // 上边距(可选)
        border: '2px solid red', // 边框(可选)
        // 动画开始callback(可选)
        onStart: function() {
            // this指向当前动画元素
        },
        // 动画停止callback(可选)
        onStop: function() {
            // this指向当前动画元素
        },
        // 动画完成callback(可选)
        onComplete: function() {
            // this指向当前动画元素
        }
    };
    var anim = new Anim(animElem, options);
     
    最后附上 源代码 以及easing算法函数的 demo。
     
     
  • 相关阅读:
    IIS是如何处理ASP.NET请求的
    c# Socket通讯中关于粘包,半包的处理,加分割符
    windows2008(64位)下iis7.5中的url伪静态化重写(urlrewrite)
    C#微信公众号/订阅号开发 接口源码
    C#线程池多线程Socket通讯 服务器端和客户端示例
    百度地图JS调用示例
    c# 图片转二进制/字符串 二进制/字符串反转成图片
    电商项目面试总结
    96. Unique Binary Search Trees
    92.Reverse Linked List II
  • 原文地址:https://www.cnblogs.com/dianshi/p/4212900.html
Copyright © 2011-2022 走看看