Animate on scroll using react.js - javascript

I am using some css animations from animate.css and I'm using react.js which works fine at the top of my page however, I also have some animations near the middle of the page. When my page loads everything animates at once which means once I scroll down the animations in the middle of the page have already completed. I am looking for away to delay the animations until that area of the screen is visible. I have found some questions/answers on here but they date back quite a few years and appear to be outdated.
As seen in the code below the animate__animated animate__bounce animate__zoomInDown classes are derived from animate.css but play immediately when the page is loaded and not when visible onscreen:
import React from "react";
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faHourglassStart} from '#fortawesome/free-solid-svg-icons'
function MiddleContainer() {
return (
<div>
<div id = "middle-container" class="middle-container">
<h1>What can I offer you?</h1>
<div className = "fast animate__animated animate__bounce animate__zoomInDown">
<FontAwesomeIcon className="social-icon" icon={faHourglassStart} size = '4x' color = "black"/>
<h4>Fast and Reliable Service</h4>
<p>Your product will be delivered to you with precision, care and in a timely manner.</p>
<p>Add more info here when you are done with the css. </p>
</div>
</div>
</div>
)
}
export default MiddleContainer;

So I was able to solve this myself using a different library as I couldn't find any documentation from animate.css on how to animate on scroll
The new library with documentation that worked is AOS from https://michalsnik.github.io/aos/
I had to use useEffect from react.js in order for it to work.
Here is my code with animate on scroll working:
import React, { useEffect } from "react";
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faHourglassStart} from '#fortawesome/free-solid-svg-icons'
import AOS from "aos";
import "aos/dist/aos.css";
function MiddleContainer() {
useEffect(() => {
AOS.init({
// duration : 5000
});
}, []);
return (
<div>
<div id = "middle-container" class="middle-container">
<h1>What can I offer you?</h1>
<div className = "fast" data-aos="zoom-in">
<FontAwesomeIcon className="social-icon" icon={faHourglassStart} size = '4x'
color = "black"/>
<h4>Fast and Reliable Service</h4>
<p>Your product will be delivered to you with precision, care and in a
timely manner.</p>
<p>Add more info here when you are done with the css. </p>
</div>
</div>
</div>
)
}
export default MiddleContainer;

Related

Check for Windowsize React component

What I am basically trying to create is a navbar that has two completely different html hierarchy based on the window size. I want it to be different for mobile than for a desktop version. eg a nav bar that is on the right on desktop and one that is on the top for mobile.
A simply state of what was doing. I created a const that would use a state of the screen size. I had used the useState() to get a default for now but I know that if I was first loading on desktop and it it was defaulted to mobile. I would have to resize first to get the desktop version instead.
const [sizeState, setSizeState] = useState("mobile");
const changeNavbar = () => {
if (window.innerWidth <= 900) {
setSizeState("mobile");
} else {
setSizeState("desktop");
}
};
window.addEventListener('resize', changeNavbar);
the sizeState would then call an if function determin what state it curently is set to.
if (sizeState === "mobile") {
return ( //some code for mobile) }
else {
// return some code for desktop
}
for now it always returns the mobile version even if loading upon a innderwidth that is above 900 abd only on resize it would do something.
I have been trying to use a onload stuff and an eventlistener that would listen to load. but i cant manage to call the changeNavbar function on the first load of the page.
I saw people recomending usein useMediaQuerry but i dont know how to get it to work based on my if (mediaquery is set to md) { return( mobile navbar) }
if someone could help me use the useMediaQuerry in this instead of my previous attempt, so that i can have two seperated returns i would also be soooooo thankful for the help!
You can simply implement it using styled-components and styled-breakpoints packages and its hooks API.
Here is an example: https://codesandbox.io/s/styled-breakpoints-n8csvf
import { down } from "styled-breakpoints";
import { useBreakpoint } from "styled-breakpoints/react-styled";
export default function App() {
const isMobile = useBreakpoint(down("sm"));
return (
<div className="App">
{isMobile ? "Mobile View" : "Desktop View"}
</div>
);
}
Or you can create custom hooks like this: https://github.com/jasonjin220/use-window-size-v2
import useWindowSize from "use-window-size-v2";
export default function App() {
const { width, height } = useWindowSize();
return (
<div className="box">
<h1>useWindowSize Hook</h1>
<p>
height: {height}
<br />
width: {width}
</p>
</div>
);
}

Modal visible in HTML but on visible on app

Struggling to get my modal rendering when I click a button to show it. Here is the flow of this functionality
We start off by triggering toggle when the start coding button is clicked:
Start Coding
</button>
<StartModal
isShowing={isShowing}
hide={toggle}
/>
toggle is passed down from useModal()
const { isShowing, toggle } = useModal();
userModal changes the state of isShowing to true/false
import { useState } from 'react';
const useModal = () => {
const[isShowing, setIsShowing] = useState(false);
function toggle() {
console.log('toggle is being triggered')
setIsShowing(!isShowing);
}
return {
isShowing,
toggle,
};
};
export default useModal;
At this point toggle is being triggered is console logged
StartModal then should become visible:
import React from "react";
import "../../assets/scss/modal.scss"
import ReactDOM from 'react-dom';
const StartModal = ({ isShowing, hide }) => isShowing ? ReactDOM.createPortal(
<>
<div className="md-modal md-effect-12">
<div className="md-content">
<h3>Ready to start programming?</h3>
<div>
<p>The session will be split into 5 phases:</p>
<ul>
<li>Introductions</li>
<li>Pseudo-Code</li>
<li>Time to Code</li>
<li>Solution</li>
<li>Rating</li>
</ul>
<button
className="md-close"
onClick={hide}
>Close</button>
</div>
</div>
</div>
<div className="md-overlay"></div>
</>, document.body
) : null;
export default StartModal;
When I click the start coding button, my modal appears in my HTML. When I check the Elements tab on my browser, I see the modal showing up but cannot see it on my screen. I don't think it is a css problem because I have a z-index: 2000 property on the parent div. It seems as though the div appears outside of my react components?
I think the best approach is to use it with a new div.
For example:
<body>
<div id="root"></div>
<div id="modal"></div>
</body>
so you can look it here: https://codesandbox.io/s/affectionate-banzai-xypu3i

Using Parallax.js in React

I'm quite new to React, and I'm trying to use Parallax.js library in react. Now I have done the basics and installed the library using npm, I have imported the library and I have followed this topic that related to my question.
But now I'm having difficulty to make parallax work, I recieve the following error:
index.js:1 Warning: React does not recognize the `dataDepth` prop on a DOM element. If you intentionally
want it to appear in the DOM as a custom attribute, spell it as lowercase `datadepth` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
in li (at home.js:17)
in ul (at home.js:16)
in section (at home.js:15)
in ParallaxComponent (at App.js:7)
in App (at src/index.js:9)
in StrictMode (at src/index.js:8)
And this is my code
import React, { Component } from 'react'
import './css/style.css';
import headerbg from './images/header-bg.svg';
import Parallax from 'parallax-js' // Now published on NPM
class ParallaxComponent extends Component {
componentDidMount() {
this.parallax = new Parallax(this.scene)
}
componentWillUnmount() {
this.parallax.disable()
}
render() {
return (
<section className="header">
<ul ref={el => this.scene = el}>
<li className="layer" dataDepth="1.00">
<img src={headerbg} alt="Header background"/>
</li>
</ul>
<div className="content">
<h1>אנחנו דואגים להכל</h1>
<h2>אתם רק צריכים לאשר</h2>
<p>
אצלנו ב Triple V אין פשרות, איכות היא המטרה העליונה! <br/>
כל האתרים שלנו נבנים תחת פלטפורמת וורדפרס עם ציוני <br/>
מהירות שלא יורדים מ80 למובייל! <br/>
למה זה חשוב אתם שואלים? גוגל אוהב מהירות
<br/>
ככל שהאתר שלכם יותר מהיר ככה גוגל יותר מרוצה.
</p>
</div>
</section>
)
}
}
export default ParallaxComponent;
How can I run Parallax.js inside React library properly?
Try using data-depth attribute instead of DataDepth on your layers.

React Media Query needs refresh to show image

I am using react-media (https://github.com/ReactTraining/react-media) to handle different screen sizes. The aim of using react-media: Just bigger screens should see the parallax image (using materializeCSS for parallax). Problem:
If you resize the window, the image will disappear (how it should be) and when you go back to the bigger screen the place of the image is white. After refreshing the page the image is there again. I noticed it occurs every time when I use media and a javascript materializeCSS "package". How can I fix that?
import React, { useLayoutEffect } from "react";
import picture from "../../image/Introduction.jpeg";
import Media from "react-media";
const Paralaxes = () => {
useLayoutEffect(() => {
const M = window.M;
const elems = document.querySelectorAll(".parallax");
M.Parallax.init(elems, {});
});
return (
<Media query={{ minWidth: 768 }}>
{matches =>
matches ? (
<div className="parallax-container">
<div className="parallax">
<img src={picture} className="responsive-img" alt="background" />
</div>
</div>
) : (
<div className="container">
<div className="divider black" />
</div>
)
}
</Media>
);
};
export default Paralaxes;
Thanks a lot!

Rendering Component in Carousel using React

I want to achieve a carousel like Materialize.
Have an API from where I am fetching the data, so according to Materialize
I compared the console or Materialize default and my rendered components.
I guess the problem is, it's not inheriting the properties of carousel-item
Class carousel-item is supposed to Render inside of Class carousel.
<div className="carousel">
// These are supposed to be dynamic, below component is not present here
<div className="carousel-item">
</div>
</div>
How I am trying to render the data is in this manner.
renderAlbums(){
return this.state.albums.map(album =>
<Card song={album.name} singer={album.artist_name} src={album.cover_photo_url}/>
);
}
Rendered the data <Card />(It contains the class of carousel-item), which is supposed to place Card containing class of carousel-item.
class Carousel extends Component {
state = { albums: [] };
componentWillMount() {
axios.get('https://cors-anywhere.herokuapp.com/https://stg-resque.hakuapp.com/albums.json')
.then(response => this.setState({albums: response.data}));
}
renderAlbums(){
return this.state.albums.map(album =>
<div className="carousel-item"><Card key={album.name} song={album.name} singer={album.artist_name} src={album.cover_photo_url}/></div>
);
}
render() {
return (
<div className="carousel center">
{this.renderAlbums()}
</div>
);
}
}
export default Carousel;
This is my Card component
class Card extends Component {
render() {
return (
<div className="card z-depth-4">
<div>
<img src={this.props.src} />
</div>
<p>{this.props.song}</p>
<div className="singer">{this.props.singer}</div>
</div>
);
}
}
export default Card;
EDIT:
Want that content to display like this.
But it's not working the way it's expected.
Please suggest me, what am I doing wrong?
In axios.get, I see that you are using proxy link.
One reason is, it can be creating problems.
Other reason can be you are trying to put carousel-item into carousel.
Try adding center class to both i.e. carousel as well as carousel-item.
Check if these works.
First of all, there is nothing in your Carousel that says which element is active. You need to have a state variable that points to the active element.
Then you only need to draw [-2, -1, 0, 1, 2] offsets vs the active one. And each rendered card needs to know which offset to know their style.

Categories