Use Imgur as host instead
@ -5,13 +5,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gallery-photo {
|
.gallery-photo {
|
||||||
margin: 4px;
|
margin: 0.6vw;
|
||||||
margin-left: 4px;
|
border-radius: 5px;
|
||||||
margin-right: 4px;
|
|
||||||
border-radius: 8px;
|
|
||||||
display: block;
|
display: block;
|
||||||
height: auto;
|
height: auto;
|
||||||
max-width: 30vw; /* Do not mix with max-height! */
|
max-width: 31vw; /* Do not mix with max-height! */
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,53 +1,40 @@
|
|||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import Masonry from 'masonry-layout';
|
import Masonry from 'masonry-layout';
|
||||||
import './Home.css'; // Global styles
|
import images from '../data/Images'; // Import the image URLs
|
||||||
|
import './Home.css'; // Ensure you have your CSS for styling
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
const masonryRef = useRef(null);
|
const masonryRef = useRef(null);
|
||||||
|
|
||||||
// Use require.context to load all images from the static/photos directory
|
|
||||||
const importAll = (r) => {
|
|
||||||
let images = {};
|
|
||||||
r.keys().forEach((item) => { images[item.replace('./', '')] = r(item); });
|
|
||||||
return images;
|
|
||||||
};
|
|
||||||
|
|
||||||
const images = importAll(require.context('../../static/photos', false, /\.(png|jpe?g|svg)$/));
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Initialize Masonry after images have loaded
|
|
||||||
const masonry = new Masonry(masonryRef.current, {
|
const masonry = new Masonry(masonryRef.current, {
|
||||||
itemSelector: '.gallery-photo',
|
itemSelector: '.gallery-photo',
|
||||||
columnWidth: '.gallery-photo',
|
columnWidth: '.gallery-photo',
|
||||||
percentPosition: true,
|
percentPosition: true
|
||||||
horizontalOrder: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Layout Masonry after all images have loaded
|
// Layout Masonry after images have loaded
|
||||||
const imgLoad = images => {
|
const imagesLoaded = () => {
|
||||||
const imgLoad = images.map(img => {
|
masonry.layout();
|
||||||
return new Promise((resolve) => {
|
|
||||||
const imgElement = new Image();
|
|
||||||
imgElement.src = img;
|
|
||||||
imgElement.onload = resolve;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return Promise.all(imgLoad);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
imgLoad(Object.values(images)).then(() => {
|
// Add event listener for image load
|
||||||
masonry.layout();
|
const imgElements = masonryRef.current.querySelectorAll('img');
|
||||||
|
imgElements.forEach(img => {
|
||||||
|
img.addEventListener('load', imagesLoaded);
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
masonry.destroy(); // Cleanup on unmount
|
imgElements.forEach(img => {
|
||||||
|
img.removeEventListener('load', imagesLoaded);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}, [images]);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gallery" ref={masonryRef}>
|
<div className="gallery" ref={masonryRef}>
|
||||||
{Object.keys(images).map((key, index) => (
|
{images.map((image, index) => (
|
||||||
<img key={index} src={images[key]} alt={`Jake Runyan ${index + 1}`} className="gallery-photo" />
|
<img key={index} src={image} alt={`Jake Runyan ${index + 1}`} className="gallery-photo" />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
34
src/components/Navbar.css
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.navbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between; /* Space between logo, title, and icons */
|
||||||
|
align-items: center; /* Center items vertically */
|
||||||
|
background-color: #333; /* Background color of the navbar */
|
||||||
|
padding: 10px 20px; /* Padding for the navbar */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-logo .logo {
|
||||||
|
height: 50px; /* Set a height for the logo */
|
||||||
|
border-radius: 10px; /* Rounded corners for the logo */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-title h1 {
|
||||||
|
color: white; /* Text color */
|
||||||
|
font-family: 'Arial', sans-serif; /* Specify your desired font */
|
||||||
|
font-size: 24px; /* Font size for the title */
|
||||||
|
margin: 0; /* Remove default margin */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-icons {
|
||||||
|
display: flex; /* Use flexbox for icons */
|
||||||
|
gap: 15px; /* Space between icons */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-icons .icon {
|
||||||
|
height: 30px; /* Set a height for the icons */
|
||||||
|
width: 30px; /* Set a width for the icons */
|
||||||
|
transition: transform 0.2s; /* Smooth transition for hover effect */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-icons .icon:hover {
|
||||||
|
transform: scale(1.1); /* Scale up the icon on hover */
|
||||||
|
}
|
@ -1,13 +1,27 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import './Navbar.css';
|
||||||
|
import logo from './static/navbar-logo.png';
|
||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
return (
|
return (
|
||||||
<nav>
|
<nav className="navbar">
|
||||||
<ul>
|
<div className="navbar-logo">
|
||||||
<li><Link to="/">Home</Link></li>
|
<Link to="/">
|
||||||
<li><Link to="/contact">Contact</Link></li>
|
<img src={logo} alt="Logo" className="logo" />
|
||||||
</ul>
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div className="navbar-title">
|
||||||
|
<h1>Photography Portfolio</h1>
|
||||||
|
</div>
|
||||||
|
<div className="navbar-icons">
|
||||||
|
<a href="https://github.com/yourusername" target="_blank" rel="noopener noreferrer">
|
||||||
|
<img src="path/to/github-icon.png" alt="GitHub" className="icon" />
|
||||||
|
</a>
|
||||||
|
<a href="https://www.instagram.com/yourusername" target="_blank" rel="noopener noreferrer">
|
||||||
|
<img src="path/to/instagram-icon.png" alt="Instagram" className="icon" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
BIN
src/components/static/navbar-logo.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
8
src/data/Images.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* Images are loaded from urls to avoid checking everything in to git. */
|
||||||
|
const images = [
|
||||||
|
"https://i.imgur.com/OA575Dq.jpg",
|
||||||
|
"https://i.imgur.com/OA575Dq.jpg",
|
||||||
|
"https://i.imgur.com/OA575Dq.jpg",
|
||||||
|
];
|
||||||
|
|
||||||
|
export default images;
|
Before Width: | Height: | Size: 12 MiB |
Before Width: | Height: | Size: 19 MiB |
Before Width: | Height: | Size: 11 MiB |
Before Width: | Height: | Size: 10 MiB |
Before Width: | Height: | Size: 11 MiB |
Before Width: | Height: | Size: 5.7 MiB |
Before Width: | Height: | Size: 15 MiB |
Before Width: | Height: | Size: 25 MiB |
Before Width: | Height: | Size: 25 MiB |
Before Width: | Height: | Size: 24 MiB |