implemented vertical slider from Ecem Gokdogan
This commit is contained in:
+22
@@ -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} />;
|
||||
}
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user