133 lines
7.0 KiB
React
133 lines
7.0 KiB
React
import React, { useState, useRef, useEffect } from 'react';
|
|
import { MoveHorizontal } from 'lucide-react';
|
|
import CompareNew from '../assets/images/compare-new.png';
|
|
import CompareOld from '../assets/images/compare-old.png';
|
|
|
|
export const ComparisonSlider = () => {
|
|
const [sliderPos, setSliderPos] = useState(50);
|
|
const containerRef = useRef(null);
|
|
|
|
const handleMove = (e) => {
|
|
if (!containerRef.current) return;
|
|
|
|
const rect = containerRef.current.getBoundingClientRect();
|
|
const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
|
|
const percentage = (x / rect.width) * 100;
|
|
|
|
setSliderPos(percentage);
|
|
};
|
|
|
|
const handleTouchMove = (e) => {
|
|
if (!containerRef.current) return;
|
|
|
|
const rect = containerRef.current.getBoundingClientRect();
|
|
const touch = e.touches[0];
|
|
const x = Math.max(0, Math.min(touch.clientX - rect.left, rect.width));
|
|
const percentage = (x / rect.width) * 100;
|
|
|
|
setSliderPos(percentage);
|
|
};
|
|
|
|
return (
|
|
<div className="w-full max-w-5xl mx-auto my-20">
|
|
<h2 className="text-4xl font-black text-center mb-10 text-zinc-900 dark:text-white">
|
|
The <span className="text-zinc-400">Old</span> vs The <span className="text-blue-500">LynkedUp</span> Way
|
|
</h2>
|
|
|
|
<div
|
|
ref={containerRef}
|
|
className="relative w-full h-[400px] md:h-[600px] rounded-3xl overflow-hidden cursor-ew-resize shadow-2xlSelect-none group"
|
|
onMouseMove={handleMove}
|
|
onTouchMove={handleTouchMove}
|
|
>
|
|
{/* AFTER IMAGE (New Way) - Background */}
|
|
<div className="absolute inset-0 w-full h-full">
|
|
<img
|
|
src={CompareNew}
|
|
alt="The New Way"
|
|
className="w-full h-full object-cover"
|
|
/>
|
|
<div className="absolute top-10 right-10 flex flex-col items-end space-y-4 select-none">
|
|
<span className="text-xl md:text-2xl font-black text-white bg-black/50 backdrop-blur-md px-4 py-2 rounded-xl border border-blue-500/50">
|
|
Our Way
|
|
</span>
|
|
<div className="text-right space-y-2">
|
|
{[
|
|
"15-Minute Drone Scan",
|
|
"Zero Safety Risk",
|
|
"AI + Thermal Imaging",
|
|
"~30% Lower Costs",
|
|
"~ 60% faster lead conversion",
|
|
"~ Deploy Reps with confidence",
|
|
"~ Evidence-driven damage detection unlocks Revenue"
|
|
].map((text, i) => (
|
|
<div key={i} className="flex items-center justify-end space-x-2 bg-black/40 backdrop-blur-sm px-3 py-1 rounded-lg border border-blue-500/20">
|
|
<span className="text-sm md:text-base font-bold text-white">{text}</span>
|
|
<div className="w-5 h-5 rounded-full bg-blue-500 flex items-center justify-center">
|
|
<svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" /></svg>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* BEFORE IMAGE (Old Way) - Clipped Overlay */}
|
|
<div
|
|
className="absolute inset-0 w-full h-full overflow-hidden border-r-4 border-white shadow-2xl"
|
|
style={{ width: `${sliderPos}%` }}
|
|
>
|
|
<img
|
|
src={CompareOld}
|
|
alt="The Old Way"
|
|
className="w-full h-full object-cover max-w-none grayscale sepia-[0.3]"
|
|
style={{ width: containerRef.current?.offsetWidth }}
|
|
/>
|
|
{/* Overlay Text visible only when this side is dominant */}
|
|
<div className="absolute top-10 left-10 flex flex-col items-start space-y-4 select-none" style={{ opacity: Math.max(0, (sliderPos - 10) / 40) }}>
|
|
<span className="text-xl md:text-2xl font-black text-zinc-200 bg-black/60 backdrop-blur-md px-4 py-2 rounded-xl border border-red-500/50">
|
|
The Old Way
|
|
</span>
|
|
<div className="text-left space-y-2">
|
|
{[
|
|
"Dangerous Ladders & Falls",
|
|
"Guesswork Based Estimates",
|
|
"Slow Turnaround Times",
|
|
"Hidden Material Costs"
|
|
].map((text, i) => (
|
|
<div key={i} className="flex items-center space-x-2 bg-black/50 backdrop-blur-sm px-3 py-1 rounded-lg border border-red-500/20">
|
|
<div className="w-5 h-5 rounded-full bg-red-500/80 flex items-center justify-center">
|
|
<svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M6 18L18 6M6 6l12 12" /></svg>
|
|
</div>
|
|
<span className="text-sm md:text-base font-bold text-zinc-300">{text}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Slider Handle */}
|
|
<div
|
|
className="absolute top-0 bottom-0 w-1 bg-white cursor-ew-resize hidden md:flex items-center justify-center shadow-[0_0_20px_rgba(0,0,0,0.5)]"
|
|
style={{ left: `${sliderPos}%` }}
|
|
>
|
|
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center shadow-xl transform transition-transform group-hover:scale-110">
|
|
<MoveHorizontal className="text-black" size={24} />
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile Slider Handle (Always visible comparison line) */}
|
|
<div
|
|
className="absolute top-0 bottom-0 w-1 bg-white/50 md:hidden"
|
|
style={{ left: `${sliderPos}%` }}
|
|
/>
|
|
|
|
{/* Instructions Overlay (Fades out on interaction) */}
|
|
<div className="absolute bottom-6 left-1/2 -translate-x-1/2 text-white/80 text-sm font-medium bg-black/40 px-4 py-2 rounded-full backdrop-blur-sm pointer-events-none">
|
|
Drag to compare
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|