Skip to content

This is an example for a Product Landing Page for the QUADRAStalkr, an imaginary drone from an imaginary company. Includes use of video media, navigation elements, smart use of CSS animation to create an interactive design, and a form element that submits to a static page.

Notifications You must be signed in to change notification settings

trrapp12/QUADRA-STALKR

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

QUADRA-STALKR



Untitled_.Jun.2.2022.1_06.AM.mp4

Button60




HTML5

CSS3

JavaScript




Description:

"Drones ply the liminal space between the physical and the digital -- pilots fly them, but aren't in them. They are versatile and fascinating objects -- the things they can do range from the mundane (aerial photography) to the spectacular

-- John Batelle

This is an example for a Product Landing Page for the QUADRAStalkr, an imaginary drone from an imaginary company (that I have all the rights to ๐Ÿ˜ ๐Ÿ˜ ๐Ÿ˜ ). Includes use of video media, navigation elements, smart use of CSS animation to create an interactive design, and a form element that submits to a static page.


QUICKSTART GUIDE:

To use the app simply click on the View Project button or visit https://trrapp12.github.io/QUADRA-STALKR/.


Project demonstrates the following:

  • A ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅlittle animation to intro the page.

  • Javascript closures.

  • Creating a throttler for a scroll event.

  • User Story #1: My product landing page should have a header element with a corresponding id="header".

  • User Story #2: I can see an image within the header element with a corresponding id="header-img". A company logo would make a good image here.

  • User Story #3: Within the #header element I can see a nav element with a corresponding id="nav-bar".

  • User Story #4: I can see at least three clickable elements inside the nav element, each with the class nav-link.

  • User Story #5: When I click a .nav-link button in the nav element, I am taken to the corresponding section of the landing page.

  • User Story #6: I can watch an embedded product video with id="video".

  • User Story #7: My landing page has a form element with a corresponding id="form".

  • User Story #8: Within the form, there is an input field with id="email" where I can enter an email address.

  • User Story #9: The #email input field should have placeholder text to let the user know what the field is for.

  • User Story #10: The #email input field uses HTML5 validation to confirm that the entered text is an email address.

  • User Story #11: Within the form, there is a submit input with a corresponding id="submit".

  • User Story #12: When I click the #submit element, the email is submitted to a static page (use this mock URL: https://www.freecodecamp.com/email-submit).

  • User Story #13: The navbar should always be at the top of the viewport.

  • User Story #14: My product landing page should have at least one media query.

  • User Story #15: My product landing page should utilize CSS flexbox at least once.


CHALLENGES I OVERCAME...

So while I was using this I needed to create an eventlistener that would change the size and color of the text once the navbar got a certain distance down. This created a number of interesting issues.

  1. How do you prevent an expensive DOM traversal every time the smallest pixel is scrolled?
  • to fix this I had to come up with code that would throttle the the event calls to every 200ms and I had to use a closure so I could access the scope of a parent function to do it. See below:
(() => {
    // set constants
    const elementHeight = `${document.body.clientHeight}px`;
    const scrollableElement = window;
    const elementToChange = document.querySelectorAll('.nav-link-2')
    const elementColor = 'var(--prussian-blue)';
    const logo = document.getElementById('header-img');

    // check to see if object is window object
    function isElementWindow(element) {
        console.log(`isElementWindow() fired. Element is ${element}, logical comparison returns ${element === window}`)
        return element === window;
    }
    // define scroll event handler
    function scrollHandler(height, scrollableEl, element, color) {
        // when the top of the window is equal to height of the header, turn header background opaque
        for (const item in element) {
            if (isElementWindow(scrollableEl)) {
                // future improvement would take the window height/ window width to get an aspect ratio and then times that by the height to get a more dynamic response, instead of guesstimating 10% scroll down
                if (scrollableEl.scrollY >= (parseInt(height) - (parseInt(height) * .9))) {
                    element[item].style.backgroundColor = `${color}`;
                    element[item].style.letterSpacing = "2px";
                    element[item].style.borderRadius = "0px";
                    logo.style.display = "none"
                }
                // had to create a cumbersome else if instead of just a else statement because the logo would come back after CSS had removed it if you scrolled back up to the top
                else if (window.innerWidth >= 950 && scrollableEl.scrollY <= (parseInt(height) - (parseInt(height) * .9))) {
                    console.log('entering logo resize else if')
                    element[item].style.backgroundColor = 'transparent';
                    element[item].style.letterSpacing = "";
                    element[item].style.borderRadius = "8px";
                    logo.style.display = "block"
                }
            }
        }
    }

    // create throttle handler
    function throttleHandler(func, delay) {
        let lastCall = 0;
        return function(...args) {
            let currentTime = Date.now();
            if (lastCall - currentTime >= delay) {
                func(...args);
                lastCall = currentTime;
            } 
        }
    }

    // call scroll eventhandler in throttle handler
    window.addEventListener('scroll', () => {

        // tableData is only for use of console.table
        let tableData = [
            {
                name: "elementHeight",
                value: elementHeight
            },
            {
                name: "scrollableElement",
                value: scrollableElement
            },
            {
                name: "elementToChange",
                value: elementToChange
            },
            {
                name: "elementColor",
                value: elementColor
            }
        ];

        console.table(tableData)

        // attach handler to window.scroll event
        throttleHandler(scrollHandler(elementHeight, scrollableElement, elementToChange, elementColor))
    })
})();
    
  1. I decided I wanted to create an animation
(() => {
  window.addEventListener('load', () => {
    console.log('window loaded');
       
    const lineObject = document.getElementsByClassName('line');
    const secondLineObject = document.getElementsByClassName('straight');
    const displayWindow = document.getElementById('count');
    
    for (const [key, value] of Object.entries(lineObject)) {
      value.classList.add('spin-animation')
    }
    
    for (const [key, value] of Object.entries(secondLineObject)) {
      value.classList.add('spin-animation')
    }
    
    function counter() {
     count = 10;   

     setInterval(depricateTime, "1000")     
      
     function depricateTime() {  
       if (count >= 0) {
         displayTime(count); 
         count--;
       } else {
         clearInterval(depricateTime);
         closeWindow();
       }                       
       
       
     } 
     
      function displayTime(count) {
        displayWindow.innerHTML = count;
      }
      
      function closeWindow() {
        document.getElementById('counter-container').style.display = "none"
      }
    }
    
    counter();
        
  })
})()

MY OWN PERSONAL CONTRIBUTIONS INCLUDED

  • 100% of the work on this project was my own. The original requirements of the project, as listed in the user stories, were provided for direction as part of the Free Code Camp course.

FREE CODE CAMP RESPONSIVE WEB DESIGN CERTIFICATE:

freeCodeCampResponsiveWebDesign.png


ATTRIBUTIONS

Alien icons created by Freepik - Flaticon

Photos and other asset credits:

  • Callum Hilton
  • Dids
  • Dominika Roseclay
  • Mudassir Ali
  • Petar Avramoski

YOU CAN FIND ME AT:

For more information see my LinkedIn or return to my Github

About

This is an example for a Product Landing Page for the QUADRAStalkr, an imaginary drone from an imaginary company. Includes use of video media, navigation elements, smart use of CSS animation to create an interactive design, and a form element that submits to a static page.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published