0

So I am using Next 13 loading.tsx to showcase loading before the final page renders.

I am using framer motion to showcase one animation with icon moves from the bottom-left corner of the screen to the top-right corner of the screen, and I was hoping to showcase the rendered page after that, but what happens currently is that if the page bundles loaded early in the browser instead of showing the full animation it would just show page directly after half of the animation.

So let's say the animation length is 1s but the new page renders in 0.5 seconds then the animation won't fully complete.

I want to quickly show this animation as full before the page renders. How can I achieve that? Do I have to put wait somewhere in the component I didn't like that idea.

// loading.tsx

"use client";

import React from 'react';
import { motion } from 'framer-motion';
import KikiAndJiji from '../icons/KikiAndJiji';

export default function Loading() {
    const flyAnimation = {
        initial: { x: 0, y: '100vh' },
        animate: { x: '100vw', y: '-100vh' },
    };

    const flyTransition = {
        duration: 3,
        ease: 'linear',
        repeat: Infinity,
    };

    return (
        <motion.div
            className="h-screen w-screen"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
        >
            <motion.div
                className="flying-image h-full w-full"
                variants={flyAnimation}
                initial="initial"
                animate="animate"
                transition={flyTransition}
            >
                <KikiAndJiji width="200" height="200" color="white" />
            </motion.div>
        </motion.div>
    );
}
// page.tsx

"use client";
import { BsChevronCompactLeft, BsChevronCompactRight } from "react-icons/bs";
import QuestionsSlide from "./components/QuestionSlide";
import { store } from "./store";

import "./style.css";
import { useSnapshot } from "valtio";
import { QuestionType } from "../models/types";

export default function Page() {
    const snapshot = useSnapshot(store);

    const goLeft = () => {
        if (store.questionNumber > 0) {
            store.questionNumber--;
        }
    };

    const currentQuestionIsNotDecided = (question: { question: string; type: QuestionType; }) => {
        return question.question === "" || question.type === QuestionType.NOT_DECIDED;
    }

    const goRight = () => {
        if (currentQuestionIsNotDecided(store.questions[store.questionNumber])) {
            return;
        }

        if (store.questionNumber === store.questions.length - 1) {
            store.questions.push({ question: "", type: QuestionType.NOT_DECIDED });
        }
        store.questionNumber++;
    };

    const submitSurvey = async () => {
        if (currentQuestionIsNotDecided(store.questions[store.questionNumber])) {
            return;
        }

        store.questions = store.questions.filter(question => !currentQuestionIsNotDecided(question));

        const res = await fetch("create-survey/api", {
            method: "POST", body: JSON.stringify({
                surveyName: store.surveyName,
                questions: [...store.questions]
            })
        });
        const data = await res.json();
        console.log(data);
    };

    const editSurveyName = (event: React.ChangeEvent<HTMLInputElement>) => {
        store.surveyName = event.target.value;
    };

    return (<main className="flex flex-col h-screen">
        <nav className="flex justify-center p-3">
            <input type="text" className="text-2xl bg-transparent outline-none" value={store.surveyName} onChange={editSurveyName} />
        </nav>
        <section className="flex justify-between items-center h-full">
            <button className={`text-6xl w-1/12 flex justify-center ${store.questionNumber === 0 && "btn-hide"}`} onClick={goLeft}><BsChevronCompactLeft /></button>
            <QuestionsSlide />
            <button className="text-6xl w-1/12 flex justify-center" onClick={goRight}><BsChevronCompactRight /></button>
        </section>
        <footer className="flex justify-end p-4">
            <button className="btn-primary" onClick={submitSurvey}>Finish</button>
        </footer>
    </main>);
}

My application is open source if you want to check it out, currently above code is not yet pushed. Check out here Github

Visrut
  • 360
  • 4
  • 14

0 Answers0