Skip to content

Commit 3e17a82

Browse files
committed
fix(images): fixes wierd gaps on images on non-vertical aspect ratio
1 parent d2f80fa commit 3e17a82

1 file changed

Lines changed: 58 additions & 84 deletions

File tree

app/campus-life/page.tsx

Lines changed: 58 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"use client";
22

3-
import { useState } from "react";
4-
import { motion, type PanInfo } from "framer-motion";
3+
import { motion } from "framer-motion";
54
import { BlurImage } from "@/components/ui/blur-image";
65
import { MapPin, Coffee, Utensils, Wifi, Bus, Bike, Shield } from "lucide-react";
76
import { GradientBlob } from "@/components/ui/GradientBlob";
@@ -67,18 +66,14 @@ export default function CampusLifePage() {
6766
}
6867
];
6968

70-
const [currentSlide, setCurrentSlide] = useState(0);
71-
72-
// 288px card + 16px gap = 304px per slide
73-
const getSlideOffset = (index: number) => -index * 304;
69+
const containerVariants = {
70+
hidden: { opacity: 0 },
71+
visible: { opacity: 1, transition: { staggerChildren: 0.1 } },
72+
};
7473

75-
const handleDragEnd = (_: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => {
76-
const { offset, velocity } = info;
77-
let direction = 0;
78-
if (offset.x < -50 || velocity.x < -500) direction = 1;
79-
else if (offset.x > 50 || velocity.x > 500) direction = -1;
80-
const next = Math.max(0, Math.min(currentSlide + direction, oldDorms.length - 1));
81-
setCurrentSlide(next);
74+
const itemVariants = {
75+
hidden: { opacity: 0, y: 20 },
76+
visible: { opacity: 1, y: 0 },
8277
};
8378

8479
const galleryImages = [
@@ -264,62 +259,36 @@ export default function CampusLifePage() {
264259
))}
265260
</div>
266261

267-
{/* Mobile Drag Carousel */}
268-
<div className="md:hidden -mx-6 overflow-hidden">
269-
<motion.div
270-
className="flex gap-4 px-[calc((100vw-288px)/2)] cursor-grab active:cursor-grabbing touch-pan-y"
271-
drag="x"
272-
dragConstraints={{
273-
left: getSlideOffset(oldDorms.length - 1),
274-
right: 0,
275-
}}
276-
dragElastic={0.15}
277-
onDragEnd={handleDragEnd}
278-
animate={{ x: getSlideOffset(currentSlide) }}
279-
transition={{ type: "spring", stiffness: 300, damping: 30 }}
280-
>
281-
{oldDorms.map((dorm, idx) => (
282-
<div
283-
key={idx}
284-
className="flex-shrink-0 w-[288px] select-none bg-white rounded-2xl overflow-hidden shadow-sm border border-border"
285-
>
286-
<div className="h-44 overflow-hidden relative">
287-
<BlurImage src={dorm.image} alt={dorm.title} placeholder="blur" className="w-full h-full object-cover pointer-events-none" />
288-
<div className="absolute bottom-3 right-3 bg-black/70 backdrop-blur-md text-white px-2.5 py-0.5 rounded-full text-xs font-medium z-10">
289-
{dorm.price}
290-
</div>
291-
</div>
292-
<div className="p-4">
293-
<h3 className="text-base font-bold mb-3 text-center">{dorm.title}</h3>
294-
<ul className="space-y-1.5 px-6">
295-
{dorm.features.map((feature, i) => (
296-
<li key={i} className="flex items-center gap-2 text-xs text-muted-foreground">
297-
<div className="w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0" />
298-
{feature}
299-
</li>
300-
))}
301-
</ul>
262+
{/* Mobile */}
263+
<div className="md:hidden space-y-4">
264+
{oldDorms.map((dorm, idx) => (
265+
<motion.div
266+
key={idx}
267+
initial={{ opacity: 0, y: 20 }}
268+
whileInView={{ opacity: 1, y: 0 }}
269+
viewport={{ once: true, margin: "-100px" }}
270+
transition={{ delay: idx * 0.1 }}
271+
className="bg-white rounded-2xl overflow-hidden shadow-sm border border-border"
272+
>
273+
<div className="h-44 overflow-hidden relative">
274+
<BlurImage src={dorm.image} alt={dorm.title} placeholder="blur" className="w-full h-full object-cover" />
275+
<div className="absolute bottom-3 right-3 bg-black/70 backdrop-blur-md text-white px-2.5 py-0.5 rounded-full text-xs font-medium z-10">
276+
{dorm.price}
302277
</div>
303278
</div>
304-
))}
305-
</motion.div>
306-
{/* Dot indicators */}
307-
<div className="flex justify-center mt-4">
308-
<div className="flex gap-2.5 items-center">
309-
{oldDorms.map((_, index) => (
310-
<button
311-
key={index}
312-
className={`rounded-full transition-all duration-200 ${
313-
currentSlide === index
314-
? "bg-primary w-3 h-3"
315-
: "bg-primary/30 w-2.5 h-2.5"
316-
}`}
317-
onClick={() => setCurrentSlide(index)}
318-
aria-label={`Go to slide ${index + 1}`}
319-
/>
320-
))}
321-
</div>
322-
</div>
279+
<div className="p-4">
280+
<h3 className="text-base font-bold mb-3 text-center">{dorm.title}</h3>
281+
<ul className="space-y-1.5 px-6">
282+
{dorm.features.map((feature, i) => (
283+
<li key={i} className="flex items-center gap-2 text-xs text-muted-foreground">
284+
<div className="w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0" />
285+
{feature}
286+
</li>
287+
))}
288+
</ul>
289+
</div>
290+
</motion.div>
291+
))}
323292
</div>
324293
</div>
325294
</div>
@@ -331,46 +300,51 @@ export default function CampusLifePage() {
331300
<h2 className="text-3xl font-display font-bold mb-4">Life at BIT</h2>
332301
<p className="text-muted-foreground">Everything you need within walking distance.</p>
333302
</div>
334-
<div className="flex flex-wrap gap-6">
303+
<motion.div
304+
variants={containerVariants}
305+
initial="hidden"
306+
whileInView="visible"
307+
viewport={{ once: true }}
308+
className="grid grid-cols-2 gap-3 md:gap-8"
309+
>
335310
{facilities.map((item, idx) => (
336311
<motion.div
337312
key={idx}
338-
initial={{ opacity: 0, scale: 0.95 }}
339-
whileInView={{ opacity: 1, scale: 1 }}
340-
viewport={{ once: true, margin: "-50px" }}
341-
transition={{ delay: idx * 0.05 }}
342-
className="bg-white/60 backdrop-blur-sm p-6 rounded-2xl border border-white/40 hover:bg-white/80 transition-colors w-[calc(50%-0.75rem)] md:w-[calc(33.333%-1rem)]"
313+
variants={itemVariants}
314+
className="bg-white/50 backdrop-blur-md border border-white/60 rounded-2xl md:rounded-3xl p-4 md:p-8 hover:shadow-xl transition-all duration-300 group"
343315
>
344-
<item.icon className="w-8 h-8 text-primary mb-4" />
345-
<h3 className="font-bold text-lg mb-2">{item.title}</h3>
346-
<p className="text-sm text-muted-foreground leading-relaxed">{item.desc}</p>
316+
<div className="w-9 h-9 md:w-12 md:h-12 bg-primary/10 rounded-xl md:rounded-2xl flex items-center justify-center mb-3 md:mb-6 group-hover:scale-110 transition-transform">
317+
<item.icon className="w-4 h-4 md:w-6 md:h-6 text-primary" />
318+
</div>
319+
<h3 className="text-sm md:text-2xl font-bold font-display mb-1.5 md:mb-3">{item.title}</h3>
320+
<p className="text-xs md:text-base text-muted-foreground leading-relaxed">{item.desc}</p>
347321
</motion.div>
348322
))}
349-
</div>
323+
</motion.div>
350324
</div>
351325

352326
{/* Gallery */}
353-
<div>
327+
<div className="mb-32">
354328
<h2 className="text-3xl font-display font-bold mb-12 text-center">Campus Moments</h2>
355-
<div className="mb-24 flex flex-wrap gap-4 md:gap-6">
356-
{galleryImages.map((img, idx) => (
329+
<div className="columns-2 md:columns-3 gap-4 md:gap-6">
330+
{galleryImages.map((item, idx) => (
357331
<motion.div
358332
key={idx}
359333
initial={{ opacity: 0, scale: 0.9 }}
360334
whileInView={{ opacity: 1, scale: 1 }}
361335
viewport={{ once: true, margin: "-50px" }}
362336
transition={{ delay: idx * 0.1 }}
363-
className="relative rounded-2xl overflow-hidden group w-[calc(50%-0.5rem)] md:w-[calc(33.333%-1rem)]"
337+
className="relative rounded-2xl overflow-hidden group break-inside-avoid mb-6"
364338
>
365339
<div className="absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10" />
366340
<BlurImage
367-
src={img.src}
368-
alt={img.caption}
341+
src={item.src}
342+
alt={item.caption}
369343
className="w-full h-auto object-cover transform group-hover:scale-105 transition-transform duration-700"
370344
sizes="(max-width: 768px) 100vw, 33vw"
371345
/>
372346
<div className="absolute bottom-0 left-0 right-0 p-6 translate-y-full group-hover:translate-y-0 transition-transform duration-300 z-20">
373-
<p className="text-white font-medium text-sm">{img.caption}</p>
347+
<p className="text-white font-medium text-sm">{item.caption}</p>
374348
</div>
375349
</motion.div>
376350
))}

0 commit comments

Comments
 (0)