-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bf5d9c8
commit 1446991
Showing
3 changed files
with
237 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
// @ts-nocheck | ||
|
||
import * as THREE from 'three' | ||
import { useEffect, useRef, useState } from 'react' | ||
import { Canvas, extend, useThree, useFrame } from '@react-three/fiber' | ||
import { useGLTF, useTexture, Environment, Lightformer } from '@react-three/drei' | ||
import { BallCollider, CuboidCollider, Physics, RigidBody, useRopeJoint, useSphericalJoint } from '@react-three/rapier' | ||
import { MeshLineGeometry, MeshLineMaterial } from 'meshline' | ||
import { motion, useScroll } from "framer-motion"; | ||
import { BackgroundGradient } from '../../components/ui/backgroundGradiant' | ||
import { MyExperience } from '../../components/about-me' | ||
|
||
extend({ MeshLineGeometry, MeshLineMaterial }) | ||
useGLTF.preload('/assets/blog/img_bin/justin.glb') | ||
useTexture.preload('/assets/blog/img_bin/black.png') | ||
|
||
export default function AboutMe() { | ||
const [isSmallScreen, setIsSmallScreen] = useState(false) | ||
const { scrollYProgress } = useScroll(); | ||
|
||
|
||
useEffect(() => { | ||
const handleResize = () => { | ||
setIsSmallScreen(window.innerWidth < 640) | ||
} | ||
|
||
window.addEventListener('resize', handleResize) | ||
handleResize() // Call initially to set the correct state | ||
|
||
return () => { | ||
window.removeEventListener('resize', handleResize) | ||
} | ||
}, []) | ||
|
||
return ( | ||
<div className='container mx-auto max-w-6xl min-h-screen'> | ||
<div className='relative flex flex-col md:flex-row mt-5 md:mt-10'> | ||
<BackgroundGradient containerClassName="sticky flex-1 h-fit w-full md:w-1/2 md:order-2 p-1" className='h-[200px] md:h-[400px] bg-black rounded-3xl' > | ||
<Canvas className='' camera={{ position: [0, 0, 13], fov: 25 }} style={{ pointerEvents: 'none' }}> | ||
<ambientLight intensity={Math.PI} /> | ||
<Physics interpolate gravity={[0, -40, 0]} timeStep={1 / 60}> | ||
<Band /> | ||
</Physics> | ||
<Environment background blur={0.75}> | ||
<Lightformer intensity={2} color="white" position={[0, -1, 5]} rotation={[0, 0, Math.PI / 3]} scale={[100, 0.1, 1]} /> | ||
<Lightformer intensity={3} color="white" position={[-1, -1, 1]} rotation={[0, 0, Math.PI / 3]} scale={[100, 0.1, 1]} /> | ||
<Lightformer intensity={3} color="white" position={[1, 1, 1]} rotation={[0, 0, Math.PI / 3]} scale={[100, 0.1, 1]} /> | ||
<Lightformer intensity={10} color="white" position={[-10, 0, 14]} rotation={[0, Math.PI / 2, Math.PI / 3]} scale={[100, 10, 1]} /> | ||
</Environment> | ||
</Canvas> | ||
</BackgroundGradient> | ||
<div className='flex-1 bg-black/50 w-full md:w-1/2 flex items-center justify-center'> | ||
<div className='p-10'> | ||
<MyExperience /> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
function Band({ maxSpeed = 50, minSpeed = 10 }) { | ||
const band = useRef(), fixed = useRef(), j1 = useRef(), j2 = useRef(), j3 = useRef(), card = useRef() // prettier-ignore | ||
const vec = new THREE.Vector3(), ang = new THREE.Vector3(), rot = new THREE.Vector3(), dir = new THREE.Vector3() // prettier-ignore | ||
const segmentProps = { type: 'dynamic', canSleep: true, colliders: false, angularDamping: 2, linearDamping: 2 } | ||
const { nodes, materials } = useGLTF('/assets/blog/img_bin/justin.glb') | ||
const texture = useTexture('/assets/blog/img_bin/black.png') | ||
const { width, height } = useThree((state) => state.size) | ||
const [curve] = useState(() => new THREE.CatmullRomCurve3([new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()])) | ||
const [dragged, drag] = useState(false) | ||
const [hovered, hover] = useState(false) | ||
|
||
useRopeJoint(fixed, j1, [[0, 0, 0], [0, 0, 0], 1]) // prettier-ignore | ||
useRopeJoint(j1, j2, [[0, 0, 0], [0, 0, 0], 1]) // prettier-ignore | ||
useRopeJoint(j2, j3, [[0, 0, 0], [0, 0, 0], 1]) // prettier-ignore | ||
useSphericalJoint(j3, card, [[0, 0, 0], [0, 1.45, 0]]) // prettier-ignore | ||
|
||
useEffect(() => { | ||
if (hovered) { | ||
document.body.style.cursor = dragged ? 'grabbing' : 'grab' | ||
return () => void (document.body.style.cursor = 'auto') | ||
} | ||
}, [hovered, dragged]) | ||
|
||
useFrame((state, delta) => { | ||
if (dragged) { | ||
vec.set(state.pointer.x, state.pointer.y, 0.5).unproject(state.camera) | ||
dir.copy(vec).sub(state.camera.position).normalize() | ||
vec.add(dir.multiplyScalar(state.camera.position.length())) | ||
;[card, j1, j2, j3, fixed].forEach((ref) => ref.current && ref.current.wakeUp()) | ||
card.current?.setNextKinematicTranslation({ x: vec.x - dragged.x, y: vec.y - dragged.y, z: vec.z - dragged.z }) | ||
} | ||
if (fixed.current) { | ||
// Fix most of the jitter when over pulling the card | ||
;[j1, j2].forEach((ref) => { | ||
if (!ref.current.lerped) ref.current.lerped = new THREE.Vector3().copy(ref.current?.translation()) | ||
const clampedDistance = Math.max(0.1, Math.min(1, ref.current.lerped.distanceTo(ref.current?.translation()))) | ||
ref.current.lerped.lerp(ref.current.translation(), delta * (minSpeed + clampedDistance * (maxSpeed - minSpeed))) | ||
}) | ||
// Calculate catmul curve | ||
curve.points[0].copy(j3.current.translation()) | ||
curve.points[1].copy(j2.current.lerped) | ||
curve.points[2].copy(j1.current.lerped) | ||
curve.points[3].copy(fixed.current.translation()) | ||
band.current.geometry.setPoints(curve.getPoints(32)) | ||
// Tilt it back towards the screen | ||
ang.copy(card.current.angvel()) | ||
rot.copy(card.current.rotation()) | ||
card.current.setAngvel({ x: ang.x, y: ang.y - rot.y * 0.25, z: ang.z }) | ||
} | ||
}) | ||
|
||
curve.curveType = 'chordal' | ||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping | ||
|
||
return ( | ||
<> | ||
<group position={[0, 4, 0]}> | ||
<RigidBody ref={fixed} {...segmentProps} type="fixed" /> | ||
<RigidBody position={[0.5, 0, 0]} ref={j1} {...segmentProps}> | ||
<BallCollider args={[0.1]} /> | ||
</RigidBody> | ||
<RigidBody position={[1, 0, 0]} ref={j2} {...segmentProps}> | ||
<BallCollider args={[0.1]} /> | ||
</RigidBody> | ||
<RigidBody position={[1.5, 0, 0]} ref={j3} {...segmentProps}> | ||
<BallCollider args={[0.1]} /> | ||
</RigidBody> | ||
<RigidBody position={[2, 0, 0]} ref={card} {...segmentProps} type={dragged ? 'kinematicPosition' : 'dynamic'}> | ||
<CuboidCollider args={[0.8, 1.125, 0.01]} /> | ||
<group | ||
scale={2.25} | ||
position={[0, -1.2, -0.05]} | ||
onPointerOver={() => hover(true)} | ||
onPointerOut={() => hover(false)} | ||
onPointerUp={(e) => (e.target.releasePointerCapture(e.pointerId), drag(false))} | ||
onPointerDown={(e) => (e.target.setPointerCapture(e.pointerId), drag(new THREE.Vector3().copy(e.point).sub(vec.copy(card.current.translation()))))}> | ||
<mesh geometry={nodes.card.geometry}> | ||
<meshPhysicalMaterial map={materials.base.map} map-anisotropy={16} clearcoat={1} clearcoatRoughness={0.15} roughness={0.3} metalness={0.5} /> | ||
</mesh> | ||
<mesh geometry={nodes.clip.geometry} material={materials.metal} material-roughness={0.3} /> | ||
<mesh geometry={nodes.clamp.geometry} material={materials.metal} /> | ||
</group> | ||
</RigidBody> | ||
</group> | ||
<mesh ref={band}> | ||
<meshLineGeometry /> | ||
<meshLineMaterial color="white" depthTest={false} resolution={[width, height]} useMap map={texture} repeat={[-3, 1]} lineWidth={1} /> | ||
</mesh> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import Link from "next/link"; | ||
|
||
export const MyExperience = () => { | ||
return ( | ||
<div className="h-full"> | ||
<section> | ||
<h2 className="mr-auto md:mr-0 text-3xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tighter leading-tight md:pr-8"> | ||
<span className="underline decoration-indigo-500"> | ||
About Me | ||
</span> | ||
</h2> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
Welcome to my personal website! I'm Justin Bender, a dedicated and passionate software developer based in the USA. With a robust background in software engineering, I have amassed experience across a spectrum of projects, from architecting full-stack applications to integrating cutting-edge technologies. | ||
</p> | ||
</section> | ||
|
||
<section> | ||
<h2 className="mr-auto md:mr-0 text-3xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tighter leading-tight md:pr-8"> | ||
<span className="underline decoration-indigo-500"> | ||
Professional Experience | ||
</span> | ||
</h2> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
Currently, I serve as a Software Engineer at Paperstac, where my responsibilities include building and maintaining multiple applications within a monorepo. I specialize in creating React components using Next.js, managing user login flows, account settings, and data visualization for our online marketplace. | ||
</p> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
Previously, my role at Bridge Discussion focused on product design and implementation, where I developed demos for funding presentations using a robust JavaScript stack featuring React/Next.js and integrated services like GCP and Firebase. | ||
</p> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
I also contributed as a Software Engineer at Cardano Goat, concentrating on developing WASM-integrated applications to seamlessly interact with the Cardano blockchain. My work prioritized enhancing user experience and incorporating open-source tools to maintain a competitive edge. | ||
</p> | ||
</section> | ||
|
||
<section> | ||
<h2 className="mr-auto md:mr-0 text-3xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tighter leading-tight md:pr-8"> | ||
<span className="underline decoration-indigo-500"> | ||
Freelance and Other Roles | ||
</span> | ||
</h2> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
In addition to my full-time positions, I have taken on roles as a Freelance Software Developer, leveraging tools such as Angular, React, Wix, and Google Firestore to build full-stack websites from initial design wireframes. My focus remains on optimizing performance and enriching user experience. | ||
</p> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
At Proxify, I addressed critical production challenges and optimized the Angular 5 frontend for efficient contract worker job matching. Earlier in my career at Therigy as a Junior Software Developer, I collaborated cross-functionally to develop web applications and enhance productivity through comprehensive testing suites. | ||
</p> | ||
</section> | ||
|
||
<section> | ||
<h2 className="mr-auto md:mr-0 text-3xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tighter leading-tight md:pr-8"> | ||
<span className="underline decoration-indigo-500"> | ||
Technical Skills | ||
</span> | ||
</h2> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
My technical proficiencies encompass a wide array of languages and frameworks, including JavaScript, TypeScript, Python, PHP, Go, and Rust. I am adept in front-end technologies such as React.js, Next.js, Angular, and state management with Redux. Additionally, I excel in backend development using Express.js and database management with MongoDB and SQL. | ||
</p> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
I am well-versed in cloud technologies like Docker, Kubernetes, AWS, Firebase, and Google Cloud, implementing CI/CD pipelines, GraphQL APIs, microservices, and serverless architectures. My toolkit also includes version control with Git, project management using JIRA, and proficiency in UI frameworks like TailwindCSS and Bootstrap. | ||
</p> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
Passionate about continuous learning, I explore emerging technologies and methodologies to enhance my skills and deliver innovative solutions. Outside of coding, I share insights on scripting and development through my blog at SomeScripting.com. | ||
</p> | ||
</section> | ||
|
||
<section> | ||
<h2 className="mr-auto md:mr-0 text-3xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tighter leading-tight md:pr-8"> | ||
<span className="underline decoration-indigo-500"> | ||
Contact | ||
</span> | ||
</h2> | ||
<p className="my-4 font-normal text-lg tracking-tighter leading-tight"> | ||
Thank you for visiting my website. Please feel free to connect with me on <Link href="https://www.linkedin.com/in/your-profile" target="_blank" rel="noopener noreferrer">LinkedIn</Link> or reach out via my socials. | ||
</p> | ||
</section> | ||
</div> | ||
); | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters