Skip to content

Commit 07933a7

Browse files
authored
Fixed main page image carousel (#874)
* Fixed main page image carousel * Changed carousel to pass lint checks * More carousel css changes to pass lint checks * Reworked image carousel to have better visual layout + image popup * Added newline to pass lint checks
1 parent b7e3e1e commit 07933a7

File tree

2 files changed

+181
-24
lines changed

2 files changed

+181
-24
lines changed

components/Carousel.js

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
import Image from 'next/legacy/image';
1+
// import Image from 'next/legacy/image';
22
import { useState, useEffect } from 'react';
33

4-
// width of each img in px
4+
// width of each frame in px
55
// needs to be updated if style.scss changes
6-
const IMAGE_WIDTH = 360;
6+
const FRAME_WIDTH = 340;
77
const ITEMS_PER_SECTION = 4;
88

99
const Carousel = ({ images }) => {
1010
const [sections, setSections] = useState([]);
11-
const sectionWidth = (IMAGE_WIDTH * ITEMS_PER_SECTION) / 2;
11+
const [isOpen, setIsOpen] = useState(false);
12+
const [currentImage, setCurrentImage] = useState(null);
13+
const sectionWidth = (FRAME_WIDTH * ITEMS_PER_SECTION) / 2;
1214

1315
useEffect(() => {
1416
const numItems = images.length;
@@ -19,15 +21,26 @@ const Carousel = ({ images }) => {
1921
left: (i / ITEMS_PER_SECTION) * sectionWidth,
2022
width: sectionWidth,
2123
items: images.slice(i, i + ITEMS_PER_SECTION).map((item, index) => (
22-
<a
23-
href={item}
24-
target="_blank"
25-
rel="noreferrer noopener"
26-
key={index}
27-
tabIndex="-1"
28-
>
29-
<Image src={item} width={IMAGE_WIDTH} height={IMAGE_WIDTH} alt="" />
30-
</a>
24+
<div className="image-frame" key={index}>
25+
<div
26+
className="image-click"
27+
onClick={() => {
28+
setCurrentImage(item);
29+
setIsOpen(true);
30+
}}
31+
onKeyDown={(e) => {
32+
if (e.key === 'Enter' || e.key === ' ') {
33+
setCurrentImage(item);
34+
setIsOpen(true);
35+
}
36+
}}
37+
role="button"
38+
tabIndex={0}
39+
style={{ cursor: 'pointer' }}
40+
>
41+
<img src={item} alt="" className="framed-image" />
42+
</div>
43+
</div>
3144
)),
3245
});
3346
}
@@ -65,6 +78,29 @@ const Carousel = ({ images }) => {
6578
);
6679
})}
6780
</div>
81+
{isOpen && (
82+
<div
83+
className="popup-overlay"
84+
onClick={() => setIsOpen(false)}
85+
onKeyDown={(e) => {
86+
if (e.key === 'Escape') {
87+
setIsOpen(false);
88+
}
89+
}}
90+
role="button"
91+
tabIndex={0}
92+
>
93+
<button id="close-button" onClick={() => setIsOpen(false)}></button>
94+
<div
95+
className="popup-content"
96+
onClick={(e) => e.stopPropagation()}
97+
onKeyDown={(e) => e.stopPropagation()}
98+
role="presentation"
99+
>
100+
<img src={currentImage} alt="" className="popup-image" />
101+
</div>
102+
</div>
103+
)}
68104
</div>
69105
);
70106
};

styles/components/Carousel.scss

Lines changed: 132 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,156 @@
22

33
#carousel {
44
background: #FAFAFA;
5-
height: 480px;
5+
height: 500px;
66
min-width: 100%;
77
overflow: hidden;
88
position: relative;
99

1010
#carousel-inner {
11-
width: 1600px;
11+
height: 100%;
1212
}
1313

1414
.carousel-sect {
1515
background: linear-gradient(rgba(variables.$acm-black, 0.8), rgba(variables.$acm-black, 1));
1616
position: absolute;
1717
top: 0;
1818
width: 1600px;
19+
height: 100%;
20+
display: flex;
21+
flex-wrap: wrap;
22+
align-content: flex-start;
1923

20-
div {
21-
background-size: cover;
22-
display: inline-block;
23-
height: 240px;
24+
.image-frame {
25+
width: 340px;
26+
height: 250px;
2427
margin: 0;
25-
opacity: 0.9;
26-
padding: 0;
28+
background: #FFF;
29+
border: 1px solid #D0D0D0;
30+
box-shadow:
31+
0 2px 8px rgba(0, 0, 0, 0.1),
32+
inset 0 0 0 1px rgba(255, 255, 255, 0.8);
33+
box-sizing: border-box;
34+
display: flex;
35+
align-items: center;
36+
justify-content: center;
37+
position: relative;
2738
transition: 0.35s cubic-bezier(0.05, 1.04, 0.72, 0.98);
28-
vertical-align: top;
29-
width: 360px;
39+
40+
// Photo frame texture effect
41+
&::before {
42+
content: '';
43+
position: absolute;
44+
top: 0;
45+
left: 0;
46+
right: 0;
47+
bottom: 0;
48+
}
49+
50+
&:hover {
51+
transform: translateY(-4px);
52+
box-shadow:
53+
0 6px 16px rgba(0, 0, 0, 0.15),
54+
inset 0 0 0 1px rgba(255, 255, 255, 0.9);
55+
}
56+
57+
.image-click {
58+
width: 100%;
59+
height: 100%;
60+
display: flex;
61+
align-items: center;
62+
justify-content: center;
63+
overflow: hidden;
64+
65+
.framed-image {
66+
max-width: 100%;
67+
max-height: 100%;
68+
width: 100%;
69+
height: 100%;
70+
object-fit: cover;
71+
display: block;
72+
transition: 0.35s cubic-bezier(0.05, 1.04, 0.72, 0.98);
73+
}
74+
}
75+
76+
&:hover .framed-image {
77+
transform: scale(1.05);
78+
}
79+
}
80+
}
81+
82+
// Popup Overlay w/ the darkened fullscreen background
83+
.popup-overlay {
84+
position: fixed;
85+
top: 0;
86+
left: 0;
87+
width: 100vw;
88+
height: 100vh;
89+
background: rgba(0, 0, 0, 0.8);
90+
display: flex;
91+
justify-content: center;
92+
align-items: center;
93+
z-index: 9999;
94+
animation: fadeIn 0.25s ease-out;
95+
96+
#close-button {
97+
position: fixed;
98+
top: 20px;
99+
right: 20px;
100+
background: rgba(0, 0, 0, 0.7);
101+
color: #FFF;
102+
border: 2px solid #FFF;
103+
font-size: 1.5em;
104+
width: 50px;
105+
height: 50px;
106+
border-radius: 50%;
107+
cursor: pointer;
108+
display: flex;
109+
align-items: center;
110+
justify-content: center;
111+
transition: 0.3s;
112+
z-index: 10001;
30113

31114
&:hover {
32-
opacity: 0.6;
115+
background: rgba(255, 255, 255, 0.2);
116+
transform: scale(1.1);
33117
}
34118
}
35119
}
120+
121+
// Inner box that holds the image
122+
.popup-content {
123+
position: relative;
124+
animation: scaleIn 0.25s ease-out; // smooth zoom animation
125+
126+
img.popup-image {
127+
max-width: min(80vw, 1200px);
128+
max-height: min(80vh, 800px);
129+
border-radius: 10px;
130+
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
131+
display: block;
132+
}
133+
}
134+
135+
// Fade and scale animations
136+
@keyframes fadeIn {
137+
from {
138+
background: rgba(0, 0, 0, 0);
139+
}
140+
141+
to {
142+
background: rgba(0, 0, 0, 0.8);
143+
}
144+
}
145+
146+
@keyframes scaleIn {
147+
from {
148+
transform: scale(0.9);
149+
opacity: 0;
150+
}
151+
152+
to {
153+
transform: scale(1);
154+
opacity: 1;
155+
}
156+
}
36157
}

0 commit comments

Comments
 (0)