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

Body of the table spanning the entire width of the screen

Looking for a solution to create a responsive table layout where the thead stretches up to a specified div, while the tbody expands to fill the entire screen width. Is this achievable without using fixed values? https://i.stack.imgur.com/v2ZYx.png It is ...

Trouble with the $.inArray function

Encountering an issue with storing objects into an array. However, when attempting to verify the existence of an object using $.inArray, it consistently returns -1. The code is written in AngularJS. <input name="{{question.number}}" ng-clic ...

Using AngularJS to Retrieve a Specific DOM Element Using its Unique Identifier

Example Please take a look at this Plunkr example. Requirement I am looking for a way to retrieve an element by its id. The provided code should be capable of applying a CSS class to any existing DOM element within the current view. This functionality ...

Is there a way to locate a parent class starting from a child class, and subsequently track down another child class from the parent?

I am facing a challenge with multiple tags structured like this: <div class="A"> <div class="B1">...</div> <div class="C1">Hello World!</div> <div class="C2">World Hell ...

Instructions for retrieving data from a weather API using JavaScript

Hello amazing Stackoverflow community! I need your help to figure out how to extract data from a weather REST API using JavaScript. I'm struggling to fetch the weather condition and date/time information from this API. { info: { _postman_i ...

Using JQuery to conceal floated divs

I'm facing an issue that I had resolved the last time I worked on this website. However, I am currently redesigning it to include additional elements, and I am struggling to make the jQuery part function correctly. Essentially, I have an HTML documen ...

Encountering problems when attempting to effectively filter a list of products using data

<div id="prod"> <div class="content" data-brand="Andrew" data-price="1000" data-store="JCPenny">Andrew</div><br /> <div class="content" data-brand="Hill" d ...

Avoiding the opening of a select menu

Is there a way to prevent the dropdown menu from appearing when a select element is clicked in a form? I have attempted two methods but they did not work: $('select').click (function (e) { console.log (e); return false; }); and $(&apo ...

Effortless AJAX/jQuery solution for displaying live file updates while copying

As I delve into the world of Ajax/jQuery, my current focus is on setting up a test environment for the following scenario: The server needs to recursively copy an entire folder from one location to another. The client should then display the list of copi ...

How can DataTables (JQuery) filter multiple columns using a text box with data stored in an array?

I've been attempting to create a multi-column filter similar to what's shown on this page () using an array containing all the data (referred to as 'my_array_data'). However, I'm facing issues with displaying those filter text boxe ...

Issue with Bootstrap 4 Navbar collapsing and not expanding again

Help needed! My navigation bar collapses when the window is resized, but clicking on the hamburger icon does not open it back up. I have included my code below. Can someone please provide guidance on how to expand the collapsed navbar? <html lang=&quo ...

What is the most effective method for updating a basic div element using AJAX?

I'm struggling with updating the element that shows the value in real-time from the database using AJAX. This application is designed to take a number, increase it by 1, save the new value, and then display the updated value live for the user. It&apo ...

Removing a function when changing screen size, specifically for responsive menus

$(document).ready(function () { // retrieve the width of the screen var screenWidth = 0; $(window).resize(function () { screenWidth = $(document).width(); // if the document's width is less than 768 pixels ...

Attempting to conceal an HTML 'label' element by employing CSS 'hide' properties

Why is it so difficult to hide a checkbox that says "Remember Me" on my membership site login form? The HTML code snippet causing the issue: <label><input name="rememberme" type="checkbox" id="rememberme" value="forever" /> Remember Me</la ...

Functionality of jQuery Mobile Page

$(document).on("pageshow", "#mappage", function (event) { $("#doldur").append("<li> <label onclick='getBina(" + featuressokak[f].attributes.SOKAKID + ");'>" ...

Displaying or concealing dropdown menus based on a selected option

My goal is to have a drop-down menu in which selecting an option triggers the display of another drop-down menu. For example, if I have options like "Vancouver," "Singapore," and "New York," selecting Vancouver will reveal a second set of options, while ch ...

The onclick handler fails to function following the injection of html using jquery AJAX

After using ajax to inject HTML into my page, the onclick handler on a specific part of that injected HTML does not seem to be functioning... Specifically, I am referring to this image... < img class="close_row" src="img/close.gif"/> In jQuery, I ...

Issue with Website Rendering: Safari 4 exhibits display glitch showing temporary content before showing a blank white screen

Currently, I'm in the process of developing a specialized rails application. However, there seems to be an unusual rendering error that has been reported by Safari 4 users. It's quite peculiar because the page appears briefly but quickly disappea ...

Customizing the appearance of input range in Firefox

I am having trouble styling the HTML input range element. I have successfully styled it for webkit browsers, but my styling does not seem to work on -moz- browsers. I attempted to use pseudo elements before and after on moz-range-thumb, but it seems that F ...

What steps can I take to streamline and simplify this tab controller code?

I'm looking to simplify this jQuery code because I feel like there's repetition. As someone new to JavaScript and jQuery, I've created two tabs with their respective containers containing miscellaneous information. My goal is to have each co ...