2017年10月14日 星期六

jquery 處理單位換算

// elem: dom
    // prop: cssKey
    // valueParts(單位與數值)
    function adjustCSS(elem, prop, valueParts, tween) {
        debugger;

        var adjusted;
        var scale = 1;
        var maxIterations = 20;

        //----------------------------
        // 獲取現在的值
        var currentValue = tween ?
                function () {
                    return tween.cur();
                } :
                function () {
                    return jQuery.css(elem, prop, "");
                };
        var initial = currentValue();
        //----------------------------
        // 設定的單位
        let unit;

        if (valueParts && valueParts[3]) {
            unit = valueParts[3];
        } else {
            unit = (jQuery.cssNumber[prop] ? "" : "px");
        }
        //----------------------------
        // 預設單位
        // Starting value computation is required for potential unit mismatches
        var initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial);

        if (initialInUnit) {
            initialInUnit = rcssNum.exec(jQuery.css(elem, prop));
        }

        //----------------------------
        // 若預設單位與設定單位不同
        // 必須進入轉換
        if (initialInUnit && initialInUnit[3] !== unit) {

            // Trust units reported by jQuery.css
            unit = unit || initialInUnit[3];

            // Make sure we update the tween properties later on
            valueParts = valueParts || [];

            // Iteratively approximate from a nonzero starting point
            initialInUnit = +initial || 1;

            do {

                // If previous iteration zeroed out, double until we get *something*.
                // Use string for doubling so we don't accidentally see scale as unchanged below
                scale = scale || ".5";

                // Adjust and apply
                initialInUnit = initialInUnit / scale;
                jQuery.style(elem, prop, initialInUnit + unit);

                // Update scale, tolerating zero or NaN from tween.cur()
                // Break the loop if scale is unchanged or perfect, or if we've just had enough.
            } while (
                    (function () {
                        debugger;
                        let c_value = currentValue();
                        let a = scale;

                        // initial(一開始的值)
                        // 用目標單位移動後,取比例值,供下次修正
                        let b = scale = (c_value / initial);

                        return (a !== b) && (scale !== 1) && --maxIterations;
                    })()
                    );
        }
        //----------------------------
        if (valueParts) {
            initialInUnit = +initialInUnit || +initial || 0;

            // Apply relative offset (+=/-=) if specified
            adjusted = valueParts[1] ?
                    initialInUnit + (valueParts[1] + 1) * valueParts[2] :
                    +valueParts[2];
            if (tween) {
                tween.unit = unit;
                tween.start = initialInUnit;
                tween.end = adjusted;
            }
        }
        return adjusted;
    }--------------------------------------------------------------------