implemented vertical slider from Ecem Gokdogan

This commit is contained in:
Joshua Ashton
2024-12-21 16:05:49 -07:00
parent 874e88388a
commit 14c348af18
34 changed files with 1043 additions and 18502 deletions
+22
View File
@@ -0,0 +1,22 @@
import React, { useRef, useState } from "react";
import VerticalSlider from "./components/VerticalSlider";
import "./styles.css";
export default function App() {
const data = [
{
title: "Test Header",
description: "A description of some length. Lorem ipsum this shit.",
color: "purple",
image: "/images/landscape.jpg",
alt: "A pretty background.",
},
{
title: "Another one",
description: "A description of some length. Lorem ipsum this shit.",
color: "purple",
image: "/images/landscape.jpg",
alt: "A pretty background.",
},
];
return <VerticalSlider slideData={data} />;
}
+47
View File
@@ -0,0 +1,47 @@
import React, { useRef, useState } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import { Mousewheel, Pagination } from "swiper/modules";
import "swiper/css";
import "swiper/css/pagination";
import "../styles.css";
export default function VerticalSlider({ slideData }) {
return (
<>
<Swiper
modules={[Mousewheel, Pagination]}
direction={"vertical"}
speed={800}
loop={true}
pagination={{
clickable: true,
}}
mousewheel={{
thresholdDelta: 50,
sensitivity: 1,
}}
>
{slideData.map((slide, index) => (
<SwiperSlide key={index}>
{({ isActive }) => (
<div className="slide-container">
<div className="info">
<h1 data-color={slide.color}>{slide.title}</h1>
<p>{slide.description}</p>
</div>
<div className="item">
<div
className={`circle ${isActive ? "animated-circle" : ""}`}
data-item={slide.color}
></div>
<img src={slide.image} alt={slide.alt} />
</div>
</div>
)}
</SwiperSlide>
))}
</Swiper>
</>
);
}
+6
View File
@@ -0,0 +1,6 @@
import React from "react";
import ReactDOM from "react-dom";
import App from "./App.jsx";
ReactDOM.render(<App />, document.getElementById("app"));
+261
View File
@@ -0,0 +1,261 @@
@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap");
:root {
--width: 480px;
}
*,
*::before,
*::after {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: "Lato", sans-serif;
}
html,
body {
position: relative;
height: 100%;
background: #222;
}
.swiper {
width: 100%;
height: 100vh;
overflow: hidden;
}
.swiper-slide .slide-container {
display: grid;
grid-template-columns: 48% 50%;
grid-template-rows: 100%;
column-gap: 30px;
height: 100%;
}
.info {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-left: 120px;
text-align: center;
opacity: 0;
}
.info h1 {
font-size: clamp(2.25rem, 3.5vw, 8rem);
font-weight: 600;
letter-spacing: 2px;
width: max-content;
margin-bottom: 32px;
opacity: 0;
}
[data-color="purple"] {
color: #7385ca;
}
.info p {
font-size: clamp(1.1rem, 2vw, 1.5rem);
color: #bfbec1;
font-weight: 300;
line-height: 1.5;
opacity: 0;
}
.swiper-slide-active .info {
opacity: 1;
}
.swiper-slide-active .info h1,
.swiper-slide-active .info p {
animation: moveDown 0.8s ease-in forwards;
}
.swiper-slide-active .info h1 {
animation-delay: 0.2s;
}
.swiper-slide-active .info p {
animation-delay: 1s;
}
@keyframes moveDown {
0% {
transform: translateY(-20px);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
.item {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: var(--width);
aspect-ratio: 1/1;
margin: auto;
}
.circle {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
}
.circle[data-item="purple"] {
border: 1px solid #8092d9;
}
.circle::before {
content: "";
position: absolute;
left: 0;
width: 100%;
height: 0;
z-index: -1;
}
.circle[data-item="purple"]::before {
background: linear-gradient(
to left bottom,
#8092d9,
#677abf,
#4e63a6,
#344d8d,
#163875
);
}
.animated-circle::before {
animation: colorTransition 2s linear forwards;
}
@keyframes colorTransition {
0% {
height: 0;
top: -50%;
}
100% {
height: 100%;
top: 0%;
}
}
.swiper-slide img {
display: block;
width: calc(var(--width) / 2);
filter: drop-shadow(5px 6px 5px rgba(36, 36, 42, 0.5));
user-select: none;
opacity: 0;
z-index: 1;
}
.swiper-slide-active img {
animation: itemMoveDown 0.8s ease-in forwards 1.4s;
}
@keyframes itemMoveDown {
0% {
transform: translateY(calc(var(--width) / -5));
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
.swiper-paginatino-bullet {
width: 18px;
height: 18px;
background-color: #7e7e7e;
border-radius: 50%;
transition: all 0.6s ease-in-out;
}
.swiper-pagination-bullet-active {
height: 36px;
background-color: #717271;
border-radius: 14px;
}
@media (max-width: 1250px) {
.info {
padding-left: 90px;
}
}
@media (max-width: 1075px) {
:root {
--width: 400px;
}
.swiper-slide .slide-container {
column-gap: 20px;
}
.info {
padding-left: 60px;
}
}
@media (max-width: 990px) {
:root {
--width: 360px;
}
.info {
padding-left: 30px;
}
}
@media (max-width: 790px) {
.swiper-slide .slide-container {
grid-template-columns: 100%;
grid-template-rows: 60% 35%;
column-gap: 0;
grid-template-areas:
"item"
"info";
padding: 30px;
}
.item {
grid-area: item;
}
.info {
grid-area: info;
}
.info h1 {
margin-bottom: 16px;
width: unset;
line-height: 1.1;
}
.swiper-pagination-bullet {
width: 14px;
height: 14px;
}
.swiper-pagination-bullet-active {
height: 28px;
}
}
@media (max-width: 485px) {
:root {
--width: 280px;
}
.info p {
line-height: 1.4;
}
}