Animating an image inside a bordered div

I'm attempting to create an animated effect where an image moves randomly within the boundaries of a div container. While I've come across solutions for animating within borders, none have specifically addressed keeping the image inside the div.

For example, I have a snippet that showcases a red square moving inside a yellow div, even as the page is scrolled.

How can I accomplish this?

$(document).ready(function() {
    animateDiv();

});

function makeNewPosition($container) {

    // Getting viewport dimensions (excluding the div's dimensions)
    $container = ($container || $(window))
    var h = $container.height() - 50;
    var w = $container.width() - 50;

    var nh = Math.floor(Math.random() * h);
    var nw = Math.floor(Math.random() * w);

    return [nh, nw];

}

function animateDiv() {
    var $target = $('.a');
    var newq = makeNewPosition($target.parent());
    var oldq = $target.offset();
    var speed = calcSpeed([oldq.top, oldq.left], newq);

    $('.a').animate({
        top: newq[0],
        left: newq[1]
    }, speed, function() {
        animateDiv();
    });

};

function calcSpeed(prev, next) {

    var x = Math.abs(prev[1] - next[1]);
    var y = Math.abs(prev[0] - next[0]);

    var greatest = x > y ? x : y;

    var speedModifier = 0.1;

    var speed = Math.ceil(greatest / speedModifier);

    return speed;

}
div#container {height:100px;width:100px;margin-left: 500px;background-color: yellow;}

div.a {
width: 50px;
height:50px;
 background-color:red;
position:absolute;
    
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h1>TITLE!</h1>
<p>
Just some test which the red squere won't touch at any point
</p>
</div>
<div id="container">
<div class='a'></div>
</div>

Answer №1

It is crucial that when assigning position:absolute; to an element, you also define a parent element with position:relative;. This ensures that the child (absolute element) stays within its container's boundaries.

$(document).ready(function() {
    animateDiv();

});

function makeNewPosition($container) {

    // Get viewport dimensions (remove the dimension of the div)
    $container = ($container || $(window))
    var h = $container.height() - 50;
    var w = $container.width() - 50;

    var nh = Math.floor(Math.random() * h);
    var nw = Math.floor(Math.random() * w);

    return [nh, nw];

}

function animateDiv() {
    var $target = $('.a');
    var newq = makeNewPosition($target.parent());
    var oldq = $target.offset();
    var speed = calcSpeed([oldq.top, oldq.left], newq);

    $('.a').animate({
        top: newq[0],
        left: newq[1]
    }, speed, function() {
        animateDiv();
    });

};

function calcSpeed(prev, next) {

    var x = Math.abs(prev[1] - next[1]);
    var y = Math.abs(prev[0] - next[0]);

    var greatest = x > y ? x : y;

    var speedModifier = 0.1;

    var speed = Math.ceil(greatest / speedModifier);

    return speed;

}
div#container {
  height:100px;
  width:100px;
  margin-left: 500px;
  background-color: yellow; 
  position:relative;/*Added position to the parent container*/
}

div.a {
 width: 50px;
 height:50px;
 background-color:red;
 position:absolute;
    
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h1>TITLE!</h1>
<p>
Just some test which the red squere won't touch at any point
</p>
</div>
<div id="container">
<div class='a'></div>
</div>

Reference Link 1: https://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/

Live Demo: https://www.w3schools.com/css/tryit.asp?filename=trycss_position_absolute

Answer №2

$(document).ready(function() {
    animateDiv();

});

function makeNewPosition($container) {

    // Obtain viewport dimensions (subtracting the size of the div)
    $container = ($container || $(window))
    var h = $container.height() - 50;
    var w = $container.width() - 50;

    var nh = Math.floor(Math.random() * h);
    var nw = Math.floor(Math.random() * w);

    return [nh, nw];

}

function animateDiv() {
    var $target = $('.a');
    var newq = makeNewPosition($target.parent());
    var oldq = $target.offset();
    var speed = calcSpeed([oldq.top, oldq.left], newq);

    $('.a').animate({
        top: newq[0],
        left: newq[1]
    }, speed, function() {
        animateDiv();
    });

};

function calcSpeed(prev, next) {

    var x = Math.abs(prev[1] - next[1]);
    var y = Math.abs(prev[0] - next[0]);

    var greatest = x > y ? x : y;

    var speedModifier = 0.1;

    var speed = Math.ceil(greatest / speedModifier);

    return speed;

}
div#container {
position:relative;
  height:100px;width:100px;margin-left: 500px;background-color: yellow;}

div.a {
 width: 50px;
 height:50px;
 background-color:red;
 position:absolute;
    
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h1>TITLE!</h1>
<p>
Just some test which the red squere won't touch at any point
</p>
</div>
<div id="container">
<div class='a'></div>
</div>

Answer №3

Utilizing CSS animations to achieve a smoother visual effect is my current approach. All modifications are meticulously detailed in the Javascript/jQuery and CSS source code.

When it comes to speed, CSS animations outperform jQuery animate due to their ability to operate on a distinct thread.

$(document).ready(function() {
  /* Initiating animation */
  animateDiv();
    
  /* Adding animation class */
  $(".a").addClass("animate");
});

/* Triggering the end of transition */
$("div.a").on('transitionend', function() {
  /* Initiating next animation when previous one halts */
  animateDiv();
});

function makeNewPosition($container) {
  // Retrieve viewport dimensions (subtracting div's dimension)
  $container = ($container || $(window))
  var h = $container.height() - 50;
  var w = $container.width() - 50;
  var nh = Math.floor(Math.random() * h);
  var nw = Math.floor(Math.random() * w);
  return [nh, nw];
}

function animateDiv() {
  var $target = $('.a');
  var newq = makeNewPosition($target.parent());
  var oldq = $target.offset();
  
  /* Calculating duration in milliseconds */
  var speed = calcSpeed([oldq.top, oldq.left], newq) + "ms";
  
  /* Setting animation duration */
  $(".a.animate").css("transitionDuration", speed);

  /* Assigning new coordinates */
  $(".a").css({"top":newq[0], "left":newq[1]});
};

function calcSpeed(prev, next) {
  var x = Math.abs(prev[1] - next[1]);
  var y = Math.abs(prev[0] - next[0]);
  var greatest = x > y ? x : y;
  var speedModifier = 0.1;
  var speed = Math.ceil(greatest / speedModifier);
  return speed;
}
div#container {
  height: 100px;
  width: 100px;
  margin-left: 500px;
  background-color: yellow;
  position: relative; /* Added */
}

div.a {
  width: 50px;
  height: 50px;
  background-color: red;
  position: absolute;
  top: 0; /* Initial position */
  left: 0; /* Initial position */
}

div.a.animate {
  transition: left, top;
  transition-duration: 1000ms; /* Default value */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <h1>TITLE!</h1>
  <p>
    Just some test which the red squere won't touch at any point
  </p>
</div>
<div id="container">
  <div class='a'></div>
</div>

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

Simply click on the image to open it in a lightbox view with a thumbnail using jQuery

I have implemented a feature using fancybox to display images in a lightbox with thumbnail images. My requirement is that when a user clicks on an image, the clicked image should be displayed first in the lightbox and the rest of the images should not be s ...

Surprising pause in the menu transition animation

Currently, I am in the process of developing a menu that seems to have some flaws. One issue is that it appears a bit choppy, but the more concerning problem is the half-second delay after clicking an item before it animates. The concept behind this menu ...

The click functionality is not functioning properly within the .each() loop

For my event handler, I am trying to use click() but it doesn't seem to be working. Here is the code snippet: $('.ajax-close').click(function( event ){ event.preventDefault(); alert('hi'); $( ' ...

The functionality of bootstrap.styl malfunctions during the parsing process in stylus

I am attempting to incorporate stylus, a css preprocessor, with twitter bootstrap version 2.04. Upon downloading boostrap, I execute the command "stylus --css < bootstrap.css > bootstrap.styl" to generate a bootstrap.styl file. However, upon trying t ...

What is the best way to validate if fields are blank before sending a message using the button?

<template> <div> <div class="form-group"> <label for="name">First Name</label> <input type="text" class="form-control" v-model="firstName" placeholder="Ente ...

Can you explain the purpose of prevState within the setState method of a functional component?

When returning the updated previous state within a setState method retrieved from the useState hook, it appears that the state remains unchanged. To demonstrate this behavior, consider running the following code snippet: function App(){ const [state, ...

KnockoutJS is unable to assign a negative value to an input field

Is there a way to assign the value of an <input> as false? It seems to work fine with true. Data Model: function DataModel(){ self = this; self.Flag = ko.observable(false); }; HTML Code: <input type="text" data-bind="value:Flag"/> ...

To switch to desktop mode, double click; for mobile view, just tap once

I am looking to implement 2 different gestures for a specific feature in my application. Ideally, I want users to be able to double click on a card to open it in desktop view, but if they are using a phone, a single tap should suffice. How can I achieve th ...

Creating a responsive design for a cropped image using CSS

Hi there! I am using a cropped image as the background for the top of my webpage, with a fixed size defined in pixels for the containing div. The issue arises when I resize the browser window, causing the image to cover most of the page instead of just the ...

Error encountered with nested v-for in Vue.JS causing null and undefined values to be thrown

Question Conclusion: A Vue component I am working on has the following data setup: conversations: null, currentConversation: null, There is a method that runs on mounted() to retrieve the user's conversations: /** * Method to retrieve the user&ap ...

Utilizing the power of jQuery validation and Select2, we can seamlessly display or conceal success and error messages, all while maintaining a sleek design with Bootstrap

This is an original question Previous inquiries regarding this topic are outdated, dating back 4-5 years and pertaining to earlier versions of the projects in question. Status Update For my current project, I am utilizing: Bootstrap version 4.4.1 jQue ...

The re-assignment of `req.session.variable` in Express-session does not carry over between two different routes

I am currently working on a basic app that allows logged in users to search and book train journeys using Express, MongoDB, Mongoose, and Express-session. The selected journeys are temporarily stored in the req.session.order variable (which I believe is gl ...

A guide on updating data with duplicate values in Knex

Suppose I have the following array of data: const customerIds = [ '7d8206d2-74bc-4b90-a237-37f92486cde4', 'e594fe7f-d529-4a2f-ab24-ffc4e102268c', '7d8206d2-74bc-4b90-a237-37f92486cde4' ] As seen, there are duplicate IDs ...

What are the steps to integrate jQuery into an Angular 8 application?

I am currently working on an application that relies on SignalR for communication with a desktop application. In order to make use of SignalR, I include jQuery in my .ts file. However, after migrating from Angular 7 to Angular 8, it appears that this setup ...

Using Local Storage to store arrays in JavaScript/jQuery

Currently, I am implementing a set of multiple buttons each containing data-id and data-name Below is my concept along with some sample code for reference: $(".clickCompare").click(function ({ var id = $(this).attr('data-id'); var ...

Using TypeScript to validate the API response against specific types

I'm intrigued by the scenario where you expect a specific data type as a response from fetch / Axios / etc, but receive a different type instead. Is there a way to identify this discrepancy? interface HttpResponse<T> extends Response { parsed ...

Nuxt: Delaying Loading of Google Maps in VueJS Until Data is Fully Prepared

Hello, I am currently working on my very first VueJS project and I have successfully implemented the vue2-google-maps. However, I have encountered a problem while trying to connect the map markers to my site's JSON feed through the Wordpress REST API. ...

picture protrudes from the frame [WordPress template]

Check out my website: If you scroll to the bottom of the site, you'll see an image of a bride sitting on a couch. I recently added this code to the stylesheet: .novia img {min-width:1000px; float:none;} This code was meant to maintain a fixed heigh ...

The issue arises when trying to use the Jquery .addClass() function in Chrome, yet it functions perfectly in Mozilla Firefox

I am trying to apply a class to my input tag using the addClass method in jQuery, but it doesn't seem to be working in Chrome! ` $('#username-signup').blur(function() { var tempusername = $('#username-signup').v ...

Setting a value in Ionic 3 HTML template

Attempting to assign a value in an Ionic 3 template from the ts file while also adding css properties but encountered an issue. PROBLEM Error: Uncaught (in promise): Error: No value accessor for form control with name: 'image' Error: No va ...