Animating a child element while still keeping it within its parent's bounds

I have researched extensively for a solution and it seems that using position: relative; should resolve my issue. However, this method does not seem to work in my specific case. I am utilizing JQuery and AnimeJS. My goal is to achieve the Google ripple effect on their buttons with AnimeJS.

Thank you in advance for your help, I may not be able to respond immediately.

function createRipple(event) {
  //Get cursor position
  var x = event.pageX,
    y = event.pageY;
  if ($(".ripple").length > 0) { //Check if there is already a ripple div
    //Remove previous ripple
    $(".ripple").remove();

    $("div.btn").append("<div class='ripple'></div>"); //Add a new div with the class ripple
    $(".ripple").css({
      "top": y - 20,
      "left": x - 20
    }); //Position the div at the cursor coordinates
    var ripple = anime({ //Ripple Animation
      targets: ".ripple",
      opacity: {
        value: [1, 0],
        duration: 2000
      },
      scale: {
        value: 10,
        duration: 3000
      },
    });
    $(".ripple").delay(2000).queue(function() {
      $(this).remove();
    }); //Remove the div after animation ends
  } else {
    $("div.btn").append("<div class='ripple'></div>"); //Add a new div with the class ripple
    $(".ripple").css({
      "top": y - 20,
      "left": x - 20
    }); //Position the div at the cursor coordinates
    var ripple = anime({ //Ripple Animation
      targets: ".ripple",
      opacity: {
        value: [1, 0],
        duration: 2000
      },
      scale: {
        value: 10,
        duration: 3000
      },
    });
    $(".ripple").delay(3000).queue(function() {
      $(this).remove();
    }); //Remove the div after animation ends
  }
}
html {
  background: #d6d7d8;
  height: 100%;
  width: 100%;
}

body {
  height: 100%;
  width: 100%;
  display: grid;
  grid-template-columns: 2fr 1fr 2fr;
  grid-template-rows: 2fr 1fr 2fr;
}

.btn {
  grid-column-start: 2;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 2;
  background: #ff5722;
  border-radius: 10px;
  box-shadow: 0 10px 20px 4px #aaaaaa;
  cursor: pointer;
  overflow: hidden;
  outline: none;
  border: none;
  position: relative;
}

.ripple {
  pointer-events: none;
  position: absolute;
  border-radius: 50%;
  height: 40px;
  width: 40px;
  background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<div class="btn" onclick="createRipple(event)"></div>

Answer №1

If my understanding of the issue is correct, simply setting x & y to event.pageX / pageY without considering the parent button's position will result in incorrect CSS placement. For example, if pageX = 200, you are actually setting left: 200px relative to the parent, which may only be 80px wide, causing the element to go outside the parent container.

To adjust for the parent, you can deduct the offsetLeft and offsetTop of the parent button from event.pageX and pageY respectively:

var x = event.pageX - $btn.offsetLeft,
    y = event.pageY - $btn.offsetTop;

I have done some code optimization on your original JavaScript. It is advisable not to repeat code unnecessarily, and it appeared that all the code in the else statement was redundant.

In order to troubleshoot similar issues in the future, you may find it helpful to debug piece by piece before adding animations. By removing the animation and examining the position of the .ripple element, I quickly identified that it was placed incorrectly.

function ripple(event) {
   var $btn = $("div.btn");
   var $ripple = $(".ripple");

    //Calculate cursor position
    var x = event.pageX - $btn.offsetLeft,
        y = event.pageY - $btn.offsetTop;

    //Check if there is an existing ripple div
    if ($ripple.length > 0) {
        //Remove previous ripple
        $ripple.remove();
    }

    //Create a new div with a ripple class
    $ripple = $('<div class="ripple"></div>');
    $btn.append($ripple);

    //Position the div at the cursor location
    $ripple.css({
        "top": y,
        "left": x
    });

    //Add Ripple Animation
    var ripple = anime({
      targets: ".ripple",
      opacity: {
        value: [1, 0],
        duration: 2000
      },
      scale: {
        value: 10,
        duration: 3000
      },
    });

  //Remove the div after the animation completes
  $ripple.delay(2000).queue(function() {
    $(this).remove();
  });
}
html {
   background: #d6d7d8;
   height: 100%;
   width: 100%;
}

body {
   height: 100%;
   width: 100%;
   display: grid;
   grid-template-columns: 2fr 1fr 2fr;
   grid-template-rows: 2fr 1fr 2fr;
}

.btn {
   grid-column-start: 2;
   grid-column-end: 2;
   grid-row-start: 2;
   grid-row-end: 2;
   background: #ff5722;
   border-radius: 10px;
   box-shadow: 0 10px 20px 4px #aaaaaa;
   cursor: pointer;
   overflow: hidden;
   outline: none;
   border: none;
   position: relative;
}

.ripple {
   pointer-events: none;
   position: absolute;
   border-radius: 50%;
   height: 40px;
   width: 40px;
   background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<div class="btn" onclick="ripple(event)"></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

PHP not displaying radio button values

My latest project involved creating a quiz program using only PHP. The program consists of 4 different questions and radio buttons, and when an option is selected, the value of the radio button (A, B, C, or D) should be printed. I have set up 4 PHP varia ...

jQuery: Retrieve data from a table

I am currently working on using an HTML table as a look-up table. Normally, I would handle this server-side, but in this particular case, the client will be inputting the table. When filling out a form, they provide two values from columns A and B, which t ...

the quickest method to apply font-weight:bold; to the text within the component

Is there a way to apply font-weight: bold; only to the inner content of a component in a scss file while avoiding affecting the component tag itself? :host { font-weight: bold; } Although this code works, it also affects the component tag itself. What ...

Regex: Identifying all URLs except for those with ".js" or ".css" included

I am currently working on a project where I need to change all the links in an HTML page so that they are not clickable. However, I am having trouble finding the right Regex pattern for the following condition: href="Any_URL" except for those that contain ...

Using Django and jQuery to trigger the change() function on a DateField()

In the Django admin site for a model, I am facing an issue with 2 date fields - 'from_date' and 'to_date'. My requirement is that whenever the 'from_date' value changes, I want to automatically add 10 more days to the 'to ...

What is the best approach for adding text to an image using TCPDF?

I am trying to create dynvouchers PDF using TCPDF. However, I am facing an issue where the PDF generated does not include the username and password. Here is my code: $html = ''; $html .= '<table><tr>'; for ($a = 1; $a <= ...

Implementing full-window mask when hovering over a div

I've been grappling with creating a mask that covers an image within a div, but I can't seem to get it to cover the entire area without leaving whitespace in the middle. I've tried various solutions to fix it, but nothing has worked so far. ...

`javascript pop up notification will only display one time`

I am currently developing a chrome extension with two different modes. When the user clicks on the icon, a pop-up message should appear to indicate which mode is active. However, I am facing an issue where the message does not always display when the pop- ...

Dividing Javascript code in bs4 using Python

I've encountered some challenges when attempting to extract Javascript values from a bs4 code. The javascript snippet appears like this: <script type="text/javascript"> var FancyboxI18nClose = 'Close'; var FancyboxI18nNext = 'Ne ...

Incorporating External HTML using jQuery and Asp.net MVC

Within my Index view, the following code is present: <script type="text/javascript" src="~/Scripts/jquery-2.0.0.js"></script> <script type="text/javascript" src="~/Scripts/Javascript1.js"></script> <div id="dictionary"> < ...

Adjusting Images and Icons' Sizes Automatically on a Single Line

Imagine a row of social media icons/images (like Facebook, Twitter, LinkedIn) displayed together. How can I ensure that when I add more icons/images to this row, their sizes adjust automatically to stay on the same line instead of moving to the next one? I ...

Error Encountered: Bootstrap Dropdown Menu Malfunction in Master Page

I'm struggling to make my Bootstrap drop down menu function properly. Nothing happens when I click on the link, no dropdown appears. I've set up my nav bar in a master page and have spent hours trying to troubleshoot it without success... This i ...

Perform a calculation using data from one schema and store the result in a different schema within MongoDB using Node.js

var ItemSchema = new Schema({ name: {type: String}, size : {type: String}, price : { type: Number} }); var SizeSchema = new Schema({ sizeName: {type: String}, dimensions : {type: String} }); F ...

Including a hyperlink button within a Kendo Grid cell that is editable

I have a grid featuring a column for editable phone numbers. I want to include a small icon that users can click on to trigger a "tel: link" which will prompt their phone hardware to act accordingly. For a demo, check out this link -> Objective: Clic ...

Storing information within a Express application using Postgres

Recently, I've been delving into the world of Express and experimenting with a program that allows users to create events and invite others. While I know about using join tables to retrieve data, I'm curious if there's a way to organize the ...

Integrate properties into a React component using an object as the representation

Can props be added to a component represented by an object? I am looking to add these props just once, within the map function, if possible. children: [ { id: '1', isActive: false, label: 'Home', component: & ...

An innovative approach to incorporating multiple patterns into HTML input using markup alone, without the need for JavaScript

Input fields are currently set to accept phone numbers in the format 555-555-5555 using the pattern [0-9]{3}-[0-9]{3}-[0-9]{4}. Is it possible to modify the pattern to also allow phone numbers in the format of 5555555555? <input type="tel" cl ...

The layout of a Vuex store in a sprawling website

Currently immersed in the development of a sprawling website using Vue.js, I find myself grappling with the architecture of Vuex store. The current folder structure is as follows: . ├── build ├── src │ └── components │ ├ ...

Tips for creating multiple popups using a single line of JavaScript code

I am new to JavaScript and I am attempting to create a popup. However, I am facing an issue in opening two divs with a single line of JavaScript code. Only one div opens while the other remains closed despite trying various solutions found on this website. ...

When $routeChangeStart is triggered, the location fails to locate the corresponding template

In my web application, I have an app variable associated with the module myApp. There are 3 pages: /login, /registration, and /. The behavior of $routeChangeStart is defined as follows: First, it checks if a global variable user is defined. If yes, it mo ...