Skip to content

Commit 1520977

Browse files
committed
add creative portfolio
1 parent da31922 commit 1520977

File tree

4 files changed

+301
-10
lines changed

4 files changed

+301
-10
lines changed

93-creative portfolio/index.html

+25-7
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,29 @@ <h3 class="logo">Dimitri Marco</h3>
2323
fill="none"
2424
xmlns="http://www.w3.org/2000/svg"
2525
>
26-
<line y1="1.5" x2="43" y2="1.5" stroke="white" stroke-width="3" />
27-
<line y1="11.5" x2="28" y2="11.5" stroke="white" stroke-width="3" />
28-
<line y1="21.5" x2="16" y2="21.5" stroke="white" stroke-width="3" />
26+
<line
27+
y1="1.5"
28+
x2="43"
29+
y2="1.5"
30+
stroke="var(--white)"
31+
stroke-width="3"
32+
/>
33+
<line
34+
y1="11.5"
35+
x2="28"
36+
y2="11.5"
37+
stroke="var(--white)"
38+
stroke-width="3"
39+
/>
40+
<line
41+
y1="21.5"
42+
x2="16"
43+
y2="21.5"
44+
stroke="var(--white)"
45+
stroke-width="3"
46+
/>
2947
</svg>
30-
<!-- <div class="nav-open">
48+
<div class="nav-open">
3149
<div class="contact">
3250
<h3>Contact</h3>
3351
<p>02348-234-843</p>
@@ -73,7 +91,7 @@ <h3>Social</h3>
7391
</svg>
7492
</div>
7593
</div>
76-
</div> -->
94+
</div>
7795
</nav>
7896
</header>
7997
<main>
@@ -134,7 +152,7 @@ <h2>Hair Stylist</h2>
134152
/>
135153
</div>
136154
</section>
137-
<!-- <aside>
155+
<aside>
138156
<div class="pages">
139157
<div class="page-1">
140158
<h3>01</h3>
@@ -176,7 +194,7 @@ <h3>03</h3>
176194
</svg>
177195
</div>
178196
</div>
179-
</aside> -->
197+
</aside>
180198
</main>
181199
</div>
182200
<script

93-creative portfolio/script.js

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
function init() {
2+
// slider
3+
const slides = document.querySelectorAll(".slide");
4+
const pages = document.querySelectorAll(".page");
5+
const backgrounds = [
6+
`radial-gradient(#2B3760, #0B1023)`,
7+
`radial-gradient(#4E3022, #161616)`,
8+
`radial-gradient(#4E4342, #161616)`,
9+
];
10+
let current = 0;
11+
let scrollSlide = 0;
12+
13+
slides.forEach((slide, index) => {
14+
slide.addEventListener("click", function () {
15+
changeDots(this);
16+
nextSlide(index);
17+
scrollSlide = index;
18+
});
19+
});
20+
21+
function changeDots(dot) {
22+
slides.forEach((slide) => slide.classList.remove("active"));
23+
dot.classList.add("active");
24+
}
25+
26+
function nextSlide(pageNumber) {
27+
const nextPage = pages[pageNumber];
28+
const currentPage = pages[current];
29+
const nextLeft = nextPage.querySelector(".hero .model-left");
30+
const nextRight = nextPage.querySelector(".hero .model-right");
31+
const currentLeft = currentPage.querySelector(".hero .model-left");
32+
const currentRight = currentPage.querySelector(".hero .model-right");
33+
const nextText = nextPage.querySelector(".details");
34+
const portfolio = document.querySelector(".portfolio");
35+
36+
const tl = new TimelineMax({
37+
// disable clicks during animations
38+
onStart: function () {
39+
slides.forEach((slide) => (slide.style.pointerEvents = "none"));
40+
},
41+
onComplete: function () {
42+
slides.forEach((slide) => (slide.style.pointerEvents = "all"));
43+
},
44+
});
45+
46+
tl.fromTo(currentLeft, 0.3, { y: "-10%" }, { y: "-100%" })
47+
.fromTo(currentRight, 0.3, { y: "10%" }, { y: "-100%" }, "-=0.2")
48+
.to(portfolio, 0.3, { backgroundImage: backgrounds[pageNumber] })
49+
.fromTo(
50+
currentPage,
51+
0.3,
52+
{ opacity: 1, pointerEvents: "all" },
53+
{ opacity: 0, pointerEvents: "none" }
54+
)
55+
.fromTo(
56+
nextPage,
57+
0.3,
58+
{ opacity: 0, pointerEvents: "none" },
59+
{ opacity: 1, pointerEvents: "all" },
60+
"-=0.6"
61+
)
62+
.fromTo(nextLeft, 0.3, { y: "-100%" }, { y: "-10%" }, "-=0.6")
63+
.fromTo(nextRight, 0.3, { y: "-100%" }, { y: "10%" }, "-=0.8")
64+
.fromTo(nextText, 0.3, { opacity: 0, y: 0 }, { opacity: 1, y: 0 })
65+
.set(nextLeft, { clearProps: "all" })
66+
.set(nextRight, { clearProps: "all" });
67+
current = pageNumber;
68+
}
69+
document.addEventListener("wheel", throttle(scrollChange, 1500));
70+
document.addEventListener("touchmove", throttle(scrollChange, 1500));
71+
72+
function swithDots(dotNumber) {
73+
const activeDot = document.querySelectorAll(".slide")[dotNumber];
74+
slides.forEach((slide) => slide.classList.remove("active"));
75+
activeDot.classList.add("active");
76+
}
77+
78+
function scrollChange(e) {
79+
e.deltaY > 0 ? (scrollSlide += 1) : (scrollSlide -= 1);
80+
// reset
81+
if (scrollSlide > 2) scrollSlide = 0;
82+
if (scrollSlide < 0) scrollSlide = 2;
83+
swithDots(scrollSlide);
84+
nextSlide(scrollSlide);
85+
}
86+
87+
// menu
88+
const hamburger = document.querySelector(".menu");
89+
const hamburgerLines = document.querySelectorAll(".menu line");
90+
const navOpen = document.querySelector(".nav-open");
91+
const contact = document.querySelector(".contact");
92+
const social = document.querySelector(".social");
93+
const logo = document.querySelector(".logo");
94+
95+
const tl = new TimelineMax({ paused: true, reversed: true });
96+
97+
tl.to(navOpen, 0.5, { y: 0 })
98+
.fromTo(contact, 0.5, { opacity: 0, y: 10 }, { opacity: 1, y: 0 }, "-=0.1")
99+
.fromTo(social, 0.5, { opacity: 0, y: 10 }, { opacity: 1, y: 0 }, "-=0.5")
100+
.fromTo(logo, 0.2, { color: "var(--white)" }, { color: "black" }, "-=1")
101+
.fromTo(
102+
hamburgerLines,
103+
0.2,
104+
{ stroke: "var(--white)" },
105+
{ stroke: "black" },
106+
"-=1"
107+
);
108+
109+
hamburger.addEventListener("click", () => {
110+
tl.reversed() ? tl.play() : tl.reverse();
111+
});
112+
}
113+
114+
// avoid multiple firing
115+
function throttle(func, limit) {
116+
let inThrottle;
117+
return function () {
118+
const args = arguments;
119+
const context = this;
120+
if (!inThrottle) {
121+
func.apply(context, args);
122+
inThrottle = true;
123+
setTimeout(() => (inThrottle = false), limit);
124+
}
125+
};
126+
}
127+
128+
init();

93-creative portfolio/style.css

+147-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500&display=swap");
22

3+
:root {
4+
--white: rgba(255, 255, 255, 0.9);
5+
}
6+
37
*,
48
*::before,
59
*::after {
@@ -14,10 +18,12 @@ body {
1418
}
1519

1620
.portfolio {
17-
color: rgba(255, 255, 255, 0.9);
21+
color: var(--white);
1822
background: radial-gradient(rgba(43, 55, 96, 1), rgba(11, 16, 35, 1));
1923
}
2024

25+
/* header */
26+
2127
nav {
2228
min-height: 10vh;
2329
width: 90%;
@@ -32,6 +38,8 @@ nav {
3238
font-size: 1.25rem;
3339
}
3440

41+
/* main */
42+
3543
.page {
3644
min-height: 90vh;
3745
display: grid;
@@ -81,15 +89,152 @@ nav {
8189

8290
.details h1 {
8391
font-size: 4rem;
84-
font-weight: 400;
92+
font-weight: 500;
8593
}
8694

8795
.details h2 {
8896
font-size: 2.625rem;
97+
font-weight: 400;
8998
padding: 20px 0;
9099
}
91100

92101
.details p {
93102
font-size: 1.5rem;
94103
padding: 20px 0 50px;
95104
}
105+
106+
/* slider */
107+
108+
.pages {
109+
position: absolute;
110+
right: 5%;
111+
top: 50%;
112+
transform: translateY(-50%);
113+
}
114+
115+
.pages > div {
116+
display: flex;
117+
align-items: center;
118+
justify-content: space-between;
119+
}
120+
121+
.pages h3 {
122+
font-size: 1.5rem;
123+
padding: 30px;
124+
}
125+
126+
.pages svg {
127+
cursor: pointer;
128+
opacity: 0.5;
129+
transform: scale(2);
130+
}
131+
132+
.pages svg:hover {
133+
animation: dot 0.5s ease-in-out infinite alternate;
134+
}
135+
136+
.pages svg.active {
137+
opacity: 0.9;
138+
}
139+
140+
@keyframes dot {
141+
0% {
142+
transform: scale(2);
143+
}
144+
100% {
145+
transform: scale(4);
146+
}
147+
}
148+
149+
/* menu */
150+
151+
.nav-open {
152+
position: absolute;
153+
top: 0px;
154+
left: 0px;
155+
width: 100%;
156+
height: 50vh;
157+
background-color: #fff;
158+
color: #000;
159+
z-index: 1;
160+
display: grid;
161+
grid-template-columns: 5% 1fr 1fr 5%;
162+
justify-items: center;
163+
align-items: center;
164+
text-align: center;
165+
transform: translateY(-101%);
166+
}
167+
168+
.contact {
169+
grid-column: 2/3;
170+
}
171+
172+
.nav-open h3 {
173+
font-size: 1.75rem;
174+
padding-bottom: 40px;
175+
}
176+
177+
.nav-open p {
178+
font-size: 1.125rem;
179+
}
180+
181+
.social-links {
182+
display: flex;
183+
gap: 1.25rem;
184+
}
185+
186+
.logo,
187+
.menu {
188+
z-index: 2;
189+
}
190+
191+
.menu {
192+
cursor: pointer;
193+
}
194+
195+
/* media queries */
196+
197+
@media (max-width: 1024px) {
198+
.page {
199+
grid-template-columns: 5% 1fr 5%;
200+
grid-template-rows: 2fr 1fr;
201+
align-items: center;
202+
}
203+
204+
.hero {
205+
grid-column: 2/3;
206+
height: auto;
207+
}
208+
209+
.hero img {
210+
height: 500px;
211+
}
212+
213+
.details {
214+
grid-row: 2/3;
215+
grid-column: 2/3;
216+
text-align: center;
217+
}
218+
219+
.details h1 {
220+
font-size: 3rem;
221+
}
222+
223+
.details h2 {
224+
font-size: 2.375rem;
225+
}
226+
}
227+
228+
@media (max-width: 768px) {
229+
.hero img {
230+
height: 400px;
231+
}
232+
233+
.details h1 {
234+
font-size: 2.375rem;
235+
}
236+
237+
.details h2 {
238+
font-size: 1.75rem;
239+
}
240+
}

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
| 90 | [Tooltip](https://github.com/solygambas/html-css-fifty-projects/tree/master/90-tooltip) | [Live Demo](https://codepen.io/solygambas/full/YzNgzMb) |
9999
| 91 | [Chat Interface](https://github.com/solygambas/html-css-fifty-projects/tree/master/91-chat%20interface) | [Live Demo](https://codepen.io/solygambas/full/MWJxaOJ) |
100100
| 92 | [Music Streaming Service](https://github.com/solygambas/html-css-fifty-projects/tree/master/92-music%20streaming%20service) | [Live Demo](https://codepen.io/solygambas/full/qBRvLmg) |
101-
| 93 | [Creative Portfolio](https://github.com/solygambas/html-css-fifty-projects/tree/master/93-creative%20portfolio) | [Live Demo](#) |
101+
| 93 | [Creative Portfolio](https://github.com/solygambas/html-css-fifty-projects/tree/master/93-creative%20portfolio) | [Live Demo](https://codepen.io/solygambas/full/zYNbgxR) |
102102

103103
This repository is mostly based on 2 courses by Brad Traversy (2020):
104104

0 commit comments

Comments
 (0)