david0116
david0116

Reputation: 103

Rotate svg image from center after moving

I have made a basic svg image resizing, rotating and dragging inside mask on fiddle. I'm getting trouble in rotate image from center after moving. How do I reset origin x,y after moving?

Please move the image first, then rotate it with slider.

Try here: https://jsfiddle.net/david7418/o497akje/6/

Transform attribute gets overwrited here. How do I get origin x,y and put into transform arguments?

  //Slider rotate
  $( "#slider_rotate" ).slider({
      max: 360, 
      min: 0, 
      step:1, 
      value:0,
      slide: function( event, ui ) {
      var matrixObj = obj.transform().localMatrix.split()
      console.log(matrixObj);
          var t = new Snap.Matrix();
           //Transform overwrite
           t.add(obj.transform().localMatrix);
          obj.transform('r'+ui.value+','+t);        
      }
   });

Full code:

$(function() {
   obj = Snap(".cat");
   //Enable drag event
   obj.drag();
   var dimens = obj.node.getBoundingClientRect();    
   var orinDimens = dimens;
   //Image max enlarge rate
   var enlargeRate = 4;
   var smax = dimens.width;

   //Slider resize
   $( "#slider_resize" ).slider({
      max: smax*enlargeRate, 
      min: smax, 
      step:1, 
      value:dimens.width,
      slide: function( event, ui ) {
         w = ui.value * dimens.width / smax;
         h = ui.value * dimens.height / smax;
         obj.attr({
            width: w,
            height: h,
            x: (dimens.width - w)/2,
            y: (dimens.height - h)/2
         });
      }
   });

  //Slider rotate
  $( "#slider_rotate" ).slider({
      max: 360, 
      min: 0, 
      step:1, 
      value:0,
      slide: function( event, ui ) {
          obj.transform('r'+ui.value);        
      }
   });

   //Reset button
   $('#reset').click(function(){
       $("#slider_resize").slider('value',orinDimens.width);
       $("#slider_rotate").slider('value',0);
       var objMatrix = new Snap.Matrix();
       objMatrix.translate(0,0); 
       objMatrix.rotate(0);
       obj.transform(objMatrix);
       obj.attr({width: orinDimens.width,x:0})
   });

});

Upvotes: 0

Views: 370

Answers (1)

Ian
Ian

Reputation: 13842

I would create one central place to update all the transforms. It flows a bit easier probably if you use a Snap plugin as well for ease of coding, so something like the following.

We will store the x,y,r,s variables in a data() method for the object.

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)
    }

});

Now we have an update method, we can call this, any time we change something on the screen, or want to initialise it or whatever.

So when we want to reset it all, we can call...

$('#reset').click(function(){
   obj.init().updateTransform();
});

For the drag handler...(store the old position in oxy)

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();
}

And for the sliders, we just store the values, and call updateTransform()

$( "#slider_resize" ).slider({
      max: 4,
      min: 1,
      step:0.1, 
      slide: function( event, ui ) {
        obj.data('s', ui.value)
           .updateTransform();
      }
   });

With it all tied together, it would look like...

jsfiddle

Upvotes: 1

Related Questions