Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set css rotation to point an element towards a point

I am trying to rotate a div towards a point using css 3 transform rotate function.

I got up to this point: jsfiddle link

$(document).ready(function(){
    var scw,sch,scx,scy;
    calcCenter();
    $(window).resize(function() {         
        calcCenter();
    });
    function calcCenter(){
      sch = $(window).height(); 
      scw = $(window).width(); 
      scx = scw/2;
      scy = sch/2;
        $(".circle").remove();
      var circle = $("<span></span>").addClass('circle').text('.');
      circle.css('top',scy-50+"px");
      circle.css('left',scx-50+"px");
    $(document.body).append(circle);
    }
    function calcAngle(p1,p2){

        var angle = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
        return angle;
    }



    $(document).click(function(e){  
        var box = $("<span></span>").addClass('box');
        var x = e.pageX,y=e.pageY; 
        box.css('top',y+"px");
        box.css('left',x+"px"); 

        $(document.body).append(box);
        var angle = calcAngle({x:x,y:y},{x:scx,y:scy});

        box.css('-webkit-transform','rotate('+(90+angle)*-1+'deg)');        

        box.draggable({
                drag: function(e) {
                        var box = $(this);
                        var x = e.pageX,y=e.pageY; 
                        box.css('top',y+"px");
                        box.css('left',x+"px");
                        var angle = calcAngle({x:x,y:y},{x:scx,y:scy});

                        box.css('-webkit-transform','rotate('+(90+angle)*-1+'deg)');


                        }
                      });
    });

    var sunAngle = 1;
    setInterval(function(){
        var sun = $("span.circle")[0];
        $(sun).css('-webkit-transform','rotate('+sunAngle+'deg)');
        sunAngle = (sunAngle+1) %360;           
    },100);
});

I googled "lookat" function, and found something like lookat matrix only.

like image 625
rajaramesh Avatar asked Sep 25 '14 08:09

rajaramesh


People also ask

How do I rotate an image with a point in CSS?

rotate() The rotate() CSS function defines a transformation that rotates an element around a fixed point on the 2D plane, without deforming it. Its result is a <transform-function> data type.

How do you spin an element in CSS?

The CSS rotate() function lets you rotate an element on a 2D axis. The rotate() function accepts one argument: the angle at which you want to rotate your web element. You can rotate an element clockwise or counter-clockwise.

How do you change rotation in CSS?

Rotating an image using CSS Once the CSS code is applied to your . css file, stylesheet, or <style> tags, you can use the CSS class name in any of your image tags. To rotate an image by another measure of degrees, change the "180" in the CSS code and <img> tag to the degree you desire.

How do I change the angle of an element in CSS?

CSS rotate() Function. The CSS rotate() function is used to rotate elements in a two-dimensional space. The rotate() function rotates an element based on the angle that you provide as an argument. You can provide the angle using any valid CSS angle value (i.e. in degrees, gradians, radians, or turns).


1 Answers

First of all, the center of your circle is not being calculated correctly. Your circle is 120px wide and high, but you "center" it by setting its top and left to scy - 50, where you should have used scy - 60 (half of 120px is 60px). Or even better, also calculate half circle width and height dynamically and subtract that, in case you change your mind and make it a different size again.

I just did it statically:

circle.css('top',scy-60+"px");
circle.css('left',scx-60+"px");

Second, you want to calculate the angle the .box elements needs to rotate around its center, but you use its top and left positions to do so. That's incorrect.

Again, dynamic would be better, but let's do it static for now:

var angle = calcAngle({x:x + 32,y:y + 32},{x:scx,y:scy});

Then I'm not sure what you're doing with atan2() * 180 / Math.PI, since atan2 returns rads and you want degrees I double checked how to calculate between the two. Turns out it's not as simple as you thought. See this answer.

So I added a function:

function radToDegree(rad) {
    return (rad > 0 ? rad : (2*Math.PI + rad)) * 360 / (2*Math.PI)
}

And implemented it before returning the angle:

function calcAngle(p1,p2){      
    var angle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
    return radToDegree(angle);
}

Now, degrees start from the top, meaning if the angle is 0 degrees it will point upwards whereas you need it to point to the right due to the way your calculations are set up. So you added + 90 to your final rotate calculations.

That would have been fine if your point started upwards, but it doesn't. It starts from the bottom left, which is another 135 degrees. Add those up, and you get a 225 degree difference. So:

box.css('-webkit-transform','rotate('+(angle+225)+'deg)');  

And voila, your script works: http://jsfiddle.net/7ae3kxam/42/

edit: also works for dragging now

like image 130
Stephan Muller Avatar answered Oct 02 '22 03:10

Stephan Muller