WEB开发网
开发学院网页设计JavaScript 做自由落体运动的JSF组件,使用javascript打造富有... 阅读

做自由落体运动的JSF组件,使用javascript打造富有个性的漂亮组件——QFaces

 2010-09-14 13:44:06 来源:WEB开发网   
核心提示: QFaces.facesMakeFrame(id) 这个函数可以给任意组件id添加一个边框,包括div,table,可见的,不可见的等,甚至button,做自由落体运动的JSF组件,使用javascript打造富有个性的漂亮组件——QFaces(2),input...这个函数相对简单得多,

QFaces.facesMakeFrame(id)

这个函数可以给任意组件id添加一个边框,包括div,table,可见的,不可见的等,甚至button,input...这个函数相对简单得多,但是很方便,效果也非常好,在QFaces组件库下可以直接调用,里面捆绑了8张小png作为组件边框,这是我在photoshop中做的图,然后切割而成的,可以很方便的替换,共4个角4个边。如果单独使用,那么需要指定这些图片的位置。并约束一下左上角及右下角的宽高就可以了,。单用CSS也可以做出圆角及阴影效果,但是再怎么做也没有photoshop做出来的效果好。

函数原形:

QFaces.accDisplay = function(id, action, direction, G)

QFaces.accDisplay = function(id, action, direction, G) {
    var mydiv = QFaces.getComponent(id);
    if (mydiv.locked) {
        return;
    } else {
        mydiv.locked = true; // 锁定source,避免快速无限点击。
    }
    // 这里表示了从原始宽高度的0倍 -> 运行到原始宽高 -> 然后跳回原来的0.8倍 -> 再回到原来的宽高度。
    // 配合自由落体 (S = v0t * 1/2att),看起来就是一个弹跳过程。
    var stepArr = new Array();
    if (action == "show" || action == null) {
        stepArr[0] = 0;
        stepArr[1] = 1.2;
        stepArr[2] = 0.8;
        stepArr[3] = 1;
    } else if (action == "hide") {
        stepArr[0] = 1;
        stepArr[1] = 1.2;
        stepArr[2] = 0;
    }

    // 初始化变量.高度与G的比例    250xp : 0.006S
    var size = QFaces.getSize(id);
    var stretchObj = new StretchObject();
    stretchObj.source = mydiv;
    stretchObj.action = (action == null ? "show" : action); // 确定方向
    stretchObj.originalLeft = mydiv.offsetLeft;
    stretchObj.originalWidth = size[0];
    stretchObj.originalHeight = size[1];
    stretchObj.stepArr = stepArr;
    stretchObj.interval = 10;
    // 以一个比率动态改变加速度大小,避免大区块的动画时间过长
    // stretchObj.G = 0.006;
    stretchObj.G = (stretchObj.originalHeight * 0.006 / 250);
    if (direction == null || direction == "height" || direction == "both") {
        stretchObj.displayHeight = true;
    }
    if (direction == "width" || direction == "both") {
        stretchObj.displayWidth = true;
    }
    if (G != null) {stretchObj.G = G;} // 如果用户指定了加速度做自由落体运动的JSF组件,使用javascript打造富有个性的漂亮组件——QFaces
    stretchObj.init();    // 初始化
    travel(stretchObj); // Start display

    function travel(obj) {
        // 累计单步的执行时间,并计算距离。
        obj.stepTimeUsed += obj.interval;
        obj.stepDistance = obj.v0 * obj.stepTimeUsed + 0.5 * obj.G * obj.stepTimeUsed * obj.stepTimeUsed;
        // 设置source的位置,高宽度。
        obj.setSize(obj.stepWidth + obj.stepDistance, obj.stepHeight + obj.stepDistance);
        // 运行完毕后解锁source,并跳出。
        if (obj.isOver()) {
            obj.setSize(obj.originalWidth * obj.stepArr[obj.stepArr.length - 1], obj.originalHeight * obj.stepArr[obj.stepArr.length - 1]);
            // 如果是收缩,则清理数据后隐藏,并且设回原始位置
            if (obj.action == "hide") {
                obj.source.style.left = obj.originalLeft + "px";
                obj.source.style.width = "";
                obj.source.style.height = "";
                obj.source.style.display = "none";
            }
            obj.source.locked = false;
            return;
        }
        // 单步运行完毕
        if (obj.isStepOver()) {
            obj.stepOver();
        }
        QFaces.setTimeout(travel, obj.interval, obj);
    }

    function StretchObject() {
        this.source = null;         // 绑定的界面控件
        this.action = null;
        this.originalLeft = null;     // 原始的位置偏移
        this.originalWidth = null;     // 原始宽度
        this.originalHeight = null; // 原始高度
        this.displayWidth = false;
        this.displayHeight = false;
        this.stepArr = null;         // 要运行的数组
        this.v0 = null;
        this.v1 = null;
        this.step = 1;
        this.stepWidth = 0;     // 步宽,每次方向改变时都会改变。
        this.stepHeight = 0;     // 同上
        this.stepTimeTotal = 0; // 每次落下或弹起所需要的总时间。
        this.stepTimeUsed = 0;     // 每次落下或弹起的时间累计。
        this.stepDistance = 0;     // 在stepTimeUsed下所运行的距离
        this.G = 0.006;         // 重力加速度,为什么不是9.8米/秒?因为这里不是地球 ————是QFaces星球
        this.interval = 10;

        this.isOver = function() {
            return (this.step > this.stepArr.length - 1);
        }
        this.isZoomOut = function() {
            return (this.stepArr[this.step] > this.stepArr[this.step - 1]);
        }
        this.isStepOver = function() {
            if (this.stepTimeUsed >= this.stepTimeTotal) {return true;}// 这里防止无限止伸缩。
            var currentHeight = this.stepHeight + this.stepDistance;
            if (this.isZoomOut()) {
                return currentHeight >= this.originalHeight * this.stepArr[this.step];
            } else {
                return currentHeight <= this.originalHeight * this.stepArr[this.step];
            }
        }
        this.setSize = function(width, height) {
            if (this.displayWidth && width >= 0)
                this.source.style.width = width + "px";
            if (this.displayHeight && height >= 0)
                this.source.style.height = height + "px";
            if (this.displayWidth && width >= 0) {// 重新设置source的位置偏移。
                this.source.style.left = (this.originalLeft + (this.originalWidth - width) * 0.5) + "px";
            }
        }
        this.calculateStepTimeTotal = function() {
            if (this.stepArr[this.step] != null) {
                var nextS = Math.abs(this.originalHeight * (this.stepArr[this.step] - this.stepArr[this.step - 1]));
                if (this.isZoomOut()) { // 下降过程 s = 0.5gtt;
                    this.stepTimeTotal = Math.sqrt(2 * nextS / this.G);
                } else {// G = (v1 - v0)/t
                    this.stepTimeTotal = Math.abs((this.v0 - this.v1) / this.G);
                }
            } else {
                this.stepTimeTotal = 0;
            }
        }
        this.stepOver = function() {
            var isZoomOut_previous = this.isZoomOut();
            this.stepWidth = this.originalWidth * this.stepArr[this.step];
            this.stepHeight = this.originalHeight * this.stepArr[this.step];
            this.setSize(this.stepWidth, this.stepHeight);
            this.step += 1; // 进入下一阶段
            this.stepDistance = 0;
            this.stepTimeUsed = 0;
            
            // 特别情况(渐缩):如果前一阶段是下降,并且整个过程是渐缩 。 (s = v0t + 0.5gtt)
            if (this.action == "hide") {
                if (isZoomOut_previous) {
                    var zoomInS = Math.abs(this.originalHeight * (this.stepArr[this.step] - this.stepArr[this.step - 1]));
                    var zoomInT = Math.sqrt(2 * zoomInS / this.G);
                    this.v0 = this.G * zoomInT; // 用整段最长距离计算从最大位置缩回none时的初速度,瞬速。
                    this.v0 = this.v0 * -1;        // 上升过程,v0必须是负的
                    this.v1 = 0;
                } 
            } else {// 正常渐展开的过程。
                if (isZoomOut_previous) {
                    this.v0 = this.v1 * -1; // 在落地返弹瞬间,速度达最大,并且末速度变成反弹之后的始速度
                    this.v1 = 0; // 下一阶段的反弹末速度为0
                } else {// 从上升到下降
                    // 计算下一下降过程需要经过的距离。
                    var tempS = Math.abs(this.originalHeight * (this.stepArr[this.step] - this.stepArr[this.step - 1]));
                    var tempT = parseInt(Math.sqrt((2 * tempS / this.G))); // 计算下降需要经过的时间。
                    var tempGT = this.G * tempT; // 计算末速度。
                    this.v0 = 0;
                    this.v1 = tempGT;
                }
            }
            // 计算下一段所需要的时间
            this.calculateStepTimeTotal();
        }
        this.init = function() {
            this.source.style.display = "block";
            this.source.style.overflow = "hidden";
            this.source.style.position = "absolute";
            this.source.style.zIndex = QFaces.zIndex++;

            this.stepWidth = this.originalWidth * this.stepArr[this.step - 1];
            this.stepHeight = this.originalHeight * this.stepArr[this.step - 1];
            this.originalLeft = this.source.offsetLeft; // 必须保存原始偏移。

            if (this.displayWidth)
                this.source.style.width = this.stepWidth + "px";
            if (this.displayHeight)
                this.source.style.height = this.stepHeight + "px";

            var s = this.originalHeight * (this.stepArr[this.step] - this.stepArr[this.step - 1]);
            if (this.isZoomOut()) { // 加速
                this.v0 = 0;
                this.v1 = this.G * parseInt(Math.sqrt((2 * s / this.G)));
            } else { // 减速
                this.v0 = this.G * parseInt(Math.sqrt(Math.abs(2 * s / this.G))) * -1;
                this.v1 = 0;
            }
            // 计算下一级所需要的时间.
            this.calculateStepTimeTotal();
        }
    }
}

上一页  1 2 3 4  下一页

Tags:自由落体 运动 JSF

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接