Initiate the SVG animation upon entering the viewport

I'm struggling to initiate the animation when it enters the viewport. I've looked through previous questions on stack overflow, but I can't seem to customize the JS for my specific requirements. My latest attempt was to start the pink line's animation as soon as it becomes visible in the viewport... I believe once that is solved, I can apply it to other elements as well. If you need more information, please let me know. Any suggestions? codepen

SVG

<svg version="1.1" id="animate" class="animatedSVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     width="792px" height="815px" viewBox="0 0 792 815" xml:space="preserve">

  <path id="purple" class="purple-stroke purpleAnimation" d="M597.645,416.25c0,121.334-98.361,219.695-219.695,219.695"/>

  <path id="green" class="green-stroke" d="M173.096,197.039c-58.343,54.482-94.817,132.087-94.817,218.211 c0,164.857,133.644,298.5,298.5,298.5"/>

  <path id="red" class="red-stroke" d="M636.449,415.25c0,143.318-116.182,259.5-259.5,259.5c-143.318,0-259.5-116.182-259.5-259.5"/>

  <path id="yellow" class="yellow-stroke" d="M585.398,201.588c55.557,54.209,90.051,129.907,90.051,213.662 c0,164.857-133.644,298.5-298.5,298.5"/>

  <path id="pink" class="pink-stroke pinkAnimation" d="M376.949,77.25c26.421,0,52.134,3.031,76.81,8.766c149.667,34.779,261.19,168.983,261.19,329.234"/>

</svg>

CSS

.pink-stroke {
  fill:none;
  stroke:#E199C3;
  stroke-width:40;
  stroke-linecap:round;
  stroke-dasharray: 1000;
  stroke-dashoffset:1000;
   -webkit-animation: dash 2s linear forwards;
  animation: dash 2s linear forwards; 
}

.pinkAnimation {
  fill:none;
  stroke:#E199C3;
  stroke-width:40;
  stroke-linecap:round;
  stroke-dasharray: 1000;
  stroke-dashoffset:1000;
-webkit-animation: dash 2s linear forwards;
      animation: dash 2s linear forwards;
}

.purple-stroke{
  fill:none;
  stroke:#9E70B0;
  stroke-width:40;
  stroke-linecap:round;
  stroke-miterlimit:10;
  stroke-dasharray: 1000;
  stroke-dashoffset:1000;
  -webkit-animation: dash 2s linear forwards;
  animation: dash 2s linear forwards;
  -webkit-animation-delay:.85s;
  animation-delay:.85s;
}

.green-stroke{
  fill:none;
  stroke:#21B585;
  stroke-width:40;
  stroke-linecap:round;
  stroke-miterlimit:10;
  stroke-dasharray: 1000;
  stroke-dashoffset: -1000;
  -webkit-animation: dash 2s linear forwards;
  animation: dash 2s linear forwards;
  -webkit-animation-delay:1.25s;
  animation-delay:1.25s;
}

.red-stroke{
  fill:none;stroke:#E9706C;
  stroke-width:40;
  stroke-linecap:round;
  stroke-miterlimit:10;
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  -webkit-animation: dash 2s linear forwards;
  animation: dash 2s linear forwards;
  -webkit-animation-delay:.85s;
  animation-delay:.85s;
}

.yellow-stroke {
  fill:none;
  stroke:#EFEF99;
  stroke-width:40;
  stroke-linecap:round;
  stroke-miterlimit:10;
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  -webkit-animation: dash 2s linear forwards;
  animation: dash 2s linear forwards;
  -webkit-animation-delay:.45s;
  animation-delay:.45s;
}


@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }

JS

var onAppear = [];

document.addEventListener("DOMContentLoaded", function() {
  onAppear = [].map.call(document.querySelectorAll("#animate"), function(item ) {
    return item;
  });
}, false);

window.addEventListener("scroll", function() {
  onAppear.forEach(function(elem) {
    var vwTop = window.pageYOffset;
    var vwBottom = (window.pageYOffset + window.innerHeight);
    var elemTop = elem.offsetTop;
    var elemHeight = elem.offsetHeight;

    if (vwBottom > elemTop && ((vwTop - elemHeight) < elemTop)) {
     elem.classList.add(".pinkAnimation");
      elem.classList.remove(".pink-stroke")

    } else {
      elem.classList.remove("pinkAnimation");
      elem.classList.add ('.pink-stroke')
    }
  });
}, false);

Answer №1

After some experimentation, I managed to work out a solution for this issue. While there may be more efficient options available, the following script did the job for me. I also made adjustments to the CSS styles accordingly. You can view the updated version on CodePen.

JavaScript:

$(window).scroll(function() {
  var wScroll = $(this).scrollTop();

  if (wScroll > $('#animate').offset().top - ($(window).height() / 1.2)) {
    $("#pink").attr("class", "pink-stroke dash-pink");
    $("#yellow").attr("class", "yellow-stroke dash-yellow");
    $("#red").attr("class", "red-stroke dash-red");
    $("#purple").attr("class", "purple-stroke dash-purple");
    $("#green").attr("class", "green-stroke dash-green");

  } else {
    $("#pink").attr("class", "pink-stroke");
    $("#yellow").attr("class", "yellow-stroke");
    $("#red").attr("class", "red-stroke");
    $("#purple").attr("class", "purple-stroke");
    $("#green").attr("class", "green-stroke");
  }
});

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

What is the best way to simulate an unexported function in Javascript jest environments?

Testing a module in my vuejs project is what I'm currently focusing on. import { getBaseUrl } from "@/application/api/baseUrl"; export default ( uri: string, requestBody: Record<string, string | number> ): void => { let form ...

Unable to change the name of the file using ngx-awesome-uploader

Currently, I am utilizing https://www.npmjs.com/package/@sleiss/ngx-awesome-uploader and facing an issue regarding renaming files before uploading them. Upon reviewing the available methods, it appears that there is no option for file renaming. While I c ...

Unable to trigger click events for marker connected to the end of the line

I need help with the following code. It includes a line with a marker attached to the end. I have written click events for both the line and the marker. However, the click event does not work when I click on the marker element, and the cursor properties ar ...

Webpack is ejected from watch mode

Currently, I am in the process of learning React and have decided to use webpack alongside it. However, I seem to be facing an issue with webpack when it comes to the watch mode. It builds the files once but then halts. The console output reflects the foll ...

Enlarge the div with a click

I was looking for a solution on how to make a div expand when clicked using jQuery I came across a tutorial that seemed simple and perfect, but I couldn't get it to work when I tried to replicate the code. Do you know if this code is still valid wit ...

Determine the mean value from an array of JSON objects in an asynchronous manner

Can you help me calculate the average pressure for each device ID in this JSON data set? [ { "deviceId": 121, "Pressure": 120 }, { "deviceId": 121, "Pressure": 80 }, { "deviceId": 130, "P ...

Ensure that the div expands to accommodate the content

I'm experiencing an issue where the content within a div with a blue border exceeds the boundaries of the div when it expands. How can I make sure that the div extends to contain all the content? Here is a demonstration of the problem: When I expand ...

Why is the size of my array shrinking with every iteration of the for-loop in JavaScript?

I am struggling to change the classname of three elements that share the same classname. Unfortunately, as I loop through my array, it seems to decrease in size with each iteration, preventing me from successfully changing all three elements. Any advice or ...

Tips for utilizing OpenLayers.Control.SelectFeature with a KML layer positioned below the Layer.Markers

I stumbled upon an intriguing issue and decided to share my solution in hopes of receiving better suggestions from others. Context: This involves an OpenLayers map with 3 layers: Google (base layer), a KML layer displaying polygons, and a Layer.Markers l ...

How to refresh a page in React when the browser's back button is pressed

In my React project using Material-UI, I have created a simple search form. On page A, users can input values in text boxes and select options from drop-down lists and checkboxes. The results are then displayed on page B. My issue arises when returning to ...

Searching for a different method in JavaScript that can add items without duplication, as the prependTo function tends to insert multiple items

Every time my code runs successfully, a success message is generated and displayed using prependTo within the HTML. However, the issue arises when the user performs the successful action twice, resulting in two success messages being shown on the screen. ...

Prior to stacking the divs, separate the line within the div

In the process of creating a responsive navbar with Bootstrap, I encountered an issue. When resizing the window to a smaller size, the collapse icon shifts from the top right position below my "logo". Here is how the site appears on a regular screen: http ...

Avoiding additional empty lines between selectors when setting up Stylelint

Can anyone help me with configuring Stylelint options? Specifically, I want to enforce a rule that no empty lines are allowed between selectors in a list of selectors: &:focus, &:hover, &.active { color: #fb3a5e; text-align: left; text-de ...

Develop a custom jQuery function

Seeking guidance on creating a customizable jQuery function that accepts parameters by name for easier handling. Rather than passing variables in a specific order like this: myFunction("My function name",true,false); I prefer to set parameters using an ...

Access the video content on Instagram by utilizing the oembed endpoints

THE SCENARIO For the past 9 months, I've had a piece of jQuery ajax code that has been functioning without any issues. However, in the last couple of weeks, it seems to have encountered some problems. This particular code utilizes Instagram's e ...

Managing location markers with Google Maps API V3: Saving and removing locations

I encountered an issue while using GMAP V3. After realizing the need to save map changes in a database, I struggled to find a way to accomplish this task. Before attempting any workarounds, I thought it would be best to gather some ideas first. The communi ...

What is the best approach for managing routing in express when working with a static website?

Whenever a user navigates to mydomain.com/game, I aim for them to view the content displayed in my public folder. This setup functions perfectly when implementing this code snippet: app.use('/game', express.static('public')) Neverthel ...

The sidebar stays fixed in place and doesn't adapt to varying screen resolutions

Check out my website at . I have a fixed, blue sidebar on the left side of the page to ensure its content is always visible. However, I'm facing an issue with smaller resolutions like 1024x768 where some bottom content is cut off. How can I adjust the ...

"Problems arise with mongodb full $text search when sorting and filtering, causing duplicate items to

When using full-text search in my API and sorting by score, I am encountering an issue where the same item is returned multiple times. This behavior is not what I expected. How can I correct this to ensure unique results? Below is the structure of my rout ...

Moving information from two modules to the service (Angular 2)

Recently in my Angular2 project, I created two components (users.component and tasks.component) that need to pass data to a service for processing before sending it to the parent component. Code snippet from users.component.ts: Import { Component } fro ...