2017年3月21日 星期二

(js)將 matrix 轉換成 scale, rotate

_transformMatrix = function(tr) {
            debugger
            // var values = tr.split('(')[1].split(')')[0].split(',');

            var values = tr.split('(')[1];
            values = values.split(')')[0];
            values = values.split(',');


            var a = Number(values[0]);
            var b = Number(values[1]);
            var c = Number(values[2]);
            var d = Number(values[3]);
            /* ---------------------------------- */
            var scaleX = Math.sqrt(a * a + b * b);

            scaleX = scaleX.toFixed(5);
            console.log('ScaleX: ' + scaleX);
            /* ---------------------------------- */
            var scaleY = Math.sqrt(c * c + d * d);

            scaleY = scaleY.toFixed(5);
            console.log('ScaleY: ' + scaleY);
            /* ---------------------------------- */
            // arc sin, convert from radians to degrees, round
            // var sin = b / scale;
            // var angle = Math.round(Math.asin(sin) * (180 / Math.PI));

            // var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));

            var radians = Math.atan2(b, a);
            if (radians < 0) {
                radians += (2 * Math.PI);
            }
            var angle = Math.round(radians * (180 / Math.PI));

            console.log('Rotate: ' + angle + 'deg');

            return {
                rotate: angle,
                scaleX: scaleX,
                scaleY: scaleY
            };
        };
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * requestAnimationFrame
 */
window.requestAnimationFrame = (function(){
    return  window.requestAnimationFrame       ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame    ||
            window.oRequestAnimationFrame      ||
            window.msRequestAnimationFrame     ||
            function (callback) { window.setTimeout(callback, 1000 / 60); };
})();

var RAD_TO_DEG = 180 / Math.PI,
    RE_MAT = /matrix\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\)/;

var box  = document.getElementById('box'),
    disp = document.getElementById('disp'),
    prefix,
    transform;

prefix = (function() {
    var vendor = ['webkit', 'Moz'],
        testStyle = document.createElement('div').style,
        i, len;

    for (i = 0, len = vendor.length; i < len; i++) {
        if (testStyle.hasOwnProperty(vendor[i] + 'Transform')) {
            return vendor[i];
        }
    }

    return '';
})();

transform = prefix ? prefix + 'Transform' : 'transform';
animationPlayState = prefix ? prefix + 'AnimationPlayState' : 'animationPlayState';

document.addEventListener('click', function() {
    var isPaused = box.style[animationPlayState] === 'paused';
    box.style[animationPlayState] = isPaused ? 'running' : 'paused'

}, false);

function loop() {
    var computedStyle, mat, a, b, c, d, e, f, scale, rotate;

    computedStyle = window.getComputedStyle(box, null);
    mat = computedStyle[transform].match(RE_MAT).slice(1);
    a = parseFloat(mat[0], 10);
    b = parseFloat(mat[1], 10);
    c = parseFloat(mat[2], 10);
    d = parseFloat(mat[3], 10);
    e = parseFloat(mat[4], 10);
    f = parseFloat(mat[5], 10);
    scale  = Math.sqrt(a * a + b * b);
    rotate = (Math.atan2(b, a) * RAD_TO_DEG + 360) % 360;

    disp.innerHTML =
        'translate(' + e + 'px,' + f + 'px)<br/>' +
        'rotate(' + rotate + 'deg)<br/>' +
        'scale(' + scale + ')';

    requestAnimationFrame(loop);
};

loop();