diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..315edf2 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +ch3nyang.top \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..faa0013 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Ch3nyang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..81f3630 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# portfolio + +This is a portfolio of myself. diff --git a/assets/noun-ball.svg b/assets/noun-ball.svg new file mode 100644 index 0000000..7c78d6a --- /dev/null +++ b/assets/noun-ball.svg @@ -0,0 +1 @@ +Created by Malu Guntherfrom the Noun Project \ No newline at end of file diff --git a/assets/noun-circle.svg b/assets/noun-circle.svg new file mode 100644 index 0000000..93a454f --- /dev/null +++ b/assets/noun-circle.svg @@ -0,0 +1 @@ +Created by Malu Guntherfrom the Noun Project \ No newline at end of file diff --git a/assets/noun-lines.svg b/assets/noun-lines.svg new file mode 100644 index 0000000..2aa55a9 --- /dev/null +++ b/assets/noun-lines.svg @@ -0,0 +1 @@ +Created by Malu Guntherfrom the Noun Project \ No newline at end of file diff --git a/assets/noun-mess.svg b/assets/noun-mess.svg new file mode 100644 index 0000000..f8b56ea --- /dev/null +++ b/assets/noun-mess.svg @@ -0,0 +1 @@ +Created by Malu Guntherfrom the Noun Project \ No newline at end of file diff --git a/assets/noun-waves.svg b/assets/noun-waves.svg new file mode 100644 index 0000000..c3b8d47 --- /dev/null +++ b/assets/noun-waves.svg @@ -0,0 +1 @@ +Created by Malu Guntherfrom the Noun Project \ No newline at end of file diff --git a/icons/asterisk.svg b/icons/asterisk.svg new file mode 100644 index 0000000..87d7f73 --- /dev/null +++ b/icons/asterisk.svg @@ -0,0 +1,18 @@ + + + diff --git a/icons/bubbles.svg b/icons/bubbles.svg new file mode 100644 index 0000000..86b7dc1 --- /dev/null +++ b/icons/bubbles.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/icons/email.svg b/icons/email.svg new file mode 100644 index 0000000..0e06893 --- /dev/null +++ b/icons/email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/github.svg b/icons/github.svg new file mode 100644 index 0000000..f376c3e --- /dev/null +++ b/icons/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/hurricane.svg b/icons/hurricane.svg new file mode 100644 index 0000000..9b87b3c --- /dev/null +++ b/icons/hurricane.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/icons/smile.svg b/icons/smile.svg new file mode 100644 index 0000000..24ebacf --- /dev/null +++ b/icons/smile.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/icons/twitter.svg b/icons/twitter.svg new file mode 100644 index 0000000..8887700 --- /dev/null +++ b/icons/twitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/apple-touch-icon.png b/img/apple-touch-icon.png new file mode 100644 index 0000000..e637828 Binary files /dev/null and b/img/apple-touch-icon.png differ diff --git a/img/favicon.svg b/img/favicon.svg new file mode 100644 index 0000000..8ce83ba --- /dev/null +++ b/img/favicon.svg @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/img/ogimage.png b/img/ogimage.png new file mode 100644 index 0000000..18d786e Binary files /dev/null and b/img/ogimage.png differ diff --git a/img/twittercard.png b/img/twittercard.png new file mode 100644 index 0000000..5457fa0 Binary files /dev/null and b/img/twittercard.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..f2e2695 --- /dev/null +++ b/index.html @@ -0,0 +1,102 @@ + + + + + + + + Homepage of Ch3nyang + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
homepage of
+
ch3n
+
+
+
+
yang
+
+ Asterisk +
+
+
+
+
+
+ Smile +
+
+
Hi there!
+
I'm Ch3nyang, a fullstack developer hailing from Southeast University, China, currently pursuing a Master's degree in Cybersecurity. I have a passion for programming, enjoy writing, and love to share.
+
Hope you enjoy yourself here!
+
+
+
+

skill

+
+

link

+ + + + + + + + \ No newline at end of file diff --git a/js/link.js b/js/link.js new file mode 100644 index 0000000..7b098d9 --- /dev/null +++ b/js/link.js @@ -0,0 +1,27 @@ +var blog = document.querySelector('.cluster1 .link-title'); +var originalContent1 = blog.textContent; +var originalFontSize1 = blog.style.fontSize; +blog.addEventListener('mouseover', function() { + blog.textContent = 'blog.ch3nyang.top'; + blog.style.fontSize = '1.5em'; + blog.style.textDecoration = 'underline'; +}); +blog.addEventListener('mouseout', function() { + blog.textContent = originalContent1; + blog.style.fontSize = originalFontSize1; + blog.style.textDecoration = 'none'; +}); + +var mind = document.querySelector('.cluster2 .link-title'); +var originalContent2 = mind.textContent; +var originalFontSize2 = mind.style.fontSize; +mind.addEventListener('mouseover', function() { + mind.textContent = 'mind.ch3nyang.top'; + mind.style.fontSize = '1.5em'; + mind.style.textDecoration = 'underline'; +}); +mind.addEventListener('mouseout', function() { + mind.textContent = originalContent2; + mind.style.fontSize = originalFontSize2; + mind.style.textDecoration = 'none'; +}); \ No newline at end of file diff --git a/js/skill.js b/js/skill.js new file mode 100644 index 0000000..183e5cf --- /dev/null +++ b/js/skill.js @@ -0,0 +1,51 @@ +const skills = [ + { + category: 'Frontend', + items: ['html5', 'css3', 'javascript', 'jquery', 'react', 'vuejs', 'sass', 'tailwindcss', 'typescript', 'webpack', 'vitejs' + ] + }, + { + category: 'Backend', + items: ['c', 'cplusplus', 'python', 'rust', 'go', 'mysql', 'sqlite', 'cmake', 'elasticsearch', 'flask', 'pytorch' + ] + }, + { + category: 'Fullstack', + items: ['nodejs', 'qt', 'electron', 'tauri', 'cloudflareworkers', 'jekyll' + ] + }, + { + category: 'Tools', + items: ['linux', 'windows8', 'powershell', 'git', 'github', 'githubactions', 'vim', 'vscode', 'docker', 'cloudflare', 'jupyter', 'postman' + ] + } +] + +const paint_white = ['rust', 'flask', 'github'] + +const skill = document.querySelector('.skill') + +skills.forEach(({ category, items }, index) => { + const title = document.createElement('div') + title.classList.add('skill-title') + title.textContent = category + skill.appendChild(title) + + const ul = document.createElement('ul') + items.forEach(item => { + const li = document.createElement('li') + const img = document.createElement('img') + img.src = `https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/${item}/${item}-original.svg` + img.alt = item + if (paint_white.includes(item)) { + img.classList.add('white-img') + } + li.appendChild(img) + ul.appendChild(li) + }) + skill.appendChild(ul) + + if (index !== skills.length - 1) { + skill.appendChild(document.createElement('hr')) + } +}) \ No newline at end of file diff --git a/styles/footer.css b/styles/footer.css new file mode 100644 index 0000000..ff8883d --- /dev/null +++ b/styles/footer.css @@ -0,0 +1,56 @@ +.footer { + margin-top: 4rem; + background-color: var(--secondary-color); + color: var(--black-color); + padding: 4rem 0 2rem 0; + text-align: center; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 2rem; +} + +.job { + font-size: 2rem; + font-weight: 900; + font-family: var(--primary-font); + text-transform: uppercase; + margin: 0 1rem; +} + +.footer ul { + display: flex; + justify-content: center; + gap: 2rem; + list-style-type: none; + padding: 0; + margin: 0; +} + +.footer ul li { + font-size: 1.5rem; + transition: transform 0.25s ease-in-out; +} + +.footer ul li:hover { + transform: translateY(-0.25rem); +} + +.footer ul li a { + text-decoration: none; + color: var(--black-color); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.footer ul li a img { + height: 4rem; + width: 4rem; +} + +.footer-text { + margin-top: 2rem; +} \ No newline at end of file diff --git a/styles/home.css b/styles/home.css new file mode 100644 index 0000000..a2bf35f --- /dev/null +++ b/styles/home.css @@ -0,0 +1,169 @@ +.home { + width: 96vw; + height: 96vh; + display: flex; + margin: 1rem auto calc(96vh - 8rem) auto; + font-family: var(--primary-font); +} + +.left { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; +} + +.right { + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.left-square { + width: 100%; + height: 100%; + padding-right: 0.5rem; +} + +.square-content { + width: calc(100% - 0.5rem); + height: calc(100% - 0.5rem); + border: 2rem solid var(--primary-color); + box-sizing: border-box; + background-color: var(--white-color); +} + +.subtitle { + text-transform: capitalize; + letter-spacing: 0.25rem; + font-size: 2rem; + color: var(--primary-color); +} + +.left-title { + text-transform: uppercase; + font-size: 8rem; + font-weight: 900; + color: var(--primary-color); + line-height: 8rem; + transition: text-shadow 0.25s ease-in-out; +} + +.left-title:hover { + text-shadow: 0 0 0.25rem var(--blue-shadow-color); +} + +.right-square { + width: 100%; + height: 100%; + background-color: var(--primary-color); + border: 0.25rem solid var(--primary-color); + box-sizing: border-box; + position: relative; +} + +.right-title { + text-transform: uppercase; + font-size: 8rem; + font-weight: 900; + color: var(--white-color); + position: absolute; + bottom: 0; + left: 0; + line-height: 1; + transform: translateY(0.25rem); + transition: text-shadow 0.25s ease-in-out; +} + +.right-title:hover { + text-shadow: 0 0 0.25rem var(--white-color); +} + +.star { + position: absolute; + right: 2rem; + top: 2rem; +} + +.star img { + width: 16rem; + height: 16rem; + filter: invert(1) grayscale(1) hue-rotate(0deg); +} + +@keyframes home-scroll { + 0% { + transform: translateY(0); + height: 96vh; + } + + 100% { + transform: translateY(calc(96vh - 18.75rem)); + height: 18.75rem; + } +} + +.home { + animation: home-scroll linear forwards; + animation-timeline: scroll(); + animation-range: 0 calc(96vh - 18.75rem); +} + +@keyframes star-hover { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +.star img:hover { + animation: star-hover 1s linear infinite; +} + +@keyframes star-scroll { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + width: 14.25rem; + height: 14.25rem; + } +} + +.star img { + animation: star-scroll linear forwards; + animation-timeline: scroll(); + animation-range: 0 calc(96vh - 18.75rem); +} + +@media screen and (max-width: 768px) { + .left-square, + .star { + display: none; + } + + .home { + flex-direction: column; + } + + .left { + justify-content: end; + } + + .right { + height: auto; + } + + .right-title { + position: static; + } +} \ No newline at end of file diff --git a/styles/index.css b/styles/index.css new file mode 100644 index 0000000..5c469c7 --- /dev/null +++ b/styles/index.css @@ -0,0 +1,115 @@ +@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400..900&family=Lora:ital,wght@0,400..700;1,400..700&display=swap'); + +@import url('./home.css'); +@import url('./info.css'); +@import url('./skill.css'); +@import url('./link.css'); +@import url('./footer.css'); + +:root { + --primary-color: hsl(225, 100%, 50%); + --secondary-color: hsl(200, 100%, 90%); + --black-color: hsl(0, 0%, 0%); + --white-color: hsl(0, 0%, 100%); + --black-shadow-primary-color: hsla(0, 0%, 0%, 0.4); + --black-shadow-secondary-color: hsla(0, 0%, 0%, 0.2); + --blue-shadow-color: hsl(225, 100%, 70%); + --primary-font: "Orbitron", sans-serif; + --secondary-font: "Lora", serif; + + font-size: 16px; + font-family: var(--secondary-font); +} + +@media screen and (max-width: 1024px) { + :root { + font-size: 12px; + } +} + +@media screen and (max-width: 768px) { + :root { + font-size: 12px; + } +} + +@media screen and (max-width: 425px) { + :root { + font-size: 10px; + } +} + +@media screen and (min-width: 2560px) { + :root { + font-size: 20px; + } +} + +body { + margin: 0; + background-color: var(--white-color); +} + +h2 { + position: relative; + width: -moz-fit-content; + width: fit-content; + font-size: 2rem; + font-weight: 900; + line-height: 2.5rem; + letter-spacing: 0.5rem; + font-family: var(--primary-font); + text-transform: uppercase; + margin: 4rem auto 1rem auto; +} + +h2::before, +h2::after { + content: ""; + display: block; + height: 2rem; + width: 2rem; + background-color: var(--primary-color); + transition: background-color 0.25s ease-in-out; +} + +h2::before { + position: absolute; + top: 0.25rem; + left: -3rem; +} + +h2::after { + position: absolute; + top: 0.25rem; + right: -2.5rem; +} + +h2:hover::before, +h2:hover::after { + background-color: var(--black-color); +} + +@keyframes body-color { + 0% { + background-color: var(--white-color); + } + + 50% { + background-color: var(--secondary-color); + } + + 750% { + background-color: var(--secondary-color); + } + + 100% { + background-color: var(--white-color); + } +} + +body { + animation: body-color linear forwards; + animation-timeline: scroll(); + animation-range: 50vh 250vh; +} \ No newline at end of file diff --git a/styles/info.css b/styles/info.css new file mode 100644 index 0000000..4fc14fc --- /dev/null +++ b/styles/info.css @@ -0,0 +1,112 @@ +.info { + width: 96vw; + height: 48vh; + display: flex; + align-items: center; + justify-content: end; + margin: 0 auto 0 auto; +} + +.smile img { + width: 16rem; + height: 16rem; +} + +.info-content { + margin-left: 8rem; + width: 45rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: flex-start; + gap: 1rem; +} + +.info-title { + text-transform: uppercase; + font-size: 4rem; + font-weight: 900; + font-family: var(--primary-font); +} + +.info-text { + letter-spacing: 0.05rem; + font-size: 1.5rem; + line-height: 2.25rem; + -webkit-hyphens: auto; + hyphens: auto; +} + +.info-text u { + transition: color 0.25s ease-out; +} + +.info-text u:hover { + background-color: var(--primary-color); + text-decoration: none; + color: var(--white-color); +} + +@keyframes smile-scroll { + 0% { + transform: translateX(-100vw) rotate(-60deg) scale(0.5); + } + + 80% { + transform: translateX(0) rotate(0deg) scale(1); + } + + 90% { + transform: translateX(5vw) rotate(30deg) scale(1.05); + } + + 100% { + transform: translateX(0) rotate(0deg) scale(1); + } +} + +.smile img { + view-timeline: scroll() block; + animation-timeline: view(); + animation-name: smile-scroll; + animation-range: entry 0% contain 50%; + animation-fill-mode: forwards; +} + +@keyframes info-title-scroll { + 0% { + color: var(--black-color); + } + + 100% { + color: var(--primary-color); + } +} + +.info-title { + view-timeline: scroll() block; + animation-timeline: view(); + animation-name: info-title-scroll; + animation-range: entry 100% contain 75%; + animation-fill-mode: forwards; +} + +@media screen and (max-width: 768px) { + .smile { + display: none; + } + + .info { + justify-content: center; + } + + .info-content { + margin-left: 0; + } +} + +@media screen and (min-width: 1440px) { + .info { + justify-content: center; + } +} \ No newline at end of file diff --git a/styles/link.css b/styles/link.css new file mode 100644 index 0000000..6441601 --- /dev/null +++ b/styles/link.css @@ -0,0 +1,81 @@ +.link { + display: flex; + justify-content: center; + align-items: stretch; + gap: 1rem; + margin: 3rem 2rem 0 2rem; +} + +.link-cluster { + text-decoration: none; + color: var(--primary-color); + display: grid; + grid-template-columns: auto auto; + grid-template-rows: auto 1fr; + gap: 1rem 2rem; + border: 0.25rem solid var(--primary-color); + max-width: 31.25rem; + padding: 2rem; + transition: transform 0.25s ease-in-out; +} + +.link-cluster:hover { + transform: translateY(-0.25rem); +} + +.link .cluster1 { + background-color: var(--primary-color); + color: var(--white-color); +} + +.link-cluster .img { + grid-row: 1 / 3; + height: 100%; +} + +.link-cluster .img:hover img { + transform: translateY(8rem) rotate(30deg); +} + +.link-cluster .img img { + height: 8rem; + width: 8rem; + transition: transform 0.25s ease-in-out; +} + +.cluster1 .img img { + filter: invert(1); +} + +.link-cluster .link-title { + font-size: 3rem; + font-weight: 900; + font-family: var(--primary-font); + line-height: 4rem; + text-transform: uppercase; +} + +.link-cluster .link-text { + font-size: 1.5rem; + line-height: 2.25rem; + letter-spacing: 0.05rem; + -webkit-hyphens: auto; + hyphens: auto; +} + +@media screen and (max-width: 768px) { + .link { + flex-direction: column; + align-items: center; + } +} + +@media screen and (max-width: 425px) { + .img { + display: none; + } + + .link-cluster { + grid-template-columns: auto; + } +} \ No newline at end of file diff --git a/styles/skill.css b/styles/skill.css new file mode 100644 index 0000000..1f03f83 --- /dev/null +++ b/styles/skill.css @@ -0,0 +1,120 @@ +.white-img { + filter: invert(1); +} + +.skill { + width: 100%; + background-color: var(--black-color); + color: var(--white-color); + display: grid; + grid-template-columns: auto auto; + justify-content: center; + align-items: start; + gap: 3rem; + padding: 8rem 0; + box-shadow: 0 -1rem 1rem var(--black-shadow-secondary-color), 0 -0.25rem 0.25rem var(--black-shadow-primary-color); +} + +.skill h2 { + grid-column: 1 / 3; +} + +.skill h2:hover::before, +.skill h2:hover::after { + background-color: var(--white-color); +} + +.skill-title { + text-transform: uppercase; + text-align: end; + font-size: 3rem; + font-weight: 100; + font-family: var(--primary-font); + height: 100%; +} + +.skill ul { + list-style-type: none; + display: grid; + grid-template-columns: repeat(6, 4rem); + gap: 1rem; + margin: 0; + padding: 0; +} + + +.skill li { + display: grid; +} + +.skill li img { + width: 4rem; + height: 4rem; + transition: transform 0.25s ease-in-out; +} + +.skill li img:hover { + transform: scale(0.9) rotate(10deg); +} + +.skill hr { + grid-column: 1 / 3; + width: 100%; + border: 0.0625rem solid var(--primary-color); +} + +@keyframes skill-scroll { + from { + transform: translateY(50vh); + } + + to { + transform: translateY(0); + } +} + +.skill { + transform: translateY(50vh); + view-timeline: scroll() block; + animation-timeline: view(); + animation-name: skill-scroll; + animation-range: entry 40% entry 90%; + animation-fill-mode: forwards; +} + +@keyframes skill-element-scroll { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +.skill-title, +.skill ul, +.skill hr { + opacity: 0; + view-timeline: scroll() block; + animation-timeline: view(); + animation-name: skill-element-scroll; + animation-range: entry 50% contain 50%; + animation-fill-mode: forwards; +} + +@media screen and (max-width: 768px) { + .skill { + grid-template-columns: auto; + align-items: center; + } + + .skill h2, + .skill hr { + grid-column: 1 / 2; + } + + .skill-title { + text-align: center; + } +} \ No newline at end of file