Calculate new position post rotation

102 views Asked by At

I'm having trouble centering a div post rotation.

Here's my fiddle: https://jsfiddle.net/cfy2ztdz/

Move between slides with keyboard 1 & 2

You can see that it finds the middle perfectly without rotation, but post rotation, moving back to 1, moves off page - instead of back to the middle.

Where's my math going wrong?

Here's the most relevant code:

var windowWidth = $(window).width();
var windowHeight = $(window).height();

var winOriginX = windowWidth/2;
var winOriginY = windowHeight/2;

document.onkeypress = function(evt) {
      evt = evt || window.event;
      var charCode = evt.keyCode || evt.which;
      var charStr = String.fromCharCode(charCode);

      var slideWidth = $('#slide'+charStr).width();
      var slideHeight = $('#slide'+charStr).height();

      var slideXPos = $('#slide'+charStr).position().left;
      var slideYPos = $('#slide'+charStr).position().top;

      var originX = slideXPos + slideWidth/2;
      var originY = slideYPos + slideHeight/2;

      var xPos = winOriginX - slideXPos - slideWidth/2;
      var yPos = winOriginY - slideYPos - slideHeight/2;

      var rotation = 0;

      if($('#slide'+charStr).attr('slider-rotate')) {
        rotation = $('#slide'+charStr).attr('slider-rotate');
      }
      else {
        rotation = 0;
      }

      var nextRotation = rotation;


      $('#viewport').velocity({scaleX: "50%", scaleY: "50%", translateZ:0, rotateZ: nextRotation + "deg"},{duration: 1000, easing: 'easeInOutSine'});

      slideXPos = $('#slide'+charStr).position().left;
      slideYPos = $('#slide'+charStr).position().top;

      xPos = winOriginX - slideXPos - slideWidth/2;
      yPos = winOriginY - slideYPos - slideHeight/2;



      $('#slides').velocity({left: xPos + 'px', top: yPos + 'px', translateZ:0},{duration: 1000, easing: 'easeInOutSine'});
      $('#viewport').velocity({scaleX: "100%", scaleY: "100%", translateZ:0},{duration: 1000, easing: 'easeInOutSine'});

 }

And the HTML

  <div id="slides">

      <div id="slide1" class="slide" style="top: 300px; left: 100px; background: url('Andy.jpg');"></div>
      <div id="slide2" class="slide" style="top: 300px; left: 600px; background: transparent" slider-rotate="-75">
        <div style="width: 300px; height: 300px; background: url('Woody.jpg'); transform-origin: 50% 50%; transform: rotate(75deg)"></div>
      </div>

  </div>

1

There are 1 answers

2
Me.Name On BEST ANSWER

The problem is that after the rotation the new target x/y values are calculated based on the rotated positions. You could buffer the target centering x/y positions of the viewport inside each slide at startup, and reuse those while animating towards the centerpoint. In this example I used jquery data to store the values:

Fiddle

Script:

    $(document).ready(function() {
        var windowWidth = $(window).width();
        var windowHeight = $(window).height();

        var winOriginX = windowWidth/2;
        var winOriginY = windowHeight/2;
            $('#viewport').css('width',windowWidth).css('height',windowHeight);
      $('body').append('<div style="position: absolute; top:' + winOriginY + 'px; left:' + winOriginX + 'px; width: 5px; height: 5px; background: #000; z-index: 99999;"></div>');



        $('.slide').each(function(i,sl){
          var slide = $(sl);
          var slideWidth = slide.width();
          var slideHeight = slide.height();           
          var slideXPos = slide.position().left;
          var slideYPos = slide.position().top;

          var xPos = winOriginX - slideXPos - slideWidth/2;
          var yPos = winOriginY - slideYPos - slideHeight/2;

            slide.data('X', xPos);
            slide.data('Y', yPos);
        });

    });

   document.onkeypress = function(evt) {

       evt = evt || window.event;
       var charCode = evt.keyCode || evt.which;
       var charStr = String.fromCharCode(charCode);
       var slide =$('#slide'+charStr);             
       if(slide.length === 0)return; 

       var xPos = slide.data('X');
       var yPos =slide.data('Y');
       var rotation = slide.attr('slider-rotate');
       if(!rotation)rotation= 0;

       $('#viewport').velocity({scaleX: "50%", scaleY: "50%", translateZ:0, rotateZ: rotation + "deg"},{duration: 1000, easing: 'easeInOutSine', });   


       $('#slides').velocity({left: xPos + 'px', top: yPos + 'px', translateZ:0},{duration: 1000, easing: 'easeInOutSine'});

      $('#viewport').velocity({scaleX: "100%", scaleY: "100%", translateZ:0},{duration: 1000, easing: 'easeInOutSine'});

   }