Developing a dual-sided radio wave animation

I am searching for a Radar wave animation similar to this one:

https://i.sstatic.net/FdO9N.jpg

After putting in significant effort with my limited knowledge of Svgs, I was able to create the left side of the desired wave successfully. However, I need some assistance adding the right side with an appropriate solution.

Note: If you have any source code or a more straightforward solution to achieve such an animation than mine, please feel free to reach out and let me know.

Note 2: I require a function to trigger the animation.

Thank you in advance.

function Wave() {
  const waves = document.querySelectorAll(".radio-wave");
  waves.forEach(wave => wave.classList.add('add-wave'));
  
  const wave1 = document.querySelector(".radio-wave-1");
  wave1.classList.add('add-radio-wave-1');
  
  const wave2 = document.querySelector(".radio-wave-2");
  wave2.classList.add('add-radio-wave-2');
  
  const wave3 = document.querySelector(".radio-wave-3");
  wave3.classList.add('add-radio-wave-3');
  
  const wave4 = document.querySelector(".radio-wave-4");
  wave4.classList.add('add-radio-wave-4');
  
  const wave5 = document.querySelector(".radio-wave-5");
  wave5.classList.add('add-radio-wave-5');
  
  const wave6 = document.querySelector(".radio-wave-6");
  wave6.classList.add('add-radio-wave-6'); 
}

setTimeout(() => Wave(), 2000);
body {
  background: black;
}

.left-wave-container {
  position: relative;
  margin-right: 50%;
  padding: 0;
  font-size: 16px;
}

.radio-wave-container {
  display: flex;
  flex-flow: column nowrap;
  justify-content: center;
  align-items: center;
  margin: 5rem;
}

.radio-wave-container.content {
  flex-flow: row nowrap;
  width: 100%;
}

.radio-source {
  position: absolute;
  right: 2rem;
  width: 2rem;
  fill: #fcba03;
}

... (CSS continues) ...

@keyframes wave-6 {
  0% {opacity: 0.2;}
  10% {opacity: 0.3;}
  20% {opacity: 0.4;}
  30% {opacity: 0.5;}
  40% {opacity: 0.6;}
  50% {opacity: 0.7;}
  60% {opacity: 0.8;}
  70% {opacity: 0.9;}
  80% {}
  90% {}
  100% {}
}
<div class="left-wave-container" xmlns:xlink="http://www.w3.org/1999/xlink">
    <svg style="position:absolute;width:0;height:0;" width="0" height="0" version="1.1">
      <defs>
        <symbol id="radio-wave" viewBox="0 0 100 200">
    
          <g>
            <path d="M62.5,185 Q12.5,100 62.5,15" />
          </g>
        </symbol>
        <symbol id="radio-source" viewBox="0 0 100 100">
      
        </symbol>
      </defs>
    </svg>
    ... (SVG elements continue) ...
  </div>

Answer №1

To achieve a reflective animation, apply the following CSS:

transform: rotate(180deg);

This will create the mirroring effect on the right side when used on a wrapping div.

For instance:

<div class="radio-wave-container">
      <div class="radio-wave-container content">
        <div class="reflect">
            <svg class="radio-source">
            <use xlink:href="#radio-source"></use>
            </svg>
        </div>
...(etc)

Add this to your stylesheet:

.reflect {
     transform: rotate(180deg);
}

Answer №2

To access the elements wave1..wave6, you can use the querySelectorAll method:

const wave1 = document.querySelectorAll(".radio-wave-1");
...
const wave6 = document.querySelectorAll(".radio-wave-6");

This is because they are part of a collection.

Next, I used a for loop and specified an index of 2 to add a class for each wave1..wave6.

I also made some corrections to your HTML and CSS layout. If you want the waves to align with the image you shared, follow these steps:

Use flex to align them with each other. Add the following to your CSS:

.wave-container {
    display: flex;
    justify-content: center;
}

Remove the rule margin-right: 50% from the selectors .left-wave-container and .right-wave-container.

With these changes, it should be good to go!

function Wave() {
  const waves = document.querySelectorAll(".radio-wave");
  const wave1 = document.querySelectorAll(".radio-wave-1");
  const wave2 = document.querySelectorAll(".radio-wave-2");
  const wave3 = document.querySelectorAll(".radio-wave-3");
  const wave4 = document.querySelectorAll(".radio-wave-4");
  const wave5 = document.querySelectorAll(".radio-wave-5");
  const wave6 = document.querySelectorAll(".radio-wave-6");

  waves.forEach(function(wave) {
    wave.classList.add('add-wave');

    for (var i = 0; i < 2; i++) {    
      wave1[i].classList.add('add-radio-wave-1'); 
      wave2[i].classList.add('add-radio-wave-2');  
      wave3[i].classList.add('add-radio-wave-3'); 
      wave4[i].classList.add('add-radio-wave-4'); 
      wave5[i].classList.add('add-radio-wave-5'); 
      wave6[i].classList.add('add-radio-wave-6');  
    }  
  });
}

setTimeout(() => Wave(), 2000);
body {
  background: black;
}

.wave-container {
    display: flex;
    justify-content: center;
}

.left-wave-container {
  position: relative;
  /*margin-right: 50%;*/
  padding: 0;
  font-size: 16px;
}

.right-wave-container {
  position: relative;
  /*margin-right: 50%;*/
  padding: 0;
  font-size: 16px;
  transform: rotate(180deg); /* flip the animation*/
}

.radio-wave-container {
  display: flex;
  flex-flow: column nowrap;
  justify-content: center;
  align-items: center;
  margin: 5rem;
}

.radio-wave-container.content {
  flex-flow: row nowrap;
  width: 100%;
}

.radio-source {
  position: absolute;
  right: 2rem;
  width: 2rem;
  fill: #fcba03;
}

.add-wave {
  -webkit-animation-duration: 2.2s;
          animation-duration: 2.2s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear;
          animation-timing-function: linear;
}

/* Rest of the CSS rules omitted for brevity */
Your HTML structure looks like this but has dependencies on external SVG resources and JS files.

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

Finding a Particular Parent Component in Vue.js

Is there a more reliable way in VueJS to call the parent component of multiple parents without specifying the exact number of parents or children? In jQuery, you can use closest('element') to find the nearest element without having to count layer ...

Why is it necessary to create a new object in Node.js to establish a server?

After reviewing the information about socket.io, there is one aspect that I find confusing. I understand that to create a server, it can be done like this: var io = require ("socket.io")(); However, I am curious about why it necessitates creating a new ...

Separate jQuery code from the PHP-generated HTML output

Experimenting with PHP and probably not doing it correctly, but this is just a proof of concept to get approval for the right approach. I am using a php script for login and posting variables from forms. The issue: I am echoing out an HTML code that inclu ...

"Utilizing the Bootstrap framework to enhance the functionality

I have a bootstrap table containing data that needs to be edited, with certain fields not displayed in the table. To enable editing, I have added an edit button to each row along with a modal form. The button successfully loads the modal form without any ...

Combining Multiple 3D JSON Objects in JavaScript [or jQuery]

Looking to combine multiple JSON objects into one? I have a code snippet that you can use! Here is the code: http://jsfiddle.net/5Uz27/ The issue with this code is that it only merges objects on the first level, causing deeper levels to be overwritten. T ...

Conflicting banner element positioning due to scroll bar pages interference

Is there a way to prevent elements from moving when navigating to a page with a scroll bar? I've observed that my elements shift slightly when selecting a page with a scroll bar. See an example here. I am considering forcing a scroll bar to appear on ...

``Despite running $scope.$digest, the scope variable is failing to update in the view

.controller('PizzaCtrl', ['$scope','$state','$ionicLoading', function($scope, $state, $ionicLoading) { $scope.$emit('menu-refresh-request'); $scope.$on('menu-refresh-response', funct ...

Navbar in Bootstrap 4 Disappearing Upon Icon Selection

Whenever my page is small enough to display the collapsible navbar, you can simply click or tap the icon to open the navbar. However, if you try to click or tap it again, the navbar won't close and I'm uncertain as to why. <link rel="styl ...

React-file-viewer shrinks any document to a compact size

I have been searching extensively for information on how to adjust file sizing in react-file-viewer without any success. My objective is to utilize the react-file-viewer to allow users to click on a filename hyperlink and open the file (be it an image, do ...

Exploring the depths of CSS table-cell and the impact of percentage-based

During my exploration of Github, I came across a fascinating menu display: If you pay attention, each item in the menu is assigned an equal width. In CSS, we typically give it a percentage value - but why? It's interesting to note that the parent div ...

Discover the magic of observing prop changes in Vue Composition API / Vue 3!

Exploring the Vue Composition API RFC Reference site, it's easy to find various uses of the watch module, but there is a lack of examples on how to watch component props. This crucial information is not highlighted on the main page of Vue Composition ...

Managing functions within objects: A guide

I'm having an issue with handling a simple personalAccount object in JavaScript. I have defined some functions within the object keys, but when I try to display the output of my accountBalance function using console.log, it doesn't show the expec ...

When I add text to div boxes, they begin to drift downward

After creating four div boxes with content, I encountered an issue. Initially, when inserting filler text, everything seemed fine. However, as soon as I started adding actual content into the first box, the other three boxes shifted downwards by the same a ...

What methods can I use to prevent the `<style>` tags from being trapped in my CSS selectors?

As I work on styling existing documents with CSS, I find myself using a variety of adjacent sibling selectors (such as item1 + item2) to add spacing between elements. However, some of the documents contain <style> tags at different points in the page ...

Echo a JS variable into PHP and then insert a PHP file into an HTML element - a step-by-step guide!

Greetings to the wonderful community at stackoverflow, I am currently working on a variable code that allows for easy insertion of code from another file, such as a div. I am curious if it is possible to include a PHP file using JavaScript and JS variable ...

Problem with Safari: File downloaded with name "Unknown" due to Javascript issue

After successfully converting my data to text/csv, I can easily download the file in Chrome. However, when attempting to do so in Safari on an iPad or Mac, it opens a tab with the name "unknown" or "Untitled". The code snippet I am using for this is as fol ...

Remove markers from Google Maps when there are no markers present

I am working on a mobile web app that features a mapping page where users can toggle different POI's, such as Gas Stations. The issue I am facing is when the google.maps.places.PlacesService does not find any Gas Stations within my specified radius, I ...

What is the best place in Rails to add @media CSS tags?

Currently, my layout.html.erb contains some CSS rules with @media queries. <style> @media (max-width: 900px) { .green-button{ display: none!important; } .chat_button{ margin-top: 20px!important; } #myCarousel{ ...

Application becomes unresponsive following database write caused by an infinite loop

I have a user_dict object that is generated by fetching data from a Firebase database. Once the user_dict object is created, I store a copy of it within a profile child under the uid. Although the necessary information is successfully saved to the databas ...

Achieving the perfect alignment: Centering a paragraph containing an image using JQuery

I need help centering the background image of my <p> tag on the webpage. Script $(function() { $('ul.nav a').bind('click', function(event) { var $anchor = $(this); $('html, body').stop().animate({ ...