Search code examples
javascriptsvgsnap.svg

How to initial exist image matrix with snap svg?


Thanks lan who helped me to complete svg transform with slider Fiddle.

After some progresses I got another problem about it.If the image has exist matrix, how should I apply it to the slider at the beginning? As Fiddle example, the image behavior looks strange while I drag the slider.

$(function() {
    Snap.plugin(function(Snap, Element, Paper, global) {
        Element.prototype.updateTransform = function() {
            var newTransform = 't' + (this.data('xy').x) + ',' + (this.data('xy').y);
            newTransform += 'r' + (this.data('r'))
            newTransform += 's' + (this.data('s'))
            this.transform(newTransform)
            return this;
        }
        Element.prototype.init = function() {
            return this.data('xy', {
                    x: 0,
                    y: 0
                })
                .data('r', 0)
                .data('s', 1)
        }

    });

    function dragStart(x, y) {
        this.data('oxy', this.data('xy'));
    }

    function dragMove(dx, dy, x, y) {
        this.data('xy', {
                x: this.data('oxy').x + dx,
                y: this.data('oxy').y + dy
            })

            .updateTransform();
    }
    obj = Snap(".cat");
    obj.init();
    obj.drag(dragMove, dragStart);

    //Slider resize
    $("#slider_resize").slider({
        max: 4,
        min: 1,
        step: 0.1,
        slide: function(event, ui) {
            obj.data('s', ui.value)
                .updateTransform();
        }
    });
    //Slider rotate
    $("#slider_rotate").slider({
        max: 360,
        min: 0,
        step: 1,
        value: 0,
        slide: function(event, ui) {
            obj.data('r', ui.value)
                .updateTransform();
        }
    });

    //Reset button
    $('#reset').click(function() {
        $("#slider_resize").slider('value', 0);
        $("#slider_rotate").slider('value', 0);
        obj.init().updateTransform();
    });
});

Solution

  • You can store the initial transform, and then add it on each time to the start of the new transform..so relevant bits would be...

    In our init function, check if we have stored an initial transform, if not store it. We only want to do this once (otherwise you can't use the reset button).

    if( !this.data('origTransform') ) this.data('origTransform', this.transform())
    

    In the update transform function, we can add the original transform to the new one which we are manipulating, e.g

    this.transform( this.data('origTransform') + newTransform )
    

    jsfiddle

    This 'may' be what you want, depending on what's in that initial transform (as subsequent transforms are affected by it). It may start to get very complicated if it isn't, as matrices aren't really reversable (eg the proper translation from a matrix) otherwise, but there may be a way depending on requirements :). I would test it with an initial rotation and scale on the image and see if it does what you want (if that's what you will end up supporting).