Unveiling SVG elements with each section scrolled

I have utilized a function on this JSFiddle to retrieve the percentage of an element visible within the viewport while scrolling. The function ensures that the percentage is capped at 100 once the user scrolls beyond the element:

// Tracking the percentage of section seen within the viewport
// Assigning target section to a variable
const element = document.getElementById('section--example');

// Calculating the percentage of section in viewport
const percentageSeen = () => {
    
    // Obtaining necessary measurements and positions
    const viewportHeight = window.innerHeight;
    const scrollTop = window.scrollY;
    const elementOffsetTop = element.offsetTop;
    const elementHeight = element.offsetHeight;
    
    // Calculating the percentage of the element seen
    const distance = (scrollTop + viewportHeight) - elementOffsetTop;
    const percentage = Math.round(distance / ((viewportHeight + elementHeight) / 100));
    
    // Restricting range between 0 — 100
    return Math.min(100, Math.max(0, percentage));

}

Subsequently, I am trying to utilize the value of percentageSeen in the following function to animate an SVG path as the user scrolls:

// Retrieving a reference to the <path>
var path = document.querySelector('#path--example');

// Getting the length of the SVG path
var pathLength = path.getTotalLength();

// Creating dashes to match the length of the SVG path
path.style.strokeDasharray = pathLength + ' ' + pathLength;

// Initially offsetting dashes to hide the SVG entirely
path.style.strokeDashoffset = pathLength;

path.getBoundingClientRect();

// Animating the SVG on scroll
window.addEventListener('scroll', function(e) {
 
    // Fetching the percentage seen 
    var scrollPercentage = percentageSeen;

    // Calculating the length to offset the dashes
    var drawLength = pathLength * scrollPercentage;

    // Drawing in reverse
    path.style.strokeDashoffset = pathLength - drawLength;
  
});

I've documented my progress in a JSFiddle here. While I can successfully log the visible percentage to the console, it appears that the value is not being accepted when used in the scroll function above. Additionally, I can reveal the SVG based on page height (as commented out in the JSFiddle), but struggle with representing it based on section height. Can anyone offer guidance on how to effectively incorporate the percentageSeen variable into the scroll function?

Answer №1

  • The issue lies in the fact that the variable percentageSeen represents a percentage value. Multiplying pathLength by percentageSeen results in a value 100 times larger than intended.
  • Additionally, the function was being called without parentheses, causing scrollPercentage to store the function itself rather than its result.
  • If your aim is to make the element visible as the user scrolls, it's easier to set strokeDasharray to '0 pathLength' and then use
    drawLength (pathLength-drawLenght)
    .
  • You are limiting percentageSeen to 100, rendering the final cap redundant (also, you specified the cap at 0.99 instead of 99).

I've created a modified version with a working sample. In this example, percentageSeen never falls below 38 or exceeds 61. You may need to rectify the calculation.

// Animation — Stitch [Scroll]
// Reference: https://css-tricks.com/scroll-drawing/
// --------------------------------------------------

// Track percentage of animation container (section) in viewport
// Assign target section to var
const element = document.getElementById('section--example');

// Log percentage to console
const logPercentageSeen = () => {
    //console.log(percentageSeen());
}

// Re-run 'logPercentageSeen' on scroll
window.addEventListener('scroll', logPercentageSeen);

// Calculate percentage of section in viewport
const percentageSeen...
...
</svg>

  <p>It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters...</p>

</section>

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 detect if a user has reached the end of a container div while implementing Infinite Scroll

I am in the process of implementing infinite scroll on our website's dashboard, but I am currently facing a challenge in determining the bottom of the container div in my jsfiddle mockup. The original function works on a blank page with no container ...

The PHP file is returning a 403 Forbidden error for specific requests

My PHP script is returning a 403-Access Forbidden error for some HTTP requests, while others are working fine. I am receiving a 403 error for the following request (via AJAX) POST http://example.com/api/interaction/practitioner HTTP/1.1 Host: example.co ...

The issue of an invalid hook call was encountered while using the useState hook within a function component in TypeScript with React

As I worked on developing a custom react component library, I encountered an error while trying to implement a hover feature using the useState hook. The browser console of the app generated by create-react-app displayed the following message: I have been ...

Surrounding space in SVG

I am working on a project that involves using an svg icon generated by a plugin. However, I have noticed that the svg has some unwanted blank space around it that I need to modify. Can anyone help me understand the cause of this blank space and suggest how ...

Is it impossible to extend a Typescript class with an overriding method that uses a different parameter?

I am currently working on a Typescript MVC app and encountering an issue. When I try to extend my BaseController and override the ajaxMethod with different parameters, my transpiler throws an error. Any help would be appreciated. Below is the code snippet ...

What could be causing the error? And is there a way to successfully append the child div to the parent div?

Here is the error message that I am encountering: Uncaught TypeError: Cannot read property 'appendChild' of null at HTMLButtonElement.<anonymous> Error is located at app.js on line 7 const flexContainer = document.querySelector(&apo ...

Need assistance as require function is not functioning as anticipated

const THREE = require('three'); require('three/examples/js/loaders/OBJLoader.js'); Once I imported threejs from node_modules, I decided to utilize the provided OBJLoader, but encountered an unexpected error. THREE is not defined a ...

Fixing a scrolling element within a div located below the screen is my goal, ensuring it remains fixed in place as the user scrolls

I'm facing a challenge that I need help with: My HTML/CSS layout currently looks like this: Screenshot of how my CSS/HTML appears on the screen upon page load: As I scroll down, I encounter a green element: While scrolling down -> Upon further s ...

Having trouble with executing dual actions in React, causing state to behave incorrectly

Within a component, I am faced with the challenge of dispatching two distinct actions from two separate reducers that update different states within my application. Below is some excerpt of the code snippet for the said component: onSubmit = e => { ...

Which method proves to be quicker: storing data on a DOM element with a class attribute, or using jQuery data?

In my application, I have a render loop that constantly updates the appearance of several DOM elements based on data fetched from an external source. Each element needs to have presentational classes applied according to this data. For example: var anima ...

Is there a way to display one of the divs in sequence each time the page is reloaded?

Is there a way to display the divs sequentially when the page is refreshed? For instance, on the initial load, only div 1 should appear, and with each refresh it should cycle through divs 2, 3, 4, and 5 before starting over. Below is an example I'm c ...

How can I send a value from a for loop to a URL within a modal using Django?

Currently, I am working on a project that involves using a for loop with buttons and their corresponding pk values. {% for obj in all_objects %} <button data-toggle="modal" data-id="{{ obj.pk }}" data-target="#myModal" class="open-my-modal"> {{ ob ...

AngularJS: enhancing $http with custom functionality

I am facing an issue with my simple controller, which looks like this: function MyController($scope, $http) { ... $http.post(url).success(function(data) { console.log(data) }); } MyController.$inject = ['$scope', &ap ...

Closures are like the "use" keyword in PHP or the capture list in C++, but they play a similar role in JavaScript and other transpiler languages

PHP has a useful feature with the use keyword, which allows for the usage of 'external' variables in closures. For example: $tax = 10; $totalPrice = function ($quantity, $price) use ($tax){ //mandatory 'use' return ($price * $quan ...

Swap out one JSON array with another while ensuring the original order is maintained

My API returns JSON data in the following format: {'items':[ {'id': 1, 'quantity': 3}, {'id': 4, 'quantity': 7}, {'id': 5, 'quantity': 1} ]} I have configured my page to fetch this API ...

Troubleshooting problem with formatting and default value in MUI X DatePicker

I'm encountering a problem and struggling to find a solution. The default format for displaying dates in the MUI X DatePicker (with Material UI) is: Fri Oct dd yyyy HH:MM:SS GMT+HHMM (name of timezone here) However, I need to pass a date in the forma ...

What is the reason why the show() function in JQuery only applies to one specific element, rather than all elements selected with the same selector?

JSFiddle. This example code features a nested <table> within another <table>. The main issue concerns the click listener for the #add button. Specifically, the final if/else statement in the function. When you execute this code and click the ...

Updating dynamically generated HTML using jQuery seems to be causing some difficulties

I am facing an issue with my ajax function that loads inbox messages, each message containing a user_type and read field. As I loop through the messages, I generate HTML for each of them. function initializeMailbox() { // retrieve all mailbox data ...

In PHP, a boolean variable will not display on the webpage when echoed

I am facing an issue with my PHP code where certain variables are not being echoed properly in the generated JavaScript. The code is designed to check if specific values are assigned in the $_GET global array and assign default values if they are not prese ...

The carousel feature in Angular JS is malfunctioning

My angular carousel is not working properly and I am facing issues. You can view the carousel here. The controller in my Angular code does not seem to be calling out the images. To see the source code, you can click here. I have followed the coding demon ...