Adjust css rotation to direct an element towards a specific point

Looking to rotate a div towards a point using the CSS 3 transform rotate function.

Progress so far: View code on JSFiddle

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

Searching for a "lookat" function led me to something similar to a lookat matrix.

Answer №1

Initially, the center of your circle seems to be miscalculated. The width and height of your circle are 120px each, but you have set its top and left positions based on a value of scy - 50, whereas it should have been scy - 60 (half of 120px equals 60px). It would be more efficient to calculate half of the circle's width and height dynamically and subtract those values, especially if the size changes in the future.

I have addressed this statically:

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

Additionally, when determining the angle by which the .box element needs to rotate around its center, using its top and left positions for this calculation is inaccurate.

Although a dynamic approach would be preferable, I will demonstrate the static method for now:

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

You seem to be applying atan2() * 180 / Math.PI without considering that atan2 returns radians rather than degrees. Redirected to a insightful answer explaining the conversion process between the two units here.

To resolve this issue, I included a function:

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

This function was then incorporated before returning the angle:

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

It is important to note that the degree calculation starts from the top. Therefore, an adjustment of + 90 to the final rotation calculation is necessary for correct orientation based on your existing setup. Since the initial position is bottom left at 135 degrees, the total deviation should be 225 degrees. Hence:

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

After implementing these adjustments, your script will run effectively: http://jsfiddle.net/7ae3kxam/42/

edit: also functional for dragging interactions now

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having issues sorting the ranking table numerically in a Javascript/jQuery/JSON/localStorage game

I have successfully created a leaderboard for my game, but I am struggling to automatically sort the scores from high to low. I believe that placing the objects into an array and then sorting them may be the solution, however, I am unsure of how to do th ...

Arrange a series by the actual pixel width of the string

Imagine you have an array of tags represented as strings and you need to display them in a narrow view. Some tags are smaller, allowing for 2 to fit on one line, while larger tags require their own line. Your goal is to sort the array so that the smalles ...

CSS Class Returns to Inactive State

One of my tasks involves adding a new class to an image. .bbbLink img { outline: 1px solid #ddd; border-top: 1px solid #fff; padding: 10px; background: #f0f0f0; } When hovering over the image, I apply the following styles, .bbbLink img ...

Adjusting the font size in Bootstrap grid rows to include an offset

I am currently working on improving site navigation using the Bootstrap Grid system. My goal is to create a layout with 3 columns and two rows structured as follows: |Title | |Login| |Subtitle|Menu buttons| | Everything seems to be functi ...

Troubleshoot: jQuery Datalink functionality not functioning properly with object methods

Within my JavaScript code, I have defined an object that includes various properties and an instance method that calculates a value based on two of those properties. To synchronize the object's property values with form elements in the UI, I am utili ...

Is this an effective and appropriate method for establishing media queries?

<link id ="style" rel="stylesheet" type="text/css" title="other" href="regularStyles.css" /> <link rel="stylesheet" media= "all and (mid-width: 767px) and (max-width:2049px) and (min-height:767px) and (max-height: 1538px)" href="notePads.css" /& ...

What is causing the collapsed-animation to malfunction in Vue3?

Why won't the transition animation function in vue3js? The animation does not appear to be working for me. I've implemented this library https://github.com/ivanvermeyen/vue-collapse-transition <template> <nav class="navbar color-d ...

Sending information to other domains and managing the feedback

As a newcomer to Jquery, I am attempting to send data to a cross-domain and need to manage the response, which is a complete HTML page. Here is the code snippet I am using: $.ajax({ url: "http://www.somehost.com/abc/xyz.php", type: "post", d ...

What is the best way to move between websites or pages without having to reload the current page using a selector?

Have you ever wondered how to create a webpage where users can navigate to other websites or pages without seeing their address, simply by selecting from a drop-down menu? Take a look at this example. Another similar example can be found here. When visit ...

Managing the result efficiently when asp.net mvc ModelState IsValid is false

My colleagues and I are currently working on a CRUD application using .net mvc4. The project involves rendering dynamic content through jQuery based on customer choices. One challenge we face is the need to create multiple hidden inputs to pass additional ...

Issue with the Bootstrap carousel jQuery plugin

Hi everyone, I need some help with creating a multiple items bootstrap carousel. I keep getting an error message that says "#Carousel".carousel is not a function TypeError: "#Carousel".carousel is not a function. Can anyone guide me on how to fix this issu ...

The PHP plugin I created seems to be adding an unnecessary whitespace at the end of its output

New to the world of PHP, I challenged myself to create a simple PHP plugin that generates a text greeting based on the time of day for users. To use my plugin, simply drop the .php file into your 'includes' folder and insert a line where you want ...

How can we ensure that the borders of a text field automatically adjust to fit the dimensions of the text field using CSS?

I've encountered an issue with the borders of text fields while working on a project involving CSS/HTML. The problem is that in the browser, the borders appear shorter than the text fields. Initially, I attempted to adjust the border size to match th ...

Strange issue: the code appears to be running multiple times with just one click

I've implemented a commenting system with a like feature. However, I'm facing an issue where sometimes clicking the like link results in sending multiple requests (up to 8-9) per click. This problem also occurs with another jQuery code that is tr ...

Issues with displaying images in CSS when using HTML 5 canvas drawing

In attempting to draw an image on a canvas using a pre-loaded image and CSS, such as: img.style.backgroundColor="red"; ctx.drawImage(img,0,0,100,100); I have observed that the image is drawn without incorporating the CSS modifications. Are HTML canvases ...

Every time I use Get for ajax calls, I keep getting hit with a frustrating

Initially, I was making a call to a [web method] using the POST method. However, since I need to receive data back, I attempted to switch to using the GET method instead. The previous implementation using POST was successful. Unfortunately, using GET resu ...

What is the best way to focus on the N elements contained within another element?

Here is an example html input: <div class="grid--item user-info user-hover"> <div class="user-gravatar48"> <a href="/users/22656/jon-skeet"> <div class="gravatar-wrapper-48"> ...

Ensure each checkbox within a list is selected

My dilemma involves an assortment of checkboxes enclosed within LIs and SPANs in an unordered list. To simplify the checking process, I attempted using jQuery to automatically check all boxes when a button positioned above the UL is clicked. However, my ...

What's the best way to transform a JSON object into a practical tool?

This is a snippet from my JSON file: "shipping":{ "countries":{ "150":{ "id":150, "code":"nl", "title":"Nederland" } }, "country":150, "zipcode":null, "methods":{ ... ...

What caused the mat-date calendar style to malfunction?

I integrated mat-date into my Angular project, but encountered an issue where the styles of the calendar were not displaying properly when clicking the icon. Here is the displayed calendar effect I attempted to troubleshoot by commenting out the styles o ...