Skip to content

Commit

Permalink
Merge pull request #123 from Gather307/90-update-home-page
Browse files Browse the repository at this point in the history
90 update home page
  • Loading branch information
zmattes04 authored May 30, 2024
2 parents 70548a8 + d9b9fe9 commit 01117f8
Show file tree
Hide file tree
Showing 4 changed files with 340 additions and 2 deletions.
Binary file added frontend/public/HomePage2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { Box, ChakraProvider } from "@chakra-ui/react";
import { useState, useEffect } from "react";
import LoginPage from "./pages/LoginPage";
import HomePage from "./pages/HomePage";
import SignupPage from "./pages/SignupPage";
import ItemsPage from "./pages/ItemsPage";
import NavbarSignedOut from "./components/NavbarSignedOut";
Expand All @@ -15,6 +14,7 @@ import EditItem from "./components/EditItem";
import EditGroup from "./components/EditGroup";
import EditBasket from "./components/EditBasket";
import { IUser } from "../../backend/models/userSchema";
import MoveLetters from "./components/moveLetters";
import theme from "./theme";

// TODO: When we integrate the frontend to use the backend, we need to use this API server: gather-app-inv.azurewebsites.net
Expand Down Expand Up @@ -87,7 +87,7 @@ function App() {
<NavbarSignedOut />
)}
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/" element={<MoveLetters />} />
<Route
path="/login"
element={<LoginPage updateState={{ setUser, setToken }} />}
Expand Down
293 changes: 293 additions & 0 deletions frontend/src/components/moveLetters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
import React, { useEffect, useRef, useState } from "react";
import "../styles/moveLetters.css";
import { Button } from "@chakra-ui/react";
import imageSrc from "../../public/TheLeaf.png";

const MoveLetters: React.FC = () => {
const letters =
"GATHERGATHERGATHEGATHERGATHERGATHERGATHERGATHERGATHEGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHERGATHER".split(
"",
);
const [showImage, setShowImage] = useState(false); // State to control image display

const sceneRef = useRef<HTMLDivElement>(null);
const [positions, setPositions] = useState<
{ x: number; y: number; vx: number; vy: number; settled: boolean }[]
>([]);

const mousePosition = useRef<{ x: number; y: number }>({
x: window.innerWidth / 2,
y: window.innerHeight / 2,
});
const [showText, setShowText] = useState(false);
const animationFrameId = useRef<number>();

useEffect(() => {
// Initialize positions for each letter
const initialPositions = letters.map(() => ({
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
vx: 0,
vy: 0,
settled: false,
}));
setPositions(initialPositions);

// Function to handle collisions and update positions
const updatePositions = () => {
setPositions((prevPositions) => {
// Copy previous positions
const newPositions = [...prevPositions];

// Update positions based on mouse interaction
newPositions.forEach((pos, index) => {
if (!pos.settled) {
let newX = pos.x + pos.vx;
let newY = pos.y + pos.vy;

// Check boundaries
const letterWidth = 20; // Assuming 50px width for letters
const letterHeight = 30; // Assuming 50px height for letters
const minX = 20;
const maxX = window.innerWidth - letterWidth;
const minY = 90;
const maxY = window.innerHeight - letterHeight;

if (newX < minX) {
newX = minX;
pos.vx *= -1; // Reverse horizontal velocity to bounce off the left border
} else if (newX > maxX) {
newX = maxX;
pos.vx *= -1; // Reverse horizontal velocity to bounce off the right border
}

if (newY < minY) {
newY = minY;
pos.vy *= -1; // Reverse vertical velocity to bounce off the top border
} else if (newY > maxY) {
newY = maxY;
pos.vy *= -1; // Reverse vertical velocity to bounce off the bottom border
}

// Update position
newPositions[index] = { ...pos, x: newX, y: newY };

// Check if letter is close to button and mark it as settled
const buttonRect = sceneRef.current?.getBoundingClientRect();
if (buttonRect) {
const distanceToButton = Math.sqrt(
Math.pow(newX - (buttonRect.left + buttonRect.width / 2), 2) +
Math.pow(newY - (buttonRect.top + buttonRect.height / 2), 2),
);
if (distanceToButton < 150) {
// Adjust the distance as needed
newPositions[index] = { ...pos, settled: true };
}
}
}
});

return newPositions.filter((pos) => !pos.settled);
});

animationFrameId.current = requestAnimationFrame(updatePositions);
};

// Start the animation loop
animationFrameId.current = requestAnimationFrame(updatePositions);

// Cleanup
return () => {
if (animationFrameId.current) {
cancelAnimationFrame(animationFrameId.current);
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

// Update mouse position
const handleMouseMove = (event: React.MouseEvent<HTMLDivElement>) => {
mousePosition.current = { x: event.clientX, y: event.clientY };

// Reset velocities to zero
setPositions((prevPositions) => {
return prevPositions.map((pos) => ({ ...pos, vx: 0, vy: 0 }));
});

// Influence the velocity of letters based on mouse movement
setPositions((prevPositions) => {
const newPositions = [...prevPositions];
newPositions.forEach((pos) => {
const dx = pos.x - mousePosition.current.x;
const dy = pos.y - mousePosition.current.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const speed = 1.0; // Adjust the speed as needed

if (distance < 800) {
// Adjust the range as needed
pos.vx = (dx / distance) * speed;
pos.vy = (dy / distance) * speed;
}
});
return newPositions;
});
};

const handleMouseMovePull = () => {
// Reset velocities to zero
setPositions((prevPositions) => {
return prevPositions.map((pos) => ({ ...pos, vx: 0, vy: 0 }));
});

// Influence the velocity of letters based on mouse movement
setPositions((prevPositions) => {
const newPositions = [...prevPositions];
newPositions.forEach((pos) => {
const dx = mousePosition.current.x - pos.x;
const dy = mousePosition.current.y - pos.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const speed = 7.0; // Adjust the speed as needed

if (distance < 5000) {
// Adjust the range as needed
pos.vx = (dx / distance) * speed;
pos.vy = (dy / distance) * speed;
}
});
return newPositions;
});
};

const handleButtonClick = () => {
setShowText(true); // Show the new text when the button is clicked
console.log(showText);
setTimeout(() => {
setShowImage(true);
}, 3000);
// Toggle to show the image when button is clicked
handleMouseMovePull(); // Perform the original button action
};

return (
<div className="letterwrapper">
<div
className="letter-container"
ref={sceneRef}
onMouseMove={handleMouseMove}
>
{positions.map(({ x, y }, index) => (
<div
key={index}
className="letter"
style={{ left: `${x}px`, top: `${y}px` }}
>
{letters[index]}
</div>
))}
</div>
<div style={{ textAlign: "center" }}>
{!showImage && (
<Button
variant="ghost"
sx={{
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
fontSize: "60px",
padding: "70px 30px",
borderRadius: "15px",
borderWidth: "1px",
color: "white",
backgroundColor: "#49A078",
zIndex: "3",
_hover: {
borderWidth: "5px",
borderColor: "White",
},
}}
onClick={handleButtonClick}
>
Get Started
<br />
With Gather
</Button>
)}
{showImage && (
<img
src={imageSrc}
alt="Descriptive Text"
style={{
width: "200px", // Adjust width as needed
height: "200px", // Adjust height as needed
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
zIndex: "3",
}}
/>
)}
</div>
{showText && (
<div
style={{
position: "absolute",
top: "25%",
left: "50%",
transform: "translate(-50%, -50%)",
zIndex: "4",
fontSize: "50px",
color: "var(--col-dark)",
whiteSpace: "nowrap",
fontWeight: "bold",
}}
>
THE WORLD WITH PERFECT ORGANIZATION
</div>
)}
{showText && (
<div
style={{
position: "absolute",
top: "10px",
right: "10px",
zIndex: "4",
}}
>
<div style={{ position: "relative" }}>
{/* Arrow */}
<div
style={{
width: 0,
height: 0,
borderLeft: "20px solid transparent",
borderRight: "20px solid transparent",
borderBottom: "20px solid white",
position: "absolute",
top: "-10px",
right: "75px",
}}
/>
{/* Text */}
<div
style={{
backgroundColor: "white",
color: "var(--col-secondary)",
fontSize: "25px",
padding: "10px",
borderRadius: "5px",
textAlign: "center",
marginTop: "10px",
fontWeight: "bold",
}}
>
It starts here!
</div>
</div>
</div>
)}
</div>
);
};
export default MoveLetters;
45 changes: 45 additions & 0 deletions frontend/src/styles/moveLetters.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.letterwrapper {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
position: relative; /* This will serve as a stacking context */
z-index: 0; /* Base layer */
}

.letter-container {
position: fixed;
top: 65px;
left: 0;
width: 100%;
height: 100%;
pointer-events: auto;
background-image: url("../../public/HomePage2.jpg");
background-size: cover;
background-repeat: no-repeat;
background-position: center;
z-index: 1; /* Above the base layer */
}

.letter {
position: fixed;
transform: translate(-50%, -50%);
font-size: 50px;
color: #ffffff;

z-index: 2; /* Ensures letters are above the background container */
}

.letter-center-button {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 3; /* Button above letters for interactivity */
}

/* Ensure the new text is visible by placing it on top */
div[style*="text-align: center; marginTop:"] {
z-index: 4; /* Highest in the hierarchy to ensure visibility */
position: relative; /* Adjust as needed for visibility */
}

0 comments on commit 01117f8

Please sign in to comment.