I created different animation thought Bodymovin. I would like to fire the animation once the scroll reach the animation.
I am trying to figure out the way, but unfortunately I am not able to do it.
I am working with Gatsby JS (React framework). I paste my code down here of the .js file:
import React, { Component } from 'react'
import Lottie from 'react-lottie'
import animationData from './paginaweb.json'
class UncontrolledLottie extends Component {
render(){
const defaultOptions = {
loop: false,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice'
}
};
return(
<div>
<Lottie options={defaultOptions}
width={200}
/>
</div>
)
}
}
export default UncontrolledLottie
I tried libraries as https://www.npmjs.com/package/react-animate-on-scroll but didn't work to me. The animation shows up but it's already fired.
Someone out there that can help me out with this? I will really appreciate.
Thank you
I done similar things with react-waypont. You can place a waypoint somewhere in the page. If your scroll reach it, then you can trigger something. Make sure you just render the animation when this event triggered, so it just starts when you reach there. Something like this.
import {Waypoint} from 'react-waypoint';
import React, {useState} from 'react';
const Component = () => {
let [renderLottie, set] = useState(false);
return (
...
components to push waypoint out of the first page, so you can scroll to it
...
<Waypoint
onEnter={set(true)}
/>
{renderLottie && UncontrolledLottie}
)
}
Related
Hi im trying to get a loading page to show while website is taking the time to load. as it quite a large website I thought a loading screen would provide the best possible user experience however I cannot seem to figure out how to get it to work on nextjs 13. I have created a simple functional component that says loading... and have imported it directly into my layout.jsx folder.
I am using the app directory method which is quite new and im also new at nextjs so im a little lost ^^
I imagine I might need to set state at some point but I cant seem to figure out when and where to do it
any advice would be great.
thanks
import "./globals.css";
import React, { useState, useEffect } from "react";
import Loading from "../components/loading/loading";
const Layout = ({ children, dataLoaded }) => {
const [loading, setLoading] = useState(true);
useEffect(() => {
if (dataLoaded) {
setLoading(false);
}
}, [dataLoaded]);
return (
<body className="app {oswald.className}">
{loading && <Loading />}
{children}
</body>
);
};
export default Layout;
.
.
.
Attempt 1 -
After following one of the answers below it does not seem like my loading page is showing up at all. and no errors showing up.
my layout is as follows
layout.jsx
import "./globals.css";
import { Suspense } from "react";
import Loading from "../components/loading/loading";
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<Suspense fallback={<Loading />}>{children}</Suspense>
</body>
</html>
);
}
LoadingPage.js
const LoadingPage = () => {
return (
<div className="loading w-screen h-screen bg-red-100">
<p>Loading...</p>
</div>
);
};
export default LoadingPage;
Loading.js
import LoadingPage from "#/components/loading/loading";
export default function Loading() {
return <LoadingPage />;
}
In NextJS 13, there's actually a default way to handle loading states within pages. You can declare a loading.tsx file in your /app directory, with this content:
export default function Loading() {
return <Loading />
}
Then, inside your Layout, you can wrap your page with a Suspense tag, like this:
<Layout>
<Navbar>
...
<Suspense fallback={<Loading/>}>
<Page/>
</Suspense>
</Layout>
Your loading state will be automatically handled upon navigation.
I want each of my pages to have different loading animations when loading. How can i achieve this?
It is not possible to put the loading component on the page component like this:
//Page component
Page.Loader = SomeLoaderComponent
//_app.tsx
const Loader = Component.Loader || DefaultLoader;
This will not work because "Component(the page)" isnt loaded/rendered yet.
I have also tried dynamic import with next.js, so that i can import the correct page based on the url, and then get the correct loader. My initial plan was to add the Loader to the page component, as shown at the first line in the code above. That does not work because I have to give an explicit path.
const getLoader = (pagePath: string): ComponentType => {
const Loader = dynamic(() => import(pagePath));
return Page.Loader;
};
This is stated in the Next.js docs:
So the question is: How can I get a custom loader per page?
You can use Suspense and lazy to accomplish your task.
lets say you have ComponentA.js as follows
const ComponentA = () => {
return <div>Helloooo</div>
}
You can create another component WrapperA.js file
import React, { Suspense } from 'react';
const WrapperA = React.lazy(() => import('./ComponentA'));
function WrapperA() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<ComponentA />
</Suspense>
</div>
);
}
in the place of <div>Loading...</div> you can have any loader component you like. and export WrapperA to your routes or tab as needed.
I am currently working on the final project of a coding Bootcamp and there's just one thing that I can't seem to figure out(not sure if it is possible though).
I have a list of activities, where I map every activity into a card (which works fine). Now I would like to put these cards into the React Bootstrap Carousel and show 4 cards at a time. When I press one of the indicator it should slide to the next (or previous) card (not the next 4 cards). The only thing that I can get to work is having 1 card in the carousel.
Hoping that there is someone out there who is able to help me out.
Thank you from a nonDeveloper to a soon to become noobDeveloper.
Here's my code:
import React, { useState, useEffect } from "react";
import "./Cardslider.css";
import Explorecard from "./Explorecard/Explorecard";
import axios from "axios";
import Carousel from "react-bootstrap/Carousel";
function createCard(area) {
return (
<Carousel.Item>
<div>
<Explorecard image={`images/${area.area}.jpg`} title={area.area} />
</div>
</Carousel.Item>
);
}
const Cardslider = (props) => {
const [listOfActivities, setListOfActivities] = useState([]);
const getAllActivities = () => {
axios
.get("http://localhost:9999/activities")
.then((responseFromApi) => {
console.log(responseFromApi);
setListOfActivities(responseFromApi.data);
})
.catch((error) => console.error(error));
};
useEffect(getAllActivities, []);
return (
<div className="cards-container">
<Carousel className="explore-card-carousel" indicators={false}>
{listOfActivities.map(createCard)}
</Carousel>
</div>
);
};
export default Cardslider;
Before using the Carousel.Item tag, you must use the Carousel tag.
I'm learning Next.js and I'm trying to integrate the #react-aria/overlays package in my project. I have a layout component, where I'm simply invoking the usePreventScroll method like this:
usePreventScroll({
isDisabled: true
});
This layout component is used in my _app.js.
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import * as gtag from '../lib/gtag'
import 'styles/vendor.scss';
import 'styles/globals.scss';
import Layout from 'components/layout';
import { SSRProvider } from '#react-aria/ssr';
const App = ({ Component, pageProps }) => {
return (
<SSRProvider>
<Layout>
<Component {...pageProps} />
</Layout>
</SSRProvider>
)
}
export default App;
When going to my browser and loading a page, it gives me the following error:
Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
at Layout (/home/bas/projects/test-website/build/server/pages/_app.js:718:3)
at div
at $c5f9596976ab8bd94c5879001549a3e$var$OverlayContainerDOM (/home/bas/projects/test-website/node_modules/#react-aria/overlays/dist/main.js:864:7)
at ModalProvider (/home/bas/projects/test-website/node_modules/#react-aria/overlays/dist/main.js:810:5)
at OverlayProvider
at SSRProvider (/home/bas/projects/test-website/node_modules/#react-aria/ssr/dist/main.js:33:13)
at UIContextProvider (/home/bas/projects/test-website/build/server/pages/_app.js:1144:74)
at ManagedUIContext (/home/bas/projects/test-website/build/server/pages/_app.js:1105:3)
at App (/home/bas/projects/test-website/build/server/pages/_app.js:5171:3)
at AppContainer (/home/bas/projects/test-website/node_modules/next/dist/next-server/server/render.js:23:748)
What's the problem here and how would I be able to solve it?
I tried wrapping the the Layout component in the packages <SSRProvider>.
You can dynamically load the component and disable SSR:
import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(
() => import('../components/hello3'),
{ ssr: false }
)
function Home() {
return (
<div>
<Header />
<DynamicComponentWithNoSSR />
<p>HOME PAGE is here!</p>
</div>
)
}
export default Home
The code example has been taken from the NextJS docs. If that's not your thing, you can call the hook or render the component as long as processs.browser is true.
Next js is computes your 1st page on server. so it does not understand browser scroll or localstorage or other browser api.
you can add a check in your code block if window object is present or execution is running in server and then execute usePreventDefault.
import {useIsSSR} from '#react-aria/ssr';
function Layout() {
let isSSR = useIsSSR();
useEffect(() => {
!isSSR && usePreventScroll({ ... })
}, [isSSR])
}
Im trying to find a solution to what Ive been experiencing with image based galleries (in example lightbox or FancyBox). This error came up after following this doc and using this code as an
example.
I have tried using react-images to no avail, the modal doesn't display right, so I tried the links react-photo-gallery and I am encountering this error. Ive tried converting it to a component, and it didn't agree with the App function in the top portion of the file. I also tried creating a html file in my pages directory and added the import link to the illustrationGallery file, but that didn't seem to work.
My illustrationGallery file
import React, { useState, useCallback } from "react";
import { render } from "react-dom";
import Gallery from "react-photo-gallery";
import Carousel, { Modal, ModalGateway } from "react-images";
import { illustrations } from "../components/illustrations";
import Artwork from '../pages/gallery';
function App() {
const [currentImage, setCurrentImage] = useState(0);
const [viewerIsOpen, setViewerIsOpen] = useState(false);
const openLightbox = useCallback((event, { photo, index }) => {
setCurrentImage(index);
setViewerIsOpen(true);
}, []);
const closeLightbox = () => {
setCurrentImage(0);
setViewerIsOpen(false);
};
return (
<div>
<Gallery illustrations={illustrations} onClick={openLightbox} />
<ModalGateway>
{viewerIsOpen ? (
<Modal onClose={closeLightbox}>
<Carousel
currentIndex={currentImage}
views={illustrations.map(x => ({
...x,
srcset: x.srcSet,
caption: x.title
}))}
/>
</Modal>
) : null}
</ModalGateway>
</div>
);
}
render(<App />, document.getElementById("illuGallery"));
Local host window error
invariant
node_modules/react-dom/cjs/react-dom.development.js:56
render
node_modules/react-dom/cjs/react-dom.development.js:21195
▲ 2 stack frames were expanded.
Module.<anonymous>
src/components/illustrationGallery.js:43
40 | </div>
41 | );
42 | }
> 43 | render(<App />, document.getElementById("illuGallery"));
44 |
This error description is towards the top, but there are more
Just trying to achieve something that displays a proper image gallery using react, would it be easier to just make it using another doc or from scratch? Does anyone have any recommendations or answers to help?
This happens because:
document.getElementById("illuGallery") can not find an element with id #illuGaller.
if you are willing to make it work, and this is the only component you actually want react to render.
as from the example of the codesandbox project.
You go to your template, where react renders the ellement. basically index.html or template.html, in the example it's index.html
And make sure that the root element there which where react will inject your JSX, make sure it has the id illuGallery