Car Modelling with Coding

Blog For Education
By -
0

 HTML:


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title> 3D Car Animation Model | Nothing4us </title>
    <script src="https://cdn.tailwindcss.com"></script>

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@300;500;800&display=swap" rel="stylesheet">

    <script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>
    <link rel="stylesheet" href="./style.css">

</head>

<body>
    <!-- partial:index.partial.html -->
    <div id="page" class="h-full bg-gradient-to-r from-transparent to-slate-200/30 bg-slate-200 text-slate-900 transition-colors duration-[2000ms] antialiased relative overflow-hidden select-none">

        <div id="loading" class="absolute inset-0 z-50 bg-slate-200/80 flex items-center justify-center">
            <svg class="animate-spin h-10 w-10" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                <g fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="2">
                    <circle class="opacity-20" cx="12" cy="12" r="11" />
                    <path d="m23 12c0 6.1-4.9 11-11 11" />
                </g>
            </svg>
        </div>

        <model-viewer class="absolute left-0 top-0 w-full h-full z-30 pointer-events-none" src="https://cdn.glitch.global/ccaf12bb-59b0-46bb-bd74-b9467ca22e3d/scene.gltf?v=1674149863924" exposure="1" shadow-intensity="3" camera-orbit="0deg 10deg 20%" camera-target="-9.5m -8m 5m"></model-viewer>

        <div class="absolute left-0 top-1/2 -translate-y-1/2 z-0 pointer-events-none">
            <div class="title opacity-0 text-[clamp(200px,40vh,500px)] font-bold text-slate-900/5 opacity-0 pointer-events-none flex whitespace-nowrap will-change-transform">
                <span class="mx-20">240K GT</span>
                <span class="mx-20">240K GT</span>
                <span class="mx-20">240K GT</span>
                <span class="mx-20">240K GT</span>
                <span class="mx-20">240K GT</span>
                <span class="mx-20">240K GT</span>
            </div>
        </div>

        <div class="swiper w-full h-full absolute left-0 top-0 z-40 opacity-0">

            <div class="swiper-wrapper">

                <section class="swiper-slide w-full h-full flex flex-col justify-end relative p-[5vw]">

                    <div id="inner-1" class="flex flex-col items-start gap-4 lg:gap-8 w-full sm:w-2/3 lg:w-1/3 3xl:w-1/4 md:text-lg">
                        <h1 class="text-[clamp(26px,4vw,60px)] leading-none font-light uppercase">
                            Datsun
                            <br class="hidden lg:block" />
                            <span class="font-bold">240K GT</span>
                        </h1>

                        <p>
                            Introducing a Masterpiece, the combination of all Datsun’s great automotive innovations.
                        </p>

                        <strong class="hidden lg:block">
                            From 30,500 €
                        </strong>

                        <div class="flex flex-wrap gap-2">
                            <a href="#section-2" data-slide-to="1" class="uppercase px-6 py-3 md:px-12 md:py-4 rounded-full text-xs md:text-base tracking-wider text-slate-50 bg-blue-700 hover:bg-blue-600 active:bg-blue-900 transition-colors grow text-center">
                                Learn more
                            </a>
                            <a href="#" target="_blank" rel="noopener" class="uppercase px-6 py-3 md:px-12 md:py-4 rounded-full text-xs md:text-base tracking-wider bg-transparent hover:bg-slate-50/50 active:bg-white transition-colors grow text-center">Contact us</a>
                        </div>
                    </div>

                    <p> &#169; Codingwithbharath</p>

                </section>

                <section class="swiper-slide w-full h-full flex flex-col items-end justify-end lg:justify-center relative z-50 px-[5vw] py-[5vh]">

                    <div id="inner-2" class="flex flex-col items-start gap-5 lg:gap-8 w-full sm:w-2/3 lg:w-1/3 2xl:w-1/4 p-[2.5vw] mb-8 lg:mb-0 sm:box-content rounded-xl sm:rounded-[2vw] md:text-lg text-slate-50 bg-zinc-900/20 backdrop-blur-lg">
                        <h2 class="text-[clamp(22px,3vw,36px)] leading-[110%]">
                            A compact car with an exceptional power-to-weight ratio
                        </h2>

                        <p class="mb-10 lg:mb-7">
                            In addition to all the usual Datsun free extra, the 240K gives you ultimate refinements like electric rear window defroster; adjustable tilt steering wheel.
                        <p> &#169; Codingwithbharath</p>
                        </p>


                        <a href="#section-3" data-slide-to="2" class="uppercase px-12 py-4 rounded-full text-xs md:text-base tracking-wider text-slate-50 bg-blue-700 hover:bg-blue-600 active:bg-blue-900 transition-colors absolute bottom-0 translate-y-1/2">
                            Personalise
                        </a>

                    </div>

                </section>

                <section class="swiper-slide w-full h-full flex flex-col items-center relative px-[5vw] py-[5vh]">

                    <div id="inner-3" class="relative z-50 flex flex-col items-center gap-4 text-white drop-shadow-[0_2px_3px_rgba(0,0,0,0.9)]">
                        <h4 class="text-[clamp(22px,3vw,36px)]">
                            Paint
                        </h4>
                        <div class="flex gap-8">
                            <button aria-label="White" data-color="#CBD5E1" class="active relative rounded-full w-[40px] h-[30px] bg-gradient-to-r from-slate-50 to-slate-500 bg-slate-200 outline-0 hover:scale-110 focus:scale-110 transition-all"></button>
                            <button aria-label="Blue" data-color="#355F99" class="relative rounded-full w-[40px] h-[30px] bg-gradient-to-r from-blue-500 to-blue-900 bg-blue-700 outline-0 hover:scale-110 focus:scale-110 transition-all"></button>
                            <button aria-label="Red" data-color="#923939" class="relative rounded-full w-[40px] h-[30px] bg-gradient-to-r from-red-400 to-red-800 bg-red-600 outline-0 hover:scale-110 focus:scale-110 transition-all"></button>
                        </div>
                    </div>

                </section>

            </div>

            <div class="swiper-pagination"></div>

        </div>

        <picture class="absolute left-0 top-1/2 w-full h-full z-0 opacity-0">
            <source srcSet="https://cdn.glitch.global/ccaf12bb-59b0-46bb-bd74-b9467ca22e3d/bg-road-3000.jpg?v=1674210862901" media="(min-width: 2000px)" />
            <source srcSet="https://cdn.glitch.global/ccaf12bb-59b0-46bb-bd74-b9467ca22e3d/bg-road-2000.jpg?v=1674210859490, https://cdn.glitch.global/ccaf12bb-59b0-46bb-bd74-b9467ca22e3d/bg-road-3000.jpg?v=1674210862901 2x" media="(min-width: 1000px)" />
            <source srcSet="https://cdn.glitch.global/ccaf12bb-59b0-46bb-bd74-b9467ca22e3d/bg-road-1000.jpg?v=1674210857284, https://cdn.glitch.global/ccaf12bb-59b0-46bb-bd74-b9467ca22e3d/bg-road-2000.jpg?v=1674210859490 2x" media="(min-width: 500px)" />
            <img class="w-full h-full object-cover" srcSet="https://cdn.glitch.global/ccaf12bb-59b0-46bb-bd74-b9467ca22e3d/bg-road-1000.jpg?v=1674210857284 2x" src="https://cdn.glitch.global/ccaf12bb-59b0-46bb-bd74-b9467ca22e3d/bg-road-500.jpg?v=1674211189312" alt="Landscape" />
        </picture>

    </div>
    <!-- partial -->
    <script src='https://cdnjs.cloudflare.com/ajax/libs/Swiper/8.4.6/swiper-bundle.min.js'></script>
    <script src='https://unpkg.co/gsap@3/dist/gsap.min.js'></script>
    <script src='https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js'></script>
    <script src="./script.js"></script>

</body>

</html>


CSS:

@import url('https://fonts.googleapis.com/css2?family=Bree+Serif&family=Caveat:wght@400;700&family=Lobster&family=Monoton&family=Open+Sans:ital,wght@0,400;0,700;1,400;1,700&family=Playfair+Display+SC:ital,wght@0,400;0,700;1,700&family=Playfair+Display:ital,wght@0,400;0,700;1,700&family=Roboto:ital,wght@0,400;0,700;1,400;1,700&family=Source+Sans+Pro:ital,wght@0,400;0,700;1,700&family=Work+Sans:ital,wght@0,400;0,700;1,700&display=swap');

html,
body {
    width: 100%;
    height: 100%;
}

body {
    font-family: 'Manrope', sans-serif;
}

model-viewer {
    --poster-color: #e2e8f0;
    --progress-bar-color: rgba(30, 41, 59, .5);
    --progress-bar-height: 10px;
}

[data-color]::before {
    content: "";
    display: block;
    position: absolute;
    inset: -5px;
    border: 2px solid transparent;
    border-radius: 999px;
}

[data-color].active::before,
[data-color]:focus::before {
    border-color: white;
}

JS:

/* VARIABLES */
const page = document.getElementById('page'),
    loading = document.getElementById('loading'),
    slider = document.querySelector('.swiper'),
    inner1 = document.getElementById('inner-1'),
    inner2 = document.getElementById('inner-2'),
    inner3 = document.getElementById('inner-3'),
    car = document.querySelector('model-viewer'),
    slideToButtons = document.querySelectorAll('[data-slide-to]'),
    colorButtons = document.querySelectorAll('[data-color]'),
    title = document.querySelectorAll('.title'),
    bgImage = document.querySelector('picture');

const innerAnimationActive = {
    duration: 1,
    delay: 0.5,
    ease: Power4.easeOut,
    autoAlpha: 1,
    yPercent: 0,
};
const innerAnimationHidden = {
    duration: 1,
    ease: Power4.easeOut,
    autoAlpha: 0,
    yPercent: -20,
};

/* VERTICAL SLIDER */
const swiper = new Swiper(slider, {
    direction: 'vertical',
    speed: 1500,
    grabCursor: true,
    touchRatio: 2,
    threshold: 1,
    preventInteractionOnTransition: true,
    mousewheel: {
        forceToAxis: true,
    },
    keyboard: {
        enabled: true,
    },
    on: {
        init: () => {
            /* SLIDER & TITLE FADE IN */
            gsap.to(slider, {
                duration: 1,
                ease: Power4.easeOut,
                autoAlpha: 1,
            });
            gsap.to(title, innerAnimationActive);

            /* TITLE INFINITE LOOP */
            title.forEach(function(e, i) {
                let row_width = e.getBoundingClientRect().width;
                let row_item_width = e.children[0].getBoundingClientRect().width;
                let offset = ((2 * row_item_width) / row_width) * 100 * -1;
                let duration = 30 * (i + 1);

                gsap.set(e, {
                    xPercent: 0
                });

                gsap.to(e, {
                    duration: duration,
                    ease: "none",
                    xPercent: offset,
                    repeat: -1
                });
            });
        }
    },
});

/* ON LOAD */
car.addEventListener('load', (event) => {
    /* FADE OUT LOADING SCREEN */
    gsap.to(loading, {
        duration: 1,
        ease: Power4.easeOut,
        autoAlpha: 0,
    });

    /* 3D CHARACTERISTICS */
    const materials = car.model.materials,
        paint = materials[10];

    /* CHANGE CAR PAINT */
    paint.pbrMetallicRoughness.setBaseColorFactor('#CBD5E1');

    /* CAR POSITION */
    const exposure1 = '1',
        orbit1 = '0deg 50deg 50%',
        exposure2 = '0.4',
        orbit2 = '-60deg 60deg 50%',
        exposure3 = '1',
        orbit3 = '44deg 83deg 50%';
    let target1,
        target2,
        target3;

    const setCarPosition = () => {
        if (window.innerWidth <= 900) {
            target1 = '-9.5m -11.9m 4.2m';
            target2 = '-8.8m -12.7m 4.8m';
            target3 = '-9.8m -10m 3.8m';
        } else {
            target1 = '-9.5m -12.9m 2.2m';
            target2 = '-5.8m -12.5m 3.8m';
            target3 = '-12m -10.7m 1.7m';
        }
    }
    setCarPosition();

    const carPosition = (exposure, orbit, target) => {
        return ({
            duration: 1.5,
            ease: Power4.easeOut,
            attr: {
                ['exposure']: exposure,
                ['camera-orbit']: orbit,
                ['camera-target']: target,
            }
        });
    };

    /* ANIMATION ON LOAD */
    gsap.to(car, carPosition(exposure1, orbit1, target1));

    /* SLIDE CHANGE */
    swiper.on('slideChange', function() {
        if (swiper.activeIndex === 0) {
            gsap.to(car, carPosition(exposure1, orbit1, target1));
            page.classList.remove('bg-zinc-900');
            page.classList.add('bg-slate-200');
        } else if (swiper.activeIndex === 1) {
            gsap.to(car, carPosition(exposure2, orbit2, target2));
            page.classList.remove('bg-slate-200');
            page.classList.add('bg-zinc-900');
        } else if (swiper.activeIndex === 2) {
            gsap.to(car, carPosition(exposure3, orbit3, target3));
            page.classList.remove('bg-zinc-900');
            page.classList.add('bg-slate-200');
        }

        if (swiper.activeIndex === 0) {
            gsap.to(inner1, innerAnimationActive);
            gsap.to(title, innerAnimationActive);
        } else {
            gsap.to(inner1, innerAnimationHidden);
            gsap.to(title, innerAnimationHidden);
        }

        if (swiper.activeIndex === 1) {
            gsap.to(inner2, innerAnimationActive);
        } else {
            gsap.to(inner2, innerAnimationHidden);
        }

        if (swiper.activeIndex === 2) {
            gsap.to(inner3, innerAnimationActive);
            gsap.to(bgImage, {
                duration: 1,
                delay: 1,
                ease: Power4.easeOut,
                autoAlpha: 1,
                yPercent: -50,
            });
        } else {
            gsap.to(inner3, innerAnimationHidden);
            gsap.to(bgImage, {
                duration: 0.5,
                ease: Power4.easeOut,
                autoAlpha: 0,
                yPercent: 0,
            });
        }
    });

    /* WINDOW RESIZE CAR POSITION */
    swiper.on('resize', function() {
        setCarPosition();

        if (swiper.activeIndex === 0) {
            gsap.to(car, carPosition(exposure1, orbit1, target1));
        } else if (swiper.activeIndex === 1) {
            gsap.to(car, carPosition(exposure2, orbit2, target2));
        } else if (swiper.activeIndex === 2) {
            gsap.to(car, carPosition(exposure3, orbit3, target3));
        }
    });

    /* SLIDE TO */
    slideToButtons.forEach((button) => {
        button.addEventListener('click', (e) => {
            const index = e.target.dataset.slideTo;
            if (index !== undefined) {
                swiper.slideTo(index);
            }
            e.preventDefault();
        });
    });

    /* PAINT */
    colorButtons.forEach((button) => {
        button.addEventListener('click', (e) => {
            /* CHANGE COLOR */
            const color = e.target.dataset.color;
            if (color !== undefined) {
                paint.pbrMetallicRoughness.setBaseColorFactor(color);
            }

            /* BUTTON ACTIVE */
            colorButtons.forEach((otherButton) => {
                otherButton.classList.remove('active');
            });
            e.target.classList.add('active');

            e.preventDefault();
        });
    });
});

Post a Comment

0Comments

Post a Comment (0)
Why Cybersecurity Courses Are in High Demand

Why Cybersecurity Courses Are in High Demand

According to the above information, Due to the Rising Job Opportunities in Cybersecurity, We Started a Cybersecurity …

By -