Skip to content

Commit

Permalink
add scrollytelling
Browse files Browse the repository at this point in the history
  • Loading branch information
CloudLun committed Mar 18, 2024
1 parent 349d69d commit 3206201
Show file tree
Hide file tree
Showing 12 changed files with 252 additions and 12 deletions.
6 changes: 4 additions & 2 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ import { MarkerProvider } from '@/contexts/MarkerContext'
import Map from '@/components/map/Map'
import InfoPage from '@/components/infoPage/InfoPage'
import StreetView from '@/components/streetView/StreetView'
import Narrative from '@/components/narrative/Narrative'

export default function Home() {
return (
<main className="relative w-[100vw] h-[100vh] overflow-y-hidden">
<MapProvider>
<StreetViewProvider>
<MarkerProvider>
<Map />
{/* <Map />
<InfoPage />
<StreetView />
<StreetView /> */}
<Narrative />
</MarkerProvider>
</StreetViewProvider>
</MapProvider>
Expand Down
48 changes: 48 additions & 0 deletions components/narrative/Narrative.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useState, useContext, useEffect } from "react";



import Image from "next/image";
import Slider from "./Slider";
import Satellite from "./Satellite";


const Narrative = () => {
return (
<div className="w-full h-[100vh] overflow-y-auto">
{/* <Scrollama offset={0.5} onStepEnter={onStepEnter}> */}
{/* </Scrollama> */}
<div className="relative w-full h-full">
<Image
src="/imgs/narrative_one.png"
layout="fill"
alt="one"
/>
<div className="absolute right-12 bottom-16 px-5 py-7 w-[36rem] bg-black bg-opacity-[.65] rounded-lg">
<h1 className="font-semibold text-[6.25rem]">1.3 million</h1>
<p className="mb-[1rem] font-semibold text-[2rem]">New York City residents live within or directly adjacent to the floodplain. Flood damage is extensive, expensive, and often times predictable</p>
<p className="font-semibold text-[1rem]">Source: Info, Photo</p>
</div>
</div>
<Satellite />
<div className="relative w-full h-full">
<Image
src="/imgs/narrative_four.png"
layout="fill"
alt="two"
/>
<Image
src="/logos/floodgen_logo_white.png"
width={155}
height={38.75}
alt="logos_white"
className="absolute left-8 top-12"
/>
</div>
<Slider />

</div>
)
}

export default Narrative
56 changes: 56 additions & 0 deletions components/narrative/Satellite.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { useState } from 'react'
import Image from 'next/image'

//@ts-ignore
import { Scrollama, Step } from "react-scrollama";



const Satellite = () => {

const [_currentStepIndex, setCurrentStepIndex] = useState<number>(0);
const onStepEnter = (data: number) => {
setCurrentStepIndex(data)
}
return (
<div className="relative w-full h-full">
<Image
src="/imgs/narrative_two.png"
layout="fill"
alt="two"
/>
<Image
src="/logos/floodgen_logo_white.png"
width={155}
height={38.75}
alt="logos_white"
className="absolute left-8 top-12"
/>
<Scrollama offset={0.5} onStepEnter={onStepEnter}>
<Step data={1}>
<div className="absolute right-12 bottom-16 px-5 py-7 w-[36rem] bg-black bg-opacity-[.65] rounded-lg">
<p className="mb-[1rem] font-semibold text-[2rem]">Maps of predicted flooding are helpful planning tools, but aerial views distance viewers from its potential impact</p>
</div>
</Step>
<Step data={2}>
<>
<div className="absolute left-0 top-0 w-full h-full bg-black bg-opacity-40"></div>
<div className="absolute left-8 bottom-28 p-5 w-[52.75rem] bg-black bg-opacity-[.65] rounded-lg">
<Image
src="/imgs/narrative_six.png"
width={804}
height={423.24}
alt="narrative_six"
/>
<p className="mt-2 font-semibold text-[2rem]">If we show the reality of predicted flooding through photorealistic imagery, could people be more prepared?</p>
</div>
</>
</Step>

</Scrollama>
</div>

)
}

export default Satellite
79 changes: 79 additions & 0 deletions components/narrative/Slider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"use client";

import Image from "next/image";
import { useState } from "react";
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/16/solid";

const Slider = () => {
const [sliderPosition, setSliderPosition] = useState(50);
const [isDragging, setIsDragging] = useState(false);

const handleMove = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
if (!isDragging) return;

const rect = event.currentTarget.getBoundingClientRect();
const x = Math.max(0, Math.min(event.clientX - rect.left, rect.width));
const percent = Math.max(0, Math.min((x / rect.width) * 100, 100));

setSliderPosition(percent);
};

const handleMouseDown = () => {
setIsDragging(true);
};

const handleMouseUp = () => {
setIsDragging(false);
};

return (
<div className="w-full h-full relative" onMouseUp={handleMouseUp}>
<div
className="relative w-full h-full overflow-hidden select-none"
onMouseMove={handleMove}
onMouseDown={handleMouseDown}
>
<Image
alt=""
fill
priority
src="/imgs/narrative_six.png"
/>

<div
className="absolute top-0 left-0 right-0 w-full h-full overflow-hidden select-none"
style={{ clipPath: `inset(0 ${100 - sliderPosition}% 0 0)` }}
>
<Image
fill
priority
alt=""
src="/imgs/narrative_four.png"
/>
</div>
<div
className="absolute top-0 bottom-0 w-1 bg-white cursor-ew-resize"
style={{
left: `calc(${sliderPosition}% - 1px)`,
}}
>
<div className="bg-white absolute rounded-full w-14 h-14 -left-[calc(50%_+_24px)] top-[calc(50%_-_5px)]">
<ChevronRightIcon width={24} height={24} className="absolute right-0 top-[calc(50%_-_12px)] text-black" />
<ChevronLeftIcon width={24} height={24} className="absolute left-0 top-[calc(50%_-_12px)] text-black" />

</div>
</div>
<Image
src="/logos/floodgen_logo_white.png"
width={155}
height={38.75}
alt="logos_white"
className="absolute left-8 top-12"
/>
</div>
</div>
);
};


export default Slider
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "export",
basePath: '/floodgen',
// basePath: '/floodgen',
reactStrictMode: true,
env: {
BASE_URL: process.env.NEXT_PUBLIC_MAPBOX_API_KEY,
Expand Down
67 changes: 59 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@
},
"dependencies": {
"@heroicons/react": "^2.1.1",
"@img-comparison-slider/react": "^8.0.1",
"@types/geojson": "^7946.0.14",
"@types/react-scroll": "^1.8.10",
"axios": "^1.6.7",
"dotenv": "^16.4.3",
"img-comparison-slider": "^8.0.6",
"mapbox-gl": "^3.1.0",
"next": "14.0.4",
"react": "^18",
"react-dom": "^18",
"react-responsive": "^9.0.2"
"react-responsive": "^9.0.2",
"react-scrollama": "^2.3.3"
},
"devDependencies": {
"@types/mapbox-gl": "^2.7.19",
Expand Down
Binary file added public/imgs/narrative_four.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgs/narrative_one.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgs/narrative_six.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/imgs/narrative_two.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/logos/floodgen_logo_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 3206201

Please sign in to comment.