diff --git "a/Icon\r" "b/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index 2e2ab45..ab4d224 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,12 @@ -# 포트폴리오 사이트 만들기 프로젝트 +# 포트폴리오 -이 튜토리얼은 하나의 웹사이트를 여러 가지 프레임워크를 사용하여 만드는 방법에 대해 소개합니다. -웹 개발자들은 종종 다양한 프레임워크를 이용하여 작업하게 됩니다. -이 과정에서 여러 가지 프레임워크들을 어떻게 적용하는지 알아보고, -각 프레임워크들의 장단점을 비교 분석하며 학습하게 됩니다. - -1. [vite](https://github.com/webstoryboy/port2023-vite)를 이용하여 사이트를 제작합니다. -2. [react.js](https://github.com/webstoryboy/port2023-react)를 이용하여 사이트를 제작합니다. -3. [vue.js](https://github.com/webstoryboy/port2023-vue)를 이용하여 사이트를 제작합니다. -4. [next.js](https://github.com/webstoryboy/port2023-next)를 이용하여 사이트를 제작합니다. - -이 튜토리얼은 포트폴리오 컨셉의 사이트를 4가지 버전으로 반복하여 만들어 보면서, 프론트앤드 개발의 시발점이 될 수 있는 튜토리업입니다. -자바스크립트 프레임워크를 통해 사이트를 효율적으로 만들어 보는 방법을 익힙니다. -깊이 배우기 보다는 다양한 방법을 사용하여 흐름과 감각을 익히기 위한 튜토리얼입니다. - -## 완성작 보기 -미리보기 : +1. [react.js](https://github.com/mincholover/portpolio-react)를 이용하여 사이트를 제작합니다. ## 사용 스택 -- react(https://ko.legacy.reactjs.org/) 를 사용하여 사이트를 번들링하고 관리합니다. -- gsap(https://greensock.com/gsap) 를 이용하여 패럴랙스 효과를 줍니다. -- lenis(https://lenis.studiofreight.com/) 를 이용하여 스므스 효과를 구현합니다. -- netlify(https://www.netlify.com/) 를 통해 사이트를 배포합니다. -- git(https://github.com/) 을 사용하여 파일을 관리합니다. -- HTML, CSS 기반으로 웹사이트의 기본 레이아웃 설계하고, 웹 표준 및 웹 접근성을 준수하여 작업합니다. [ARIA(Accessible Rich Internet Applications)](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles) -## 프로젝트 실행 -- react를 설치합니다. `npx create-react-app 타이틀` -- react-router-dom을 설치합니다. `npm install react-router-dom` -- sass를 설치합니다. `npm install sass` -- gsap를 설치합니다. `npm install gsap` -- lenis를 설치합니다. `npm install @studio-freight/lenis` -출처: https://webstoryboy.co.kr/1934 [WEBSTORYBOY:티스토리] \ No newline at end of file +- react +- gsap +- lenis +- netlify +- git +- HTML, CSS diff --git a/package-lock.json b/package-lock.json index 497ec9f..733f765 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,10 +12,13 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "gsap": "^3.12.5", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-router-dom": "^6.24.0", "react-scripts": "5.0.1", "sass": "^1.77.6", + "styled-components": "^6.1.13", "web-vitals": "^2.1.4" } }, @@ -2301,6 +2304,27 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "license": "MIT" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -3322,6 +3346,14 @@ } } }, + "node_modules/@remix-run/router": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.17.0.tgz", + "integrity": "sha512-2D6XaHEVvkCn682XBnipbJjgZUU7xjLtA4dGJRBVUKpEaDYOZMENZoZjAOSb7qirxt5RupjzZxz4fK2FO+EFPw==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -4496,6 +4528,12 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "license": "MIT" + }, "node_modules/@types/testing-library__jest-dom": { "version": "5.14.9", "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", @@ -5970,6 +6008,15 @@ "node": ">= 6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -6397,6 +6444,15 @@ "postcss": "^8.4" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, "node_modules/css-declaration-sorter": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", @@ -6538,6 +6594,17 @@ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/css-tree": { "version": "1.0.0-alpha.37", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", @@ -9038,6 +9105,11 @@ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, + "node_modules/gsap": { + "version": "3.12.5", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.5.tgz", + "integrity": "sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==" + }, "node_modules/gzip-size": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", @@ -15013,6 +15085,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.24.0.tgz", + "integrity": "sha512-sQrgJ5bXk7vbcC4BxQxeNa5UmboFm35we1AFK0VvQaz9g0LzxEIuLOhHIoZ8rnu9BO21ishGeL9no1WB76W/eg==", + "dependencies": { + "@remix-run/router": "1.17.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.24.0.tgz", + "integrity": "sha512-960sKuau6/yEwS8e+NVEidYQb1hNjAYM327gjEyXlc6r3Skf2vtwuJ2l7lssdegD2YjoKG5l8MsVyeTDlVeY8g==", + "dependencies": { + "@remix-run/router": "1.17.0", + "react-router": "6.24.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", @@ -15898,6 +16000,12 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -16448,6 +16556,40 @@ "webpack": "^5.0.0" } }, + "node_modules/styled-components": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz", + "integrity": "sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw==", + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.38", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "license": "0BSD" + }, "node_modules/stylehacks": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", @@ -16463,6 +16605,12 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "license": "MIT" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", diff --git a/package.json b/package.json index 765c248..2f78958 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,13 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "gsap": "^3.12.5", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-router-dom": "^6.24.0", "react-scripts": "5.0.1", "sass": "^1.77.6", + "styled-components": "^6.1.13", "web-vitals": "^2.1.4" }, "scripts": { diff --git "a/portpolio/Icon\r" "b/portpolio/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..cdce03c --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/public/index.html b/public/index.html index efee300..ac3b6ce 100644 --- a/public/index.html +++ b/public/index.html @@ -4,12 +4,12 @@ - - 포트폴리오 사이트 만들기 😜 React-Site + + 포트폴리오 사이트 만들기 😇 React-Site
- + \ No newline at end of file diff --git a/src/App.js b/src/App.js index 9c96e9f..6e5a583 100644 --- a/src/App.js +++ b/src/App.js @@ -1,7 +1,22 @@ -import React from "react"; +import React, { useEffect } from "react"; +import {BrowserRouter, Route, Routes} from "react-router-dom"; +import HomeView from "./views/HomeView"; +import smooth from "./utils/smooth"; +import link from "./utils/link"; const App = () => { - return
App
; + useEffect(() => { + smooth(); + link(); + }, []); + + return ( + + + } /> + + + ); }; -export default App; +export default App; \ No newline at end of file diff --git a/src/assets/img/HomePage.png b/src/assets/img/HomePage.png new file mode 100644 index 0000000..0cb8daf Binary files /dev/null and b/src/assets/img/HomePage.png differ diff --git a/src/assets/img/about.jpg b/src/assets/img/about.jpg new file mode 100644 index 0000000..f5745ca Binary files /dev/null and b/src/assets/img/about.jpg differ diff --git a/src/assets/img/arrow.svg b/src/assets/img/arrow.svg new file mode 100644 index 0000000..6181b2c --- /dev/null +++ b/src/assets/img/arrow.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/assets/img/favicon.svg b/src/assets/img/favicon.svg new file mode 100644 index 0000000..6181b2c --- /dev/null +++ b/src/assets/img/favicon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/assets/img/port01.jpg b/src/assets/img/port01.jpg new file mode 100644 index 0000000..dfa2fa6 Binary files /dev/null and b/src/assets/img/port01.jpg differ diff --git a/src/assets/img/port02.jpg b/src/assets/img/port02.jpg new file mode 100644 index 0000000..4a5b415 Binary files /dev/null and b/src/assets/img/port02.jpg differ diff --git a/src/assets/img/port03.jpg b/src/assets/img/port03.jpg new file mode 100644 index 0000000..4901a76 Binary files /dev/null and b/src/assets/img/port03.jpg differ diff --git a/src/assets/img/port04.jpg b/src/assets/img/port04.jpg new file mode 100644 index 0000000..74a5ad7 Binary files /dev/null and b/src/assets/img/port04.jpg differ diff --git a/src/assets/img/port05.jpg b/src/assets/img/port05.jpg new file mode 100644 index 0000000..21ed22d Binary files /dev/null and b/src/assets/img/port05.jpg differ diff --git a/src/assets/img/port06.jpg b/src/assets/img/port06.jpg new file mode 100644 index 0000000..955961d Binary files /dev/null and b/src/assets/img/port06.jpg differ diff --git a/src/assets/img/port07.jpg b/src/assets/img/port07.jpg new file mode 100644 index 0000000..6854044 Binary files /dev/null and b/src/assets/img/port07.jpg differ diff --git a/src/assets/img/port08.jpg b/src/assets/img/port08.jpg new file mode 100644 index 0000000..0d68fde Binary files /dev/null and b/src/assets/img/port08.jpg differ diff --git a/src/assets/img/port09.jpg b/src/assets/img/port09.jpg new file mode 100644 index 0000000..dcfb78b Binary files /dev/null and b/src/assets/img/port09.jpg differ diff --git a/src/assets/img/port10.jpg b/src/assets/img/port10.jpg new file mode 100644 index 0000000..7ab126f Binary files /dev/null and b/src/assets/img/port10.jpg differ diff --git a/src/assets/scss/section/_contact.scss b/src/assets/scss/section/_contact.scss new file mode 100644 index 0000000..cfc1667 --- /dev/null +++ b/src/assets/scss/section/_contact.scss @@ -0,0 +1,127 @@ +#contact { + height: 100vh; +} +.contact__inner { + width: 100%; + height: 100%; + padding: 16px; + display: flex; + align-items: flex-start; + justify-content: flex-end; + flex-direction: column; + + @media (max-width: 800px){ + justify-content: center; + } + + .contact__title { + font-size: 10vw; + text-transform: uppercase; + line-height: 1; + font-weight: 800; + white-space: nowrap; + text-indent: -0.5vw; + letter-spacing: -0.3vw; + + @media (max-width: 800px){ + display: none; + } + } + .contact__text { + width: 100%; + height: 40vh; + background-color: var(--black); + color: var(--white); + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + position: relative; + + .text { + font-size: 3vw; + line-height: 1; + font-weight: 900; + text-transform: uppercase; + text-decoration: underline; + text-align: center; + position: relative; + z-index: 100; + transition: all 0.3s; + cursor: all-scroll; + + @media (max-width: 800px){ + font-size: 24px; + padding: 0 16px; + word-break: break-all; + } + } + } + .contact__lines { + width: 100%; + + .line { + display: block; + width: 100%; + height: 1px; + background-color: var(--black); + margin-bottom: 0.5vw; + + &:nth-child(1){ + height: 25px; + } + &:nth-child(2){ + height: 17px; + } + &:nth-child(3){ + height: 13px; + } + &:nth-child(4){ + height: 9px; + } + &:nth-child(5){ + height: 5px; + } + &:nth-child(6){ + height: 2px; + } + &:nth-child(7){ + height: 1px; + } + } + + &.top { + .line { + margin-top: 0.5vw; + margin-bottom: 0; + display: none; + + @media (max-width: 800px){ + display: block; + } + + &:nth-child(1){ + height: 1px; + } + &:nth-child(2){ + height: 2px; + } + &:nth-child(3){ + height: 5px; + } + &:nth-child(4){ + height: 9px; + } + &:nth-child(5){ + height: 13px; + } + &:nth-child(6){ + height: 17px; + } + &:nth-child(7){ + height: 25px; + } + } + } + } +} \ No newline at end of file diff --git a/src/assets/scss/section/_footer.scss b/src/assets/scss/section/_footer.scss new file mode 100644 index 0000000..e7daa86 --- /dev/null +++ b/src/assets/scss/section/_footer.scss @@ -0,0 +1,103 @@ +#footer { + font-family: var(--mainKor-font); +} +.footer__inner { + padding: 16px; + + .footer__text { + font-size: 12px; + text-transform: uppercase; + border-top: 1px solid var(--black); + border-bottom: 1px solid var(--black); + display: flex; + justify-content: space-between; + } + .footer__info { + display: flex; + justify-content: space-between; + margin: 100px 0; + + @media (max-width: 800px){ + flex-direction: column; + } + + .left { + width: 40%; + + @media (max-width: 800px){ + width: 100%; + } + + .title { + border-top: 2px solid var(--black); + border-bottom: 1px solid var(--black); + padding: 20px 0; + text-transform: uppercase; + font-weight: 700; + background: url(../../img/arrow.svg) no-repeat right 20px; + transition: all 0.3s; + + &:hover { + background-color: var(--black400); + padding-left: 10px; + border-color: transparent; + } + } + .desc { + font-size: 12px; + padding-top: 20px; + + @media (max-width: 800px){ + margin-bottom: 40px; + } + } + } + + .right { + width: 50%; + + @media (max-width: 800px){ + width: 100%; + } + + h3 { + border-top: 2px solid var(--black); + font-size: 10px; + margin-bottom: 40px; + padding-top: 10px; + } + ul { + border-top: 1px solid var(--black); + + li { + border-bottom: 1px solid var(--black); + + a { + padding: 14px 0; + font-size: 14px; + display: inline-block; + text-transform: uppercase; + } + em { + font-size: 12px; + padding-left: 10px; + opacity: 0; + transition: all 0.3s; + } + + &:hover { + em { + opacity: 1; + } + } + } + } + } + } + .footer__right { + text-align: center; + text-transform: uppercase; + font-size: 12px; + margin-bottom: 20px; + } +} \ No newline at end of file diff --git a/src/assets/scss/section/_header.scss b/src/assets/scss/section/_header.scss new file mode 100644 index 0000000..d95f788 --- /dev/null +++ b/src/assets/scss/section/_header.scss @@ -0,0 +1,129 @@ +#header { + @include position-fixed; + z-index: 10000; +} +.header__inner { + @include flex-between; + background-color: rgba(116, 99, 99, 0.1); + backdrop-filter: blur(15px); + padding: 1rem; + + .header__logo { + font-size: 0.9rem; + text-align: center; + text-transform: uppercase; + line-height: 1; + + em { + font-size: 10px; + display: block; + color: var(--black200); + } + } + + .header__nav { + + @media (max-width: 800px){ + display: none; + + &.show { + display: block; + + ul { + display: block; + position: absolute; + right: 0; + top: 68px; + background-color: rgba(116,99,99,0.1); + backdrop-filter: blur(15px); + z-index: 10000; + min-width: 150px; + padding: 20px 0; + + li { + display: block; + text-align: right; + + a { + display: inline-block; + padding: 10px; + } + } + } + } + &.show + .header__nav__mobile span::before { + width: 20px; + } + &.show + .header__nav__mobile span::after { + width: 20px; + } + } + + li { + display: inline; + + a { + text-transform: uppercase; + font-size: 14px; + padding: 14px; + position: relative; + + &::before { + content: ''; + width: calc(100% - 28px); + height: 1px; + background-color: var(--black); + position: absolute; + left: 14px; + bottom: 10px; + transform: scaleX(0); + transition: all 0.3s; + } + &:hover::before { + transform: scaleX(1); + } + } + } + } + + .header__nav__mobile { + display: none; + width: 40px; + height: 40px; + cursor: pointer; + + @media (max-width: 800px){ + display: block; + } + + span { + display: block; + width: 40px; + height: 2px; + background-color: var(--black); + margin-top: 19px; + position: relative; + + &::before { + content: ""; + width: 40px; + height: 2px; + background-color: var(--black); + position: absolute; + right: 0; + top: 6px; + transition: width 0.3s; + } + &::after { + content: ""; + width: 40px; + height: 2px; + background-color: var(--black); + position: absolute; + left: 0; + bottom: 6px; + transition: width 0.3s; + } + } + } +} \ No newline at end of file diff --git a/src/assets/scss/section/_intro.scss b/src/assets/scss/section/_intro.scss new file mode 100644 index 0000000..12c3caa --- /dev/null +++ b/src/assets/scss/section/_intro.scss @@ -0,0 +1,149 @@ +#intro { + height: 100vh; +} +.intro__inner { + width: 100%; + height: 100%; + display: flex; + align-items: flex-start; + justify-content: flex-end; + flex-direction: column; + padding: 16px; + + @media (max-width: 800px){ + justify-content: center; + } + + .intro__title { + font-size: 10vw; + text-transform: uppercase; + line-height: 1; + font-weight: 800; + white-space: nowrap; + text-indent: -0.5vw; + letter-spacing: -0.3vw; + + @media (max-width: 320px){ + display: none; + } + } + .intro__text { + width: 100%; + height: 40vh; + background-color: var(--black); + color: var(--white); + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + position: relative; + + .text { + font-size: 3vw; + line-height: 1; + font-weight: 900; + text-transform: uppercase; + text-decoration: underline; + text-align: center; + position: relative; + z-index: 100; + transition: all 0.3s; + cursor: all-scroll; + + @media (max-width: 800px){ + font-size: 24px; + } + } + .img { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + width: 30vh; + height: 30vh; + border-radius: 50%; + overflow: hidden; + filter: grayscale(100%); + transition: all 0.3s; + + @media (max-width: 320px){ + width: 20vh; + height: 20vh; + } + } + + &:hover .text { + opacity: 0; + } + &:hover .img { + filter: grayscale(0); + } + } + .intro__lines { + width: 100%; + + .line { + display: block; + width: 100%; + height: 1px; + background-color: var(--black); + margin-bottom: 0.5vw; + + &:nth-child(1){ + height: 1px; + } + &:nth-child(2){ + height: 2px; + } + &:nth-child(3){ + height: 5px; + } + &:nth-child(4){ + height: 9px; + } + &:nth-child(5){ + height: 13px; + } + &:nth-child(6){ + height: 17px; + } + &:nth-child(7){ + height: 25px; + } + } + + &.bottom { + .line { + margin-top: 0.5vw; + margin-bottom: 0; + display: none; + + @media (max-width: 800px){ + display: block; + } + + &:nth-child(1){ + height: 25px; + } + &:nth-child(2){ + height: 17px; + } + &:nth-child(3){ + height: 13px; + } + &:nth-child(4){ + height: 9px; + } + &:nth-child(5){ + height: 5px; + } + &:nth-child(6){ + height: 2px; + } + &:nth-child(7){ + height: 1px; + } + } + } + } +} \ No newline at end of file diff --git a/src/assets/scss/section/_port.scss b/src/assets/scss/section/_port.scss new file mode 100644 index 0000000..1799f6c --- /dev/null +++ b/src/assets/scss/section/_port.scss @@ -0,0 +1,120 @@ +#port { + width: 100%; + margin-top: 30vh; + // overflow: hidden; +} +.port__inner { + padding: 16px; + + .port__title { + width: 100%; + height: 5vw; + font-size: 4vw; + font-weight: 900; + line-height: 1.6; + font-family: var(--mainKor-font); + text-transform: uppercase; + color: var(--black100); + border-bottom: 0.4vw solid var(--black100); + margin-bottom: 16px; + text-indent: -0.26vw; + + em { + font-size: 1.25rem; + font-weight: 400; + line-height: 2; + } + } + .port__wrap { + display: flex; + flex-wrap: wrap; + width: 7000px; + + .port__item { + width: 500px; + height: 70vh; + background-color: var(--subBg100); + padding: 2.5rem; + margin-right: 20px; + + &.p1 { + background-color: var(--subBg100); + } + &.p2 { + background-color: var(--subBg200); + } + &.p3 { + background-color: var(--subBg300); + } + &.p4 { + background-color: var(--subBg400); + } + &.p5 { + background-color: var(--subBg500); + } + &.p6 { + background-color: var(--subBg100); + } + &.p7 { + background-color: var(--subBg200); + } + &.p8 { + background-color: var(--subBg300); + } + &.p9 { + background-color: var(--subBg400); + } + &.p10 { + background-color: var(--subBg500); + } + .num { + font-size: 2rem; + font-family: var(--mainNum-font); + } + .img { + display: block; + margin-top: -20px; + transition: margin-top 0.3s; + + img { + border-radius: 5px; + filter: saturate(0%); + transition: all 0.3s; + } + + &:hover { + margin-top: 0; + + img { + filter: saturate(100%); + } + } + } + .title { + font-size: 1.5rem; + text-align: center; + padding: 0.8rem 0; + font-weight: 700; + color: var(--black100); + border-bottom: 2px solid var(--black100); + margin-bottom: 1rem; + } + .desc { + font-size: 1rem; + } + .site { + border: 1px solid var(--black100); + display: block; + text-align: center; + padding: 0.625rem 1.5rem; + margin-top: 1.5rem; + transition: all 0.2s; + + &:hover { + background-color: var(--black100); + color: var(--white); + } + } + } + } +} \ No newline at end of file diff --git a/src/assets/scss/section/_site.scss b/src/assets/scss/section/_site.scss new file mode 100644 index 0000000..40d3a96 --- /dev/null +++ b/src/assets/scss/section/_site.scss @@ -0,0 +1,152 @@ +.site__inner { + padding: 16px; + + .site__title { + position: sticky; + top: 70px; + left: 0; + width: 70%; + height: 5vw; + font-size: 4vw; + font-weight: 900; + line-height: 1.6; + font-family: var(--mainKor-font); + text-transform: uppercase; + color: var(--black100); + border-bottom: 0.4vw solid var(--black100); + margin-bottom: 100px; + + @media (max-width: 800px){ + width: 100%; + margin-bottom: 10vw; + font-size: 30px; + height: auto; + top: 68px; + z-index: 1000; + background-color: var(--mainBg-color); + } + + em { + font-size: 1.25rem; + font-weight: 400; + line-height: 2; + } + } + .site__wrap { + .site__item { + height: 70vh; + @include flex-center; + flex-direction: column; + position: sticky; + left: 0; + + &.s1 { + background-color: var(--subBg100); + top: 180px; + + @media (max-width: 800px){ + top: 140px; + } + } + &.s2 { + background-color: var(--subBg200); + top: 200px; + + @media (max-width: 800px){ + top: 160px; + } + } + &.s3 { + background-color: var(--subBg300); + top: 220px; + + @media (max-width: 800px){ + top: 180px; + } + } + &.s4 { + background-color: var(--subBg400); + top: 240px; + + @media (max-width: 800px){ + top: 200px; + } + } + .num { + font-size: 5vw; + line-height: 1; + font-weight: 900; + font-family: var(--mainNum-font); + position: absolute; + left: 1vw; + top: 1vw; + + @media (max-width: 800px){ + font-size: 80px; + left: 20px; + top: 20px; + } + } + .text { + text-align: center; + margin-bottom: 1rem; + + > div { + font-size: 3vw; + line-height: 1; + font-weight: 900; + text-transform: uppercase; + text-decoration: underline; + font-family: var(--mainEng-font); + + @media (max-width: 800px){ + font-size: 26px; + } + } + } + .title { + font-family: var(--mainKor-font); + margin-bottom: 1rem; + } + .btn { + a { + text-decoration: underline; + text-transform: uppercase; + color: var(--black200); + font-size: 1rem; + transition: all 0.3s; + margin: 0 2px; + + &:hover { + color: var(--black); + } + } + } + .info { + position: absolute; + left: 0; + bottom: 3%; + width: 98%; + margin-left: 1%; + border-top: 1px solid var(--black); + border-bottom: 1px solid var(--black); + display: flex; + justify-content: space-between; + + @media (max-width: 800px){ + flex-direction: column; + width: 90%; + margin-left: 5%; + padding: 5px 0; + } + + span { + font-family: var(--mainKor-font); + font-size: 12px; + padding: 3px 0; + text-transform: uppercase; + } + } + } + } +} \ No newline at end of file diff --git a/src/assets/scss/section/_skill.scss b/src/assets/scss/section/_skill.scss new file mode 100644 index 0000000..c89a35b --- /dev/null +++ b/src/assets/scss/section/_skill.scss @@ -0,0 +1,68 @@ +.slkll__inner { + padding: 16px; + display: flex; + justify-content: space-between; + + @media (max-width: 800px){ + flex-direction: column; + } + + .skill__title { + position: sticky; + top: 70px; + left: 0; + width: 48%; + height: 5vw; + font-size: 4vw; + font-weight: 900; + line-height: 1.6; + font-family: var(--mainKor-font); + text-transform: uppercase; + color: var(--black100); + border-bottom: 0.4vw solid var(--black100); + + @media (max-width: 800px){ + width: 100%; + margin-bottom: 10vw; + font-size: 30px; + height: auto; + top: 68px; + background-color: var(--mainBg-color); + } + + em { + font-size: 1.25rem; + font-weight: 400; + line-height: 2; + } + } + .skill__desc { + width: 50%; + + @media (max-width: 800px){ + width: 100%; + } + + span { + font-size: 5vw; + line-height: 1; + font-weight: 900; + line-height: 1.3; + font-family: var(--mainNum-font); + + @media (max-width: 800px){ + font-size: 20vw; + } + } + h3 { + font-size: 1.5rem; + text-decoration: underline; + text-underline-position: under; + margin-bottom: 1vw; + } + p { + margin-bottom: 30vh; + font-size: 1.1rem; + } + } +} \ No newline at end of file diff --git a/src/assets/scss/setting/_fonts.scss b/src/assets/scss/setting/_fonts.scss new file mode 100644 index 0000000..5f5ad3b --- /dev/null +++ b/src/assets/scss/setting/_fonts.scss @@ -0,0 +1,13 @@ +@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;400;500;600;700;800;900&display=swap"); +@import url("https://websfont.github.io/nanumSquareNeo/nanumSquareNeo.css"); +@import url("https://websfont.github.io/gmarket/gmarket.css"); + +.mont { + font-family: "Montserrat"; +} +.nanum { + font-family: "nanumSquareNeo"; +} +.gmarket { + font-family: "gmarket"; +} \ No newline at end of file diff --git a/src/assets/scss/setting/_mixin.scss b/src/assets/scss/setting/_mixin.scss new file mode 100644 index 0000000..f121894 --- /dev/null +++ b/src/assets/scss/setting/_mixin.scss @@ -0,0 +1,29 @@ +// 가운데 정렬 +@mixin flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +// 양쪽 정렬 +@mixin flex-between { + display: flex; + align-items: center; + justify-content: space-between; +} + +// 중앙 정렬 +@mixin position-center { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} + +// 상단 고정 +@mixin position-fixed { + position: fixed; + left: 0; + top: 0; + width: 100%; +} \ No newline at end of file diff --git a/src/assets/scss/setting/_reset.scss b/src/assets/scss/setting/_reset.scss new file mode 100644 index 0000000..2602986 --- /dev/null +++ b/src/assets/scss/setting/_reset.scss @@ -0,0 +1,101 @@ +// border-box 초기화 +*, +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +// 공백 초기화 +body, +button, +dd, +dl, +dt, +fieldset, +form, +h1, +h2, +h3, +h4, +h5, +h6, +input, +legend, +li, +ol, +p, +select, +table, +td, +textarea, +th, +ul, +figure, +figcaption { + margin: 0; + padding: 0; +} + +// 폰트 초기화 +body, +button, +input, +select, +table, +textarea { + font-family: var(--mainEng-font), var(--mainKor-font), "Apple SD Gothic Neo", "Malgun Gothic", "맑은 고딕", helvetica, sans-serif; +} + +// 링크 초기화 +a, +a:hover, +a:focus { +color: inherit; + text-decoration: none; +} + +// 스타일 초기화 +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: normal; +} + +ul { + list-style: none; +} + +em, +address { + font-style: normal; +} + +strong { + font-weight: normal; +} + +img { + vertical-align: top; + width: 100%; +} + +// 스킵메뉴 +#skip a { + position: absolute; + left: 10px; + top: -92px; + z-index: 100000; + font-size: 1rem; + padding: 10px 30px; + color: var(--white); + background: var(--black); +} +#skip a:focus, +#skip a:active { + top: 10px; +} \ No newline at end of file diff --git a/src/assets/scss/setting/_vars.scss b/src/assets/scss/setting/_vars.scss new file mode 100644 index 0000000..7b36b89 --- /dev/null +++ b/src/assets/scss/setting/_vars.scss @@ -0,0 +1,39 @@ +:root { + --mainEng-font: "Montserrat"; + --mainKor-font: "nanumSquareNeo"; + --mainNum-font: "gmarket"; + + --mainBg-color: #f3ede8; + --subBg100: #cdc0b1; + --subBg200: #afa395; + --subBg300: #81887c; + --subBg400: #afa7a2; + --subBg500: #a6afa2; + + --white: #fff; + --black: #000; + --black100: #2b2b2b; + --black200: #434343; + --black300: #686868; + --black400: #e0e0e0; + + font-family: var(--mainEng-font), var(--mainKor-font); + font-size: 16px; + line-height: 1.5; + font-weight: 400; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; + + @media (max-width: 800px) { + font-size: 14px; + line-height: 1.4; + } +} + +body { + background-color: var(--mainBg-color); +} \ No newline at end of file diff --git a/src/assets/scss/style.scss b/src/assets/scss/style.scss new file mode 100644 index 0000000..2e426af --- /dev/null +++ b/src/assets/scss/style.scss @@ -0,0 +1,16 @@ +@charset "UTF-8"; + +// setting +@import "setting/fonts"; +@import "setting/vars"; +@import "setting/reset"; +@import "setting/mixin"; + +// section +@import "section/header"; +@import "section/intro"; +@import "section/skill"; +@import "section/site"; +@import "section/port"; +@import "section/contact"; +@import "section/footer"; \ No newline at end of file diff --git a/src/components/Contact.jsx b/src/components/Contact.jsx new file mode 100644 index 0000000..7034415 --- /dev/null +++ b/src/components/Contact.jsx @@ -0,0 +1,49 @@ +import React from "react"; + +import { contactText } from "../constants"; + +const Contact = () => { + return ( +
+
+

Contact

+ +
+
+ {contactText.map((contact, key) => ( +
+ + {contact.title} + +
+ ))} + +
+
+ +
+
+ ) +} + +export default Contact \ No newline at end of file diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx new file mode 100644 index 0000000..1d91da2 --- /dev/null +++ b/src/components/Footer.jsx @@ -0,0 +1,42 @@ +import React from "react"; + +import { footerText } from "../constants"; + +const Footer = () => { + return ( + + ) +} + +export default Footer; \ No newline at end of file diff --git a/src/components/Header.jsx b/src/components/Header.jsx new file mode 100644 index 0000000..a19edf5 --- /dev/null +++ b/src/components/Header.jsx @@ -0,0 +1,49 @@ +import React, { useState } from "react"; + +import { headerNav } from "../constants"; + +const Header = () => { + const [show, setShow] = useState(false); + + const toggleMenu = () => { + setShow((prevShow) => !prevShow); + } + + return ( + + ) +} + +export default Header; \ No newline at end of file diff --git a/src/components/Intro.jsx b/src/components/Intro.jsx new file mode 100644 index 0000000..58d253d --- /dev/null +++ b/src/components/Intro.jsx @@ -0,0 +1,47 @@ +import React from "react"; + +import about from "../assets/img/about.jpg"; + +import { introText } from "../constants"; + +const Intro = () => { + return ( +
+
+

+ {introText.title} +

+ +
+
+
{introText.desc[0]}
+
{introText.desc[1]}
+
{introText.desc[2]}
+
+
+ 어바웃미 +
+
+ +
+
+ ) +} + +export default Intro; \ No newline at end of file diff --git a/src/components/Main.jsx b/src/components/Main.jsx new file mode 100644 index 0000000..ec8dc84 --- /dev/null +++ b/src/components/Main.jsx @@ -0,0 +1,11 @@ +import React from 'react' + +const Main = ({ children }) => { + return ( +
+ { children } +
+ ) +} + +export default Main \ No newline at end of file diff --git a/src/components/Port.jsx b/src/components/Port.jsx new file mode 100644 index 0000000..d5837f8 --- /dev/null +++ b/src/components/Port.jsx @@ -0,0 +1,76 @@ +import React, { useEffect, useRef } from "react"; + +import { portText } from "../constants"; +import { gsap } from "gsap"; +import { ScrollTrigger } from "gsap/ScrollTrigger"; + +const Port = () => { + const horizontalRef = useRef(null); + const sectionRef = useRef([]); + + useEffect(() => { + gsap.registerPlugin(ScrollTrigger); + + const horizontal = horizontalRef.current; + const sections = sectionRef.current; + + let scrollTween = gsap.to(sections, { + xPercent: -120 * (sections.length - 1), + ease: "none", + scrollTrigger: { + trigger: horizontal, + start: "top 56px", + end: () => "+=" + horizontal.offsetWidth, + pin: true, + scrub: 1, + markers: false, + invalidateOnRefresh: true, + anticipatePin: 1, + } + }) + + return () => { + scrollTween.kill(); + }; + }, []); + + return ( +
+
+

+ portfolio 포폴 작업물 +

+
+ {portText.map((port, key) => ( + + ))} +
+
+
+ ) +} + +export default Port; \ No newline at end of file diff --git a/src/components/Site.jsx b/src/components/Site.jsx new file mode 100644 index 0000000..1f5c609 --- /dev/null +++ b/src/components/Site.jsx @@ -0,0 +1,41 @@ +import React from "react"; + +import { siteText } from "../constants"; + +const Site = () => { + return ( +
+
+

+ Site Product 프로덕트 들 +

+
+ {siteText.map((site, key) => ( +
+ {key+1}. +
+
{site.text[0]}
+
{site.text[1]}
+
{site.text[2]}
+
+

+ {site.title} +

+
+ code + view +
+
+ {site.info[0]} + {site.info[1]} + {site.info[2]} +
+
+ ))} +
+
+
+ ) +} + +export default Site; \ No newline at end of file diff --git a/src/components/Skill.jsx b/src/components/Skill.jsx new file mode 100644 index 0000000..2e2e169 --- /dev/null +++ b/src/components/Skill.jsx @@ -0,0 +1,26 @@ +import React from "react"; + +import { skillText } from "../constants"; + +const Skill = () => { + return ( +
+
+

+ challenge 나의 도전 +

+
+ {skillText.map((skill, key) => ( +
+ {key+1}. +

{skill.title}

+

{skill.desc}

+
+ ))} +
+
+
+ ) +} + +export default Skill; \ No newline at end of file diff --git a/src/components/Skip.jsx b/src/components/Skip.jsx new file mode 100644 index 0000000..41f9a73 --- /dev/null +++ b/src/components/Skip.jsx @@ -0,0 +1,17 @@ +import React from "react"; + +const Skip = () => { + return ( + + ) +} + +export default Skip; \ No newline at end of file diff --git a/src/constants/index.js b/src/constants/index.js new file mode 100644 index 0000000..e249f8f --- /dev/null +++ b/src/constants/index.js @@ -0,0 +1,239 @@ +import port01 from "../assets/img/HomePage.png"; +import port02 from "../assets/img/port02.jpg"; +import port03 from "../assets/img/port03.jpg"; +import port04 from "../assets/img/port04.jpg"; +import port05 from "../assets/img/port05.jpg"; +import port06 from "../assets/img/port06.jpg"; +import port07 from "../assets/img/port07.jpg"; +import port08 from "../assets/img/port08.jpg"; +import port09 from "../assets/img/port09.jpg"; +import port10 from "../assets/img/port10.jpg"; + +export const headerNav = [ + { + title: "intro", + url: "#intro" + }, + { + title: "skill", + url: "#skill" + }, + { + title: "site", + url: "#site" + }, + { + title: "portfolio", + url: "#port" + }, + { + title: "contact", + url: "#contact" + } +]; + +export const introText = { + title: "port developer", + desc: ["talent is", "found at the end of the", "effort"] +} + +export const skillText = [ + { + title: "코드로 가치를 창출하는 개발자", + desc: "문제 해결에 있어 효율적인 접근 방식을 항상 추구하며, 기술을 시도하고 연구하는 데 끝없이 달려갑니다.", + }, + { + title: "올바른 협업으로 완성도 높은 프로덕트를 창출합니다", + desc: "개인의 하드 스킬에 의존하기보다, 협업에서의 소프트 스킬을 키우며 성장하는 개발자를 추구합니다." + }, + { + title: "꾸준함의 가치를 소중히 여기는 개발자", + desc: "꾸준함은 곧 성장의 발판입니다. 하루하루 쌓이는 작은 진전이 미래의 혁신을 만들어냅니다." + } +] + +export const siteText = [ + { + text: ["We can", "Dream with", "Wecand:"], + title: "공모전 매칭 웹 사이트", + code: "https://github.com/Club-PARD/GemLense-FE.git", + view: "https://wecand.site", + + info: [ + "site coding", + "production period : seven days", + "use stack : HTML5/CSS3, styled-components, React, FireBase, MySQL, javaspring", + ], + }, + { + text: ["My", "instagram", "profile"], + title: "나의 인스타그램 프로필", + view: "https://www.instagram.com/minzzhan/", + info: [ + + ], + }, + { + text: ["NAVER", "blog", "ilsang"], + title: "블로그", + code: "https://blog.naver.com/lolgrow8", + view: "https://blog.naver.com/lolgrow8", + info: [ + "blog", + + "use hand, computer, phone", + ], + }, + { + text: ["to", "be", "continue.."], + title: "업데이트 예정", + code: "", + view: "", + info: [ + + ], + }, +]; + +export const portText = [ + { + num: "01", + title: "We can Dream with Wecand:", + desc: "이 사이트는 대학생들이 모르는 사람과 함께 공모전을 나가고자 할 때, 서로의 하드 스킬이나 소프트 스킬을 미리 알 수 있게 해주는 사이트입니다.", + img: port01, + code: "https://github.com/Club-PARD/GemLense-FE.git", + view: "https://wecand.site", + name: "김상* 포트폴리오", + }, + { + num: "02", + title: "빛나는 밤에 포트폴리오", + desc: "이 사이트는 정말 인상적인 포트폴리오입니다. 특히 스무스한 효과와 가로 모드드 높은 퀄리티를 자랑합니다. 디테일과 꼼꼼함이 넘치는 포트폴리오는 개발자의 뛰어난 능력을 엿볼 수 있습니다. GSAP와 React.js를 이용하여 사이트를 표현한 것은 기술적인 능력과 창의성을 강조하는데, 부족함이 없으며, 세심한 코딩과 디테일한 작업으로 그의 개발 감각과 능력이 빛을 발휘한 것 같습니다. ", + img: port02, + code: "https://github.com/kimsangjunv1/-React-Portfolio", + view: "https://portfolio-313.web.app/", + name: "천설* 포트폴리오", + }, + { + num: "03", + title: "열정이 넘치는 포트폴리오", + desc: "이 사이트는 정말 인상적인 포트폴리오입니다. 특히 스무스한 효과와 가로 모드드 높은 퀄리티를 자랑합니다. 디테일과 꼼꼼함이 넘치는 포트폴리오는 개발자의 뛰어난 능력을 엿볼 수 있습니다. GSAP와 React.js를 이용하여 사이트를 표현한 것은 기술적인 능력과 창의성을 강조하는데, 부족함이 없으며, 세심한 코딩과 디테일한 작업으로 그의 개발 감각과 능력이 빛을 발휘한 것 같습니다. ", + img: port03, + code: "https://github.com/seolhee313/PORTFOLIO-REACT", + view: "https://portfolio-313.web.app/", + name: "천설* 포트폴리오", + }, + { + num: "04", + title: "모던한 포트폴리오", + desc: "블랙 컨셉과 애니메이션이 돋보이는 포트폴리오 사이트입니다. GSAP를 통한 애니메이션과 NEXT.js를 통해 제작된 포트폴리오입니다. pin 애니메이션을 통한 포폴 작업물의 표현 능력이 돋보이는 사이트입니다.", + img: port04, + code: "https://github.com/dlgnsrb227/portfolio-next", + view: "https://hoongportfolio-next.netlify.app/", + name: "이훈* 포트폴리오", + }, + { + num: "05", + title: "가로모드의 정석 포트폴리오", + desc: "이 포트폴리오는 가로모드를 통해 눈에 띄는 애니메이션 효과를 가진 멋진 작품들이 펼쳐집니다. 세션 간의 부드러운 전환과 흥미로운 움직임이 사용자들에게 색다른 경험을 선사합니다. 사이트에는 탁월한 디자인과 창의적인 애니메이션들이 어우러져, 사용자들에게 인상적인 시각적인 효과를 줍니다. 애니메이션은 적절히 사용되어 사이트를 더욱 생동감 있게 만들어주는 포트폴리오입니다.", + img: port05, + code: "/", + view: "https://junseungpark.github.io/portfolio/index3.html", + name: "박준* 포트폴리오", + }, + { + num: "06", + title: "화려함의 정석 포트폴리오", + desc: "화려하고 세련된 디자인과 다채로운 색상이 사용된 포트폴리오는 사용자를 홀릴 듯한 시각적인 매력을 지니고 있습니다. 포트폴리오 내의 각 작품들은 디테일한 디자인과 탁월한 시각적 표현력을 갖추고 있어, 주인공의 뛰어난 예술적 감각을 느낄 수 있습니다. 화려한 애니메이션 효과와 부드러운 전환은 사이트를 더욱 생동감 있게 만들어주며, 사용자들에게 색다른 경험을 선사합니다.", + img: port06, + code: "/", + view: "https://webstoryboy.github.io/port2023/portfolio-student/DavidYang/index.html", + name: "포트폴리오", + }, + { + num: "07", + title: "패럴랙스 정석 포트폴리오", + desc: "마치 예술작품을 감상하는 듯한 환상적인 경험을 선사하는 포트폴리오입니다. 패럴랙스 스크롤링을 활용하여 구성된 사이트는 사용자들에게 독특하고 멋진 시각적 효과를 제공합니다. 배경과 움직이는 요소들이 조화롭게 어우러져, 사이트 전반에 걸쳐 깊이와 입체감을 느낄 수 있습니다. 스크롤에 따라 움직이는 요소들은 마치 세계를 탐험하는 듯한 느낌을 주며, 사용자들을 끌어들이는 매력적인 요소로 작용합니다.", + img: port07, + code: "/", + view: "https://webstoryboy.github.io/port2023/portfolio-student/TaeyongLee/index.html", + name: "포트폴리오", + }, + { + num: "08", + title: "트랜지션 포트폴리오", + desc: "화면 전환과 요소들의 흐름이 순조롭고 매끄러운 작품들로 가득한 포트폴리오 사이트입니다. 페이지 간의 트랜지션은 마치 이야기를 풀어내는 듯한 흥미진진한 경험을 선사합니다. 트랜지션 효과의 적절한 활용은 작품들을 보다 동적이고 생동감 있게 만들어줍니다. 각 페이지의 이동이 자연스럽고 사용자들이 원활하게 사이트를 탐색할 수 있도록 배려된 구성은 개발자의 디자인 능력을 잘 보여주는 특징입니다.", + img: port08, + code: "/", + view: "https://webstoryboy.github.io/port2023/portfolio-student/HyunroKim/index.html", + name: "포트폴리오", + }, + { + num: "09", + title: "스크롤의 정석 포트폴리오", + desc: "스크롤링을 활용하여 훌륭한 사용자 경험을 선사하는 포트폴리오 사이트입니다. 스크롤을 내리면서 작품들이 순차적으로 나타나고 효과적으로 전환되는 것은 마치 예술적인 이야기를 읽어나가는 듯한 느낌을 주며 사용자를 매료시킵니다. 스크롤의 움직임을 통해 작품들이 서서히 드러나고, 각 페이지 간의 전환은 자연스럽고 부드럽습니다. 이러한 트랜지션과 애니메이션들이 작품들의 내용과 테마를 더욱 강조해줍니다.", + img: port09, + code: "/", + view: "https://webstoryboy.github.io/port2023/portfolio-student/ChoJaeHyung/index.html", + name: "포트폴리오", + }, + { + num: "10", + title: "모던함의 정석 포트폴리오", + desc: "현대적이고 세련된 디자인으로 가득한 포트폴리오 사이트입니다. 모던한 느낌과 세심한 디테일이 조화를 이루며, 사용자에게 신선하고 품격 있는 경험을 제공합니다. 사이트의 디자인은 깔끔하고 단정하면서도 특유의 감성과 풍부한 표현력이 느껴집니다. 간결한 레이아웃과 모던한 색상 선택은 주인공의 디자인 감각을 잘 보여주는 특징입니다.", + img: port10, + code: "/", + view: "https://webstoryboy.github.io/port2023/portfolio-student/JooHyeji/index.html", + name: "포트폴리오", + }, +]; + +export const contactText = [ + { + link: "", + title: "KAKAO : lolgrow", + }, + { + link: "mailto: lolgrow8@naver.com", + title: "mail : lolgrow8@naver.com", + }, +]; + +export const footerText = [ + { + title: "youtube 없습니다.", + desc: "유튜브는 없습니다.", + + }, + { + title: "github", + desc: "깃헙에 오시면 더 많은 소스를 볼 수 있습니다.", + link: "https://github.com/MinchoLover", + }, + { + title: "blog", + desc: "블로그에 오시면 더 많은 정보를 볼 수 있습니다.", + link: "https://blog.naver.com/lolgrow8", + }, + { + title: "react-webstoryboy", + desc: "리액트로 만든 사이트를 같이 만들어 봅니다.", + link: "https://github.com/webstoryboy/port2023-react", + }, + { + title: "vue-webstoryboy", + desc: "뷰로 만든 사이트를 같이 만들어 봅니다.", + link: "https://github.com/webstoryboy/port2023-vue", + }, + { + title: "next-webstoryboy", + desc: "넥스트로 만든 사이트를 같이 만들어 봅니다.", + link: "https://github.com/webstoryboy/port2023-next", + }, + { + title: "instagram", + desc: "인스타그램", + link: "https://www.instagram.com/minzzhan/", + + }, +]; \ No newline at end of file diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..0d7bcbf --- /dev/null +++ b/src/index.html @@ -0,0 +1,451 @@ + + + + + + + + 포트폴리오 사이트 만들기 😇 React-Site + + + + + + + + + + + +
+
+
+

+ port developer +

+ +
+
+
talent is
+
found at the end of the
+
effort
+
+
+ 어바웃 +
+
+ +
+
+ + +
+
+

Challenge 나의 도전

+
+
+ 1. +

+

+ +

+
+
+ 2. +

+

+ +

+
+
+ 3. +

+

+ +

+
+
+
+
+ + +
+
+

Site hobby 나의 취미

+
+
+ 1. +
+
Make
+
site compliant with
+
react
+
+

웹 표준을 준수한 사이트 제작

+
+ code + view +
+
+ site coding + production period : two days + use stack : html5/css3, CSS Variable, Vite +
+
+
+ 2. +
+
Make
+
site compliant with
+
react.js
+
+

리액트를 이용한 사이트 제작

+
+ code + view +
+
+ site coding + production period : two days + use stack : HTML5/CSS3, CSS Variable, Vite +
+
+
+ 3. +
+
Make
+
site compliant with
+
vue.js
+
+

뷰를 이용한 사이트 제작

+
+ code + view +
+
+ site coding + production period : two days + use stack : vue.js, CSS Variable, vite +
+
+
+ 4. +
+
Make
+
site compliant with
+
next.js
+
+

넥스트를 이용한 사이트 제작

+
+ code + view +
+
+ site coding + production period : two days + use stack : next.js, CSS Variable, Vite +
+
+
+
+
+ + +
+
+
+ portfolio 포폴 작업물 +
+
+
+ 01. + + 김상준 포트폴리오 + +

어워드에도 올라간 포트폴리오

+

+ 라마 디자인을 통해 자신의 스킬을 가장 멋지게 표현한 포트폴리오입니다. + 가로 모드와 세로 모드는 매우 인상적이며 특히 리액트와 비트를 이용하여 제작한 것은 더욱 놀랍습니다. + 이 사이트는 awwwards.com에도 인정받아 올라간 포트폴리오입니다. + 확실히 그의 뛰어난 디자인 스킬과 기술력이 빛을 발휘한 결과물인 것 같습니다. +

+ 사이트 보기 +
+
+ 02. + + 천설희 포트폴리오 + +

빛나는 밤에 포트폴리오

+

+ 이 사이트는 정말 인상적인 포트폴리오입니다. + 특히 스무스한 효과와 가로 모드드 높은 퀄리티를 자랑합니다. + 디테일과 꼼꼼함이 넘치는 포트폴리오는 개발자의 뛰어난 능력을 엿볼 수 있습니다. + GSAP와 React.js를 이용하여 사이트를 표현한 것은 기술적인 능력과 창의성을 강조하는데, 부족함이 없으며, + 세심한 코딩과 디테일한 작업으로 그의 개발 감각과 능력이 빛을 발휘한 것 같습니다. +

+ 사이트 보기 +
+
+ 03. + + 여다슬 포트폴리오 + +

열정이 넘치는 포트폴리오

+

+ 깔끔하고 발랄한 느낌이 묻어나는 장난꾸러기 같은 사이트입니다. + 배치와 색상 선택이 조화롭고 사용자를 환영하는 분위기를 조성하고 있습니다. + 또한, 가로 모드에서의 디자인도 매우 멋집니다. + GSAP와 React.js를 이용한 부드러운 효과들이 사이트에서 눈에 띄며, 페이지 전환과 요소의 움직임이 매끄러운 포트폴리오입니다. +

+ 사이트 보기 +
+
+ 04. + + 이훈규 포트폴리오 + +

모던한 포트폴리오

+

+ 블랙 컨셉과 애니메이션이 돋보이는 포트폴리오 사이트입니다. + GSAP를 통한 애니메이션과 NEXT.js를 통해 제작된 포트폴리오입니다. + pin 애니메이션을 통한 포폴 작업물의 표현 능력이 돋보이는 사이트입니다. +

+ 사이트 보기 +
+
+ 05. + + 박준승 포트폴리오 + +

가로모드의 정석 포트폴리오

+

+ 이 포트폴리오는 가로모드를 통해 눈에 띄는 애니메이션 효과를 가진 멋진 작품들이 펼쳐집니다. + 세션 간의 부드러운 전환과 흥미로운 움직임이 사용자들에게 색다른 경험을 선사합니다. + 사이트에는 탁월한 디자인과 창의적인 애니메이션들이 어우러져, 사용자들에게 인상적인 시각적인 효과를 줍니다. + 애니메이션은 적절히 사용되어 사이트를 더욱 생동감 있게 만들어주는 포트폴리오입니다. +

+ 사이트 보기 +
+
+ 06. + + 포트폴리오 + +

화려함의 정석 포트폴리오

+

+ 화려하고 세련된 디자인과 다채로운 색상이 사용된 포트폴리오는 사용자를 홀릴 듯한 시각적인 매력을 지니고 있습니다. + 포트폴리오 내의 각 작품들은 디테일한 디자인과 탁월한 시각적 표현력을 갖추고 있어, 주인공의 뛰어난 예술적 감각을 느낄 수 있습니다. + 화려한 애니메이션 효과와 부드러운 전환은 사이트를 더욱 생동감 있게 만들어주며, 사용자들에게 색다른 경험을 선사합니다. +

+ 사이트 보기 +
+
+ 07. + + 포트폴리오 + +

패럴랙스 정석 포트폴리오

+

+ 마치 예술작품을 감상하는 듯한 환상적인 경험을 선사하는 포트폴리오입니다. + 패럴랙스 스크롤링을 활용하여 구성된 사이트는 사용자들에게 독특하고 멋진 시각적 효과를 제공합니다. + 배경과 움직이는 요소들이 조화롭게 어우러져, 사이트 전반에 걸쳐 깊이와 입체감을 느낄 수 있습니다. + 스크롤에 따라 움직이는 요소들은 마치 세계를 탐험하는 듯한 느낌을 주며, 사용자들을 끌어들이는 매력적인 요소로 작용합니다. +

+ 사이트 보기 +
+
+ 08. + + 김현로 포트폴리오 + +

트랜지션 포트폴리오

+

+ 화면 전환과 요소들의 흐름이 순조롭고 매끄러운 작품들로 가득한 포트폴리오 사이트입니다. + 페이지 간의 트랜지션은 마치 이야기를 풀어내는 듯한 흥미진진한 경험을 선사합니다. + + 트랜지션 효과의 적절한 활용은 작품들을 보다 동적이고 생동감 있게 만들어줍니다. + 각 페이지의 이동이 자연스럽고 사용자들이 원활하게 사이트를 탐색할 수 있도록 배려된 구성은 + 개발자의 디자인 능력을 잘 보여주는 특징입니다. +

+ 사이트 보기 +
+
+ 09. + + 포트폴리오 + +

스크롤의 정석 포트폴리오

+

+ 스크롤링을 활용하여 훌륭한 사용자 경험을 선사하는 포트폴리오 사이트입니다. + 스크롤을 내리면서 작품들이 순차적으로 나타나고 효과적으로 전환되는 것은 마치 예술적인 이야기를 읽어나가는 듯한 느낌을 주며 사용자를 매료시킵니다. + 스크롤의 움직임을 통해 작품들이 서서히 드러나고, 각 페이지 간의 전환은 자연스럽고 부드럽습니다. + 이러한 트랜지션과 애니메이션들이 작품들의 내용과 테마를 더욱 강조해줍니다. +

+ 사이트 보기 +
+
+ 10. + + 포트폴리오 + +

모던함의 정석 포트폴리오

+

+ 현대적이고 세련된 디자인으로 가득한 포트폴리오 사이트입니다. + 모던한 느낌과 세심한 디테일이 조화를 이루며, 사용자에게 신선하고 품격 있는 경험을 제공합니다. + 사이트의 디자인은 깔끔하고 단정하면서도 특유의 감성과 풍부한 표현력이 느껴집니다. + 간결한 레이아웃과 모던한 색상 선택은 주인공의 디자인 감각을 잘 보여주는 특징입니다. +

+ 사이트 보기 +
+
+
+
+ + +
+
+

Contact

+ + + +
+
+ +
+ + + + + + + + + diff --git a/src/index.js b/src/index.js index 3165128..8fdde3a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,10 +1,11 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; +import "./assets/scss/style.scss"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( -); +); \ No newline at end of file diff --git a/src/utils/link.js b/src/utils/link.js new file mode 100644 index 0000000..f5974d6 --- /dev/null +++ b/src/utils/link.js @@ -0,0 +1,16 @@ +const link = () => { + document.querySelectorAll("a[href^='#']").forEach((anchor) => { + anchor.addEventListener("click", function(e){ + e.preventDefault(); + + const targetId = this.getAttribute("href"); + const targetElement = document.querySelector(targetId); + + if(targetElement){ + targetElement.scrollIntoView({ behavior: "smooth"}); + } + }); + }); +} + +export default link; \ No newline at end of file diff --git a/src/utils/smooth.js b/src/utils/smooth.js new file mode 100644 index 0000000..38e64e7 --- /dev/null +++ b/src/utils/smooth.js @@ -0,0 +1,21 @@ +import Lenis from "@studio-freight/lenis"; + +const lenis = () => { + const lenis = new Lenis({ + duration: 1, + easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)) + }); + + function raf(time) { + lenis.raf(time) + requestAnimationFrame(raf); + } + + requestAnimationFrame(raf); + + lenis.on("scroll", (e) => { + console.log(e); + }) +} + +export default lenis; \ No newline at end of file diff --git a/src/views/HomeView.jsx b/src/views/HomeView.jsx new file mode 100644 index 0000000..44f1698 --- /dev/null +++ b/src/views/HomeView.jsx @@ -0,0 +1,29 @@ +import React from "react"; +import Header from "../components/Header"; +import Skip from "../components/Skip"; +import Intro from "../components/Intro"; +import Skill from "../components/Skill"; +import Site from "../components/Site"; +import Port from "../components/Port"; +import Contact from "../components/Contact"; +import Footer from "../components/Footer"; +import Main from "../components/Main"; + +const HomeView = () => { + return ( + <> + +
+
+ + + + + +
+