Skip to content

Commit

Permalink
Merge pull request #45 from sean1832/dev
Browse files Browse the repository at this point in the history
Implement full zoom and image performance improvements
  • Loading branch information
sean1832 authored Jun 29, 2024
2 parents 93f69f8 + dc09fbd commit f397de4
Show file tree
Hide file tree
Showing 31 changed files with 1,213 additions and 921 deletions.
11 changes: 4 additions & 7 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
"json.schemas": [
{
"fileMatch": ["projects.json"],
"url": "/src/data/projects-schema.json"
"url": "/data/schema/projects-schema.json"
},
{
"fileMatch": ["profile.json"],
"url": "/src/data/profile-schema.json"
},
{
"fileMatch": ["skills.json"],
"url": "/src/data/skills-schema.json"
"url": "/data/schema/profile-schema.json"
}
]
],
"gutterpreview.sourceFolder": "public"
}
362 changes: 362 additions & 0 deletions data/generated/imageMetadata.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/data/manifest.json → data/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Zeke Zhang Portfolio",
"version": "1.3.0",
"version": "1.4.0",
"copyright": {
"name": "zekezhang.com"
},
Expand Down
File renamed without changes.
728 changes: 728 additions & 0 deletions data/projects.json

Large diffs are not rendered by default.

File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@
}
}
},
"sizes": {
"type": "string"
},
"longDescription": {
"type": "string"
},
Expand Down
3 changes: 2 additions & 1 deletion jsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
"@/*": ["./src/*"],
"@data/*": ["./data/*"]
}
}
}
1 change: 1 addition & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import withPlaiceholder from "@plaiceholder/next";
const nextConfig = {
images: {
formats: ["image/avif", "image/webp"],
remotePatterns: [
{
protocol: "https",
Expand Down
25 changes: 21 additions & 4 deletions script/blur.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io
import json
import requests
import pathlib

def scale_image_dim(img, max_size):
width, height = img.size
Expand All @@ -13,15 +14,21 @@ def scale_image_dim(img, max_size):
else:
new_height = max_size
new_width = int(max_size * width / height)

if new_width == 0: new_width = 1
if new_height == 0: new_height = 1
return new_width, new_height

def create_blur_url(image_path, max_size=32):
with Image.open(image_path) as img:
width, height = img.size
img = img.convert('RGB')
img = img.resize(scale_image_dim(img, max_size))
buffer = io.BytesIO()
img.save(buffer, format='JPEG', quality=10)
return f'data:image/jpeg;base64,{base64.b64encode(buffer.getvalue()).decode()}'
blurDataUrl = f'data:image/jpeg;base64,{base64.b64encode(buffer.getvalue()).decode()}'
return blurDataUrl, width, height


def is_external_url(url):
return url.startswith('http')
Expand All @@ -36,8 +43,15 @@ def write_json(json_path, data):


if __name__ == '__main__':
data = read_json("src/data/projects.json")
# ============= CONFIG =============
SOURCE = "data/projects.json"
DESTINATION = "data/generated/imageMetadata.json"
SIZE = 16
# ============= CONFIG =============

data = read_json(SOURCE)
isError = False
imageMeta = {}
for project in data:
for image in project["media"]:
if "isVideo" in image and image["isVideo"]: continue
Expand All @@ -48,7 +62,9 @@ def write_json(json_path, data):

try:
print(f'{image["src"]}')
image["blurDataURL"] = create_blur_url(path, 16)
blurUrl, width, height = create_blur_url(path, SIZE)
imageMeta[image["src"]] = {"blurDataURL": blurUrl, "width": width, "height": height}


except Exception as e:
print(f'Error: {e}, image: {image["src"]}')
Expand All @@ -59,7 +75,8 @@ def write_json(json_path, data):
print("\n\nError occured, aborting...")
else:
print("\n\nWrite to file...")
write_json("src/data/projects.json", data)
pathlib.Path(DESTINATION).parent.mkdir(parents=True, exist_ok=True)
write_json(DESTINATION, imageMeta)
print("Done!")


Expand Down
4 changes: 2 additions & 2 deletions script/remove-blur.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ def write_json(json_path, data):


if __name__ == '__main__':
data = read_json("src/data/projects.json")
data = read_json("data/projects.json")
key = "blurDataURL"

for project in data:
for image in project["media"]:
if key in image:
print(f"removing from: {image['src']}")
del image[key]
write_json("src/data/projects.json", data)
write_json("data/projects.json", data)
print("\n\ndone!")
6 changes: 5 additions & 1 deletion src/app/page.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import AboutSection from "@/components/layout/aboutSection";
import LandingSection from "@/components/layout/landingSection";
import ProjectsGallerySection from "@/components/layout/projectsGallerySection";
import AppendToMedia from "@/lib/appendMetadata";
import projectsData from "@data/projects.json";
import imageMetadata from "@data/generated/imageMetadata.json";

export default function Home() {
AppendToMedia(projectsData, imageMetadata);
return (
<main>
<div className="px-10">
<LandingSection />
<AboutSection />
<ProjectsGallerySection />
<ProjectsGallerySection projects={projectsData} />
</div>
</main>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/projects/[id]/layout.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import projectData from "@/data/projects.json";
import projectData from "@data/projects.json";

// see doc: https://nextjs.org/docs/app/building-your-application/optimizing/metadata#dynamic-metadata
export async function generateMetadata({ params }) {
Expand Down
8 changes: 6 additions & 2 deletions src/app/projects/[id]/page.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React from "react";
import projectData from "@/data/projects.json";
import projectData from "@data/projects.json";
import ProjectInfo from "@/components/layout/projectDetailSection";
import { ProjectNavigation } from "@/components/ui/project-navigation";
import { notFound } from "next/navigation";
import AppendToMedia from "@/lib/appendMetadata";
import imageMetadata from "@data/generated/imageMetadata.json";

// dynamically generate page if params is not known during built time
// set to true if you want to update the site content without rebuilding the site
// see doc: https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
export const dynamicParams = false;
export const dynamicParams = false;

// static generation of project page during built time based on project id
// see doc: https://nextjs.org/docs/app/api-reference/functions/generate-static-params
Expand All @@ -28,6 +30,8 @@ const ProjectPage = ({ params }) => {
notFound();
}

AppendToMedia(projectData, imageMetadata);

const data = projectData[projectIndex];

return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/aboutSection.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import RevealListClient from "../animation/reveal-list-client";
import profile from "@/data/profile.json";
import profile from "@data/profile.json";
import { buttonVariants } from "@/components/ui/button";
import { GitHubLogoIcon, InstagramLogoIcon } from "@radix-ui/react-icons";
import { IoLogoYoutube } from "react-icons/io5";
Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/footer.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import { Separator } from "../ui/separator";
import ExternalTextLink from "../ui/external-text-link";
import manifest from "@/data/manifest";
import manifest from "@data/manifest";
import { GetLatestUrl, GetRepoUrl } from "@/lib/getGithub";

const Footer = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/landingSection.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import dynamic from "next/dynamic";
import profile from "@/data/profile.json";
import profile from "@data/profile.json";

const TextDecode = dynamic(() => import("@/components/animation/text-decode"), {
ssr: false,
Expand Down
9 changes: 5 additions & 4 deletions src/components/layout/navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use client";
import React, { useState } from "react";
import navbarData from "@/data/navbar";
import { ZekeLogoIcon } from "../svg";
import { Separator } from "../ui/separator";
import { ModeToggle } from "@/components/ui/theme/mode-toggle";
Expand Down Expand Up @@ -29,11 +28,13 @@ function MenuIcon(props) {
);
}

const navbar = [{ title: "home" }, { title: "projects" }];

const NavbarLinks = ({ navbarData, className }) =>
navbarData.map((item, i) => (
<Link
key={`navbar-link-${i}`}
href={item.url}
href={`/#${item.title}`}
className={`${className} text-xl font-medium transition-colors dark:hover:text-primary dark:text-muted-foreground hover:text-gray-500 dark:text-gray-300 text-primary`}
>
{item.title}
Expand Down Expand Up @@ -66,7 +67,7 @@ const NavBar = () => {
{/* Desktop navigation */}
<nav className="items-center gap-4">
<div className="hidden md:flex items-center gap-10">
<NavbarLinks navbarData={navbarData} className="navbar-link" />
<NavbarLinks navbarData={navbar} className="navbar-link" />
<ModeToggle />
</div>

Expand All @@ -80,7 +81,7 @@ const NavBar = () => {
</SheetTrigger>
<SheetContent side="right">
<div className="flex flex-col gap-8 justify-center items-center text-2xl">
<NavbarLinks navbarData={navbarData} className="navbar-link-mobile" />
<NavbarLinks navbarData={navbar} className="navbar-link-mobile" />
<ModeToggle />
</div>
</SheetContent>
Expand Down
6 changes: 3 additions & 3 deletions src/components/layout/projectsGallerySection.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from "react";
import { BentoGrid, BentoGridItem } from "@/components/ui/bento-grid";
import projects from "@/data/projects.json";
import Link from "next/link";
import BlurImage from "../ui/media/blur";
import ConstructProjectHref from "@/lib/constructProjectHref";
import { cn } from "@/utils/cn";

const ProjectsGallerySection = async () => {
const ProjectsGallerySection = async ({projects}) => {
return (
<section id="projects">
<BentoGrid className={`auto-rows-[30rem] md:auto-rows-[50rem] lg:grid-cols-6`}>
Expand Down Expand Up @@ -41,7 +41,7 @@ const ProjectsGallerySection = async () => {
blurDataURL={heroImage?.blurDataURL}
/>
}
className={`${project.gallery.className} uppercase `}
className={cn("lg:col-span-3 uppercase", project.gallery.className)}
/>
);
})}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/button/githubFloatingButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import FloatingButton from "./floatingButton";
import { GitHubLogoIcon } from "@radix-ui/react-icons";
import Link from "next/link";
import manifest from "@/data/manifest";
import manifest from "@data/manifest";

const GithubFloatingButton = () => {
return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/carousel/carousel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ const Carousel = forwardRef(
tabIndex={0}
ref={ref}
onKeyDownCapture={handleKeyDown}
onWheel={handleMouseScroll} // for vertical scroll
// onWheel={handleMouseScroll} // for vertical scroll
className={cn("grid gap-2 w-full relative focus:outline-none", className)}
dir={direction}
>
Expand Down
Loading

0 comments on commit f397de4

Please sign in to comment.