Skip to content

wisecameron/VertigoDAOFrontend

Repository files navigation

project logo

VertigoDAO Frontend [vertigodao.com]

Resource-packed Website Built With React/@react-three/fiber/Web3.js!

This website hosts VertigoDAO, a Web3 project that aimed to 
make DeFi more accessible by allowing users to earn tokens by completing 
company and community-supplied tasks.  It leverages scroll-based 
text and scene animations (@react-three/drei ScrollControls), and is essentially composed of numerous distinct 
three.js scenes, which makes it a great resource for learning a variety of different techniques.



Feel free to connect with me on linkedin! https://www.linkedin.com/in/cameron-warnick-64a25222a/


Content

Highlights ✨

  • Integrated Web3 dashboard and shop system
  • Countless interesting three.js effects and systems
  • Significant coverage of the React toolset
  • Interesting mini-projects including "Roadmap," an infinite highway with flying vehicles.
  • Custom scroll-based animation handling that manages three.js scenes and html content.
  • Great reference for space-themed projects.

Install 🐙

Feel free to download and use the code as you wish, you don't need to credit me if you use any of the systems, although I would certainly not mind.

Usage 💡

Obviously, this repository will not produce a working website. Unfortunately, I am not able to post the entire project. However, this is also a good thing. You can visit vertigodao.com to find specific effects or scenes that catch your eye, reference the code to learn how it works, then implement it yourself to grasp it concretely.

Examples 🖍

import React, { useRef } from 'react'
import { useFrame, useThree } from '@react-three/fiber'
import { useEffect } from 'react';
import { useScroll } from '@react-three/drei';

export default function CarOptimized(props)
{
    const ref = useRef();
    const meshRef = useRef();
    const lightRef = useRef();

    const scroll = useScroll();
    let offset;

    const cop = useRef((Math.random() < 0.2));
    const speed = useRef(400);
    const direction = useRef((Math.random() > 0.5)); //pos is true
    const iterations = useRef(0);

    const ResetPositions = () =>
    {
        if(ref.current === undefined) return;

        ref.current.position.x = (direction.current) ? -400: 1000;
        ref.current.position.y = 100 + Math.random() * 1000;
        ref.current.position.z = Math.random() * 750;
    }

    const ResetScale = () =>
    {
        meshRef.current.scale.x = 2 + Math.random() * 45;
        meshRef.current.scale.y = 2 + Math.random() * 5;
        meshRef.current.scale.z = 2 + Math.random() * 15;
    }

    useEffect(() =>
    {
        ResetScale();
    }, [])

    useFrame((_, delta) =>
    {
        let offset = scroll.offset;
        if(offset > 1) offset = 0;

        //Case: visible
        if(offset >= props.minVis && offset < props.maxVis)
        {
            //upkeep
            if(ref.current.visible == false) ref.current.visible = true;

            if(lightRef.current.intensity < 30)
            {
                lightRef.current.intensity += delta * 30;
            }

            if(meshRef.current.material.opacity < 1)
            {
                meshRef.current.material.opacity += delta * .5;
            }

            //console.log(ref.current.visible, lightRef.current.intensity, meshRef.current.material.opacity)

            // Check/handle reset
            if(ref.current.position.x > 1500 || ref.current.position.x < -2000)
            {
                //handle cop
                if(Math.random() < .2) cop.current = true;
                else cop.current = false;
    
                //init values
                if(cop.current)
                {
                    lightRef.current.color.set("red")
                    meshRef.current.material.color.set("red")
                    iterations.current = 0;
                }
                else
                {
                    lightRef.current.color.set(props.lightColor);
                    meshRef.current.material.color.set(props.materialColor);
                }
    
                ResetPositions();
                ResetScale();
    
                return;
            }
            /*
                MOVEMENT
            */
            else
            {
                if(direction.current)
                {
                    ref.current.position.x += delta * speed.current;
                }
                else
                {
                    ref.current.position.x -= delta * speed.current;
                }
            }
    
            /*
                HANDLE COP
            */
            if(cop.current)
            {
                if(iterations.current > .2)
                {
                    lightRef.current.color.getHexString() === "fe0000" ? lightRef.current.color.set("blue") : lightRef.current.color.set("red");
                    iterations.current = 0;
                }
                iterations.current += delta;
            }

            return;
        }
        //Case: invisible
        //upkeep

        if(lightRef.current.intensity > 0 || meshRef.current.material.opacity > 0)
        {
            if(lightRef.current.intensity > 0)
            {
                lightRef.current.intensity -= delta * 30;
            }
            if(meshRef.current.material.opacity > 0)
            {
                meshRef.current.material.opacity -= delta * .5;
            }

            if(direction.current)
            {
                ref.current.position.x += delta * speed.current;
            }
            else
            {
                ref.current.position.x -= delta * speed.current;
            }
        }
        else if(ref.current.visible === true) ref.current.visible = false;

        

    })

    return(
        <group ref = {ref} position = {[-400 + Math.random() * 1400, 100 + Math.random() * 1000,  Math.random() * 750]}>

            <pointLight ref = {lightRef} intensity = {30} decay = {2} distance = {600} color = {props.lightColor}/>

            <mesh ref = {meshRef} scale = {[1,1,1]} >
                <boxGeometry args = {[1,1,1]} />
                <meshBasicMaterial color = {cop.current ? "red" : props.materialColor} transparent/>
            </mesh>

        </group>
    );
}

Documentation 📄

If you want to read the vertigodao whitepaper for whatever reason, you can find it here https://vertigodao.com/documentation

Shoutouts 👷

Credit to Kim Hoang https://www.linkedin.com/in/kim-hoang-466134172/ for creating most of the art assets you can see on the site!

License ⚖️

Unlicensed! Do whatever you want, credit me if you want.


About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published