Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

animating css transformations with javascript

I have a specific problem and general question.

I have to animate dragging with javascript (no frameworks), and I think it's better to use translate() instead of changing top and left, at least for better perfomance.

But it is part of user-driven interface, so I can't predefine any animation. So I have to build a string with updated values and assign it to element style property.

It's my problem.

So if I have to animate a few user-driven transformations I have to do relatively heavy string operations to update necessary values and keep those which I don't animate? Is there any kind of simpler API to do it with javascript?

I want to understand it at first, so no frameworks, please.

Thanks.

like image 249
Anton Avatar asked Sep 20 '26 18:09

Anton


1 Answers

I saw Ilya's comment about matrices, which is probably a good thing to check out. Given I am struggled at matrix math, a string based solution is right up my alley.

I threw this together in about half an hour but it seems to work well. I assume you'll just capture mouse move and update the translate value. I created the toObject method in case you wanted to do some more advanced animations.

I think if you're going to go this route, you should reconsider not wanting to use frameworks.

(function() {
    var setTransFunc, getTransFunc;

    // make sure cross browser...
    // I don't know if this is nescessary.  Every browser I tried worked on the first options.
    (function () {
        var testElem = document.createElement('DIV');
        if (testElem.style.transform !== undefined) {
            setTransFunc = function (elem, str) {
                elem.style.transform = str;
            }
            getTransFunc = function (elem) {
                return elem.style.transform;
            }
        }
        else if (testElem.style.webkitTransform !== undefined) {
            setTransFunc = function (elem, str) {
                elem.style.webkitTransform = str;
            }
            getTransFunc = function (elem) {
                return elem.style.webkitTransform;
            }
        }
        else if (testElem.style.msTransform !== undefined) {
            setTransFunc = function (elem, str) {
                elem.style.msTransform = str;
            }
            getTransFunc = function (elem) {
                return elem.style.msTransform;
            }
        }
        else {
            throw ('unable to detect set/get methods for transform style.');
        }
    }).call();

    // constructor
    var _tranZ = function (elem) {
        this.elem = (typeof elem == 'string') ? document.getElementById(elem) : elem;
    };

    (function () {
        this.elem = null;
        // sets transform style
        this.set = function (str) {
            setTransFunc(this.elem, str);
            return this;
        }
        // gets string of transform style
        this.get = function () {
            return getTransFunc(this.elem);
        }
        // adds a trasnform
        this.add = function (str) {
            this.set(this.get() + ' ' + str);
            return this;
        }
        // removes a transform
        this.remove = function (name) {
            var re = new RegExp(name + "\\([^)]*\\)", "gi");
            console.log(re);
            this.set(this.get().replace(re, ""));
            return this;
        }
        // represent transforms as object.  Might be easier later on to animate with this.
        this.getTransformObject = function () {
            var str = this.get(),
                re = /(\w+)\s*\(([^)]*)\)/g,
                match, obj = {};

            while (match = re.exec(str)) {
                obj[match[1]] = {
                    parameters: match[2].split(/\s*,\s*/)
                }
            }

            return obj;
        }
    }).call(_tranZ.prototype);

    // add a window module
    window.tranZ = function (elem) {
        return new _tranZ(elem);
    };
})();

jsFiddle

like image 151
Daniel Gimenez Avatar answered Sep 22 '26 07:09

Daniel Gimenez