3

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.

3
  • what are you moving? Does it involve heavy painting? If not just change the top and left. Optimize only when its necessary. Commented Jul 14, 2013 at 22:33
  • 1
    There is no animation api in JS ..you basically just assign css to the .style of an element if you want to animate like this. Commented Jul 14, 2013 at 22:42
  • 1
    All CSS transforms can be expressed in the matrix form. Probably in some cases it will be easier to change matrix coefficients with JS than to build the compound 'transform' value as a string. There is a good introductory article on CSS transform matrices (also translated into Russian:), the maths for converting transform strings into matrices and back is described in the spec. Commented Jul 14, 2013 at 23:36

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.