hampter
This commit is contained in:
parent
5096d82ca4
commit
4250792684
21
public/assets/pointer_down.svg
Normal file
21
public/assets/pointer_down.svg
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="200"
|
||||||
|
height="100"
|
||||||
|
viewBox="0 0 52.916665 26.458334"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<g
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="M 0,0 25,15 50,0"
|
||||||
|
id="path970" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 539 B |
|
@ -7,7 +7,12 @@ function App() {
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Greeting />
|
<Greeting />
|
||||||
<div style={{ "height": "100vh" }}></div>
|
<div style={{ "height": "100vh" }}>
|
||||||
|
<img
|
||||||
|
src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fstyles.redditmedia.com%2Ft5_3gvs7p%2Fstyles%2FcommunityIcon_q2rzyba8wg161.png%3Fwidth%3D256%26s%3D1790af2f987e48c21d8f940258e02d6c1005661f&f=1&nofb=1"
|
||||||
|
style={{ position: "relative", left: "50%", transform: "translateX(-50%)", top: "20%" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,14 @@ import { FunctionComponent } from "react";
|
||||||
import './greeting.css';
|
import './greeting.css';
|
||||||
import WelcomeText from './WelcomeText';
|
import WelcomeText from './WelcomeText';
|
||||||
import Socials from './Socials';
|
import Socials from './Socials';
|
||||||
|
import ScrollHint from './ScrollHint';
|
||||||
|
|
||||||
const Greeting: FunctionComponent = () => {
|
const Greeting: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<div className="greeting-area">
|
<div className="greeting-area">
|
||||||
<WelcomeText />
|
<WelcomeText />
|
||||||
<Socials />
|
<Socials />
|
||||||
|
<ScrollHint />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
22
src/main_page/ScrollHint.tsx
Normal file
22
src/main_page/ScrollHint.tsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import { FunctionComponent, useEffect, useState } from "react";
|
||||||
|
import './greeting.css';
|
||||||
|
|
||||||
|
const ScrollHint: FunctionComponent = () => {
|
||||||
|
const [arrowHidden, setArrowHidden] = useState(true);
|
||||||
|
const [textHidden, setTextHidden] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => setArrowHidden(false), 2000);
|
||||||
|
setTimeout(() => setTextHidden(false), 3000);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="scroll-hint-container">
|
||||||
|
<span className={`${textHidden ? 'hidden' : ''}`}>Scroll down</span>
|
||||||
|
<br/>
|
||||||
|
<img src="/assets/pointer_down.svg" className={`${arrowHidden ? 'hidden' : ''}`} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ScrollHint;
|
|
@ -5,11 +5,11 @@ import SocialsEntry from './SocialsEntry';
|
||||||
const Socials: FunctionComponent = () => {
|
const Socials: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<div className="greeting-socials">
|
<div className="greeting-socials">
|
||||||
<SocialsEntry image="/assets/revolt_r.svg" link="https://rvlt.gg/jan" text="@jan" />
|
<SocialsEntry index={0} image="/assets/revolt_r.svg" link="https://rvlt.gg/jan" text="@jan" />
|
||||||
<SocialsEntry image="/assets/discord.svg" link="https://discord.gg/4pZgvqgYJ8" text={"J\u0430n#2756"} />
|
<SocialsEntry index={1} image="/assets/discord.svg" link="https://discord.gg/4pZgvqgYJ8" text={"J\u0430n#2756"} />
|
||||||
<SocialsEntry image="/assets/github.svg" link="https://github.com/janderedev" text="JandereDev" />
|
<SocialsEntry index={2} image="/assets/github.svg" link="https://github.com/janderedev" text="JandereDev" />
|
||||||
<SocialsEntry image="/assets/misskey.svg" link="https://miruku.cafe/@jan" text="@jan@miruku.cafe" />
|
<SocialsEntry index={3} image="/assets/misskey.svg" link="https://miruku.cafe/@jan" text="@jan@miruku.cafe" />
|
||||||
<SocialsEntry image="/assets/email.svg" link="mailto:me@janderedev.xyz" text="me@janderedev.xyz" redactUntilClick={true} />
|
<SocialsEntry index={4} image="/assets/email.svg" link="==gCtFWasR3b60WZApWYuRWZyVGZlZnL4lne" text="K0WZApWYuRWZyVGZlZnL4lne" redactUntilClick={true} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,37 @@
|
||||||
import { FunctionComponent, useState } from "react";
|
import { FunctionComponent, useEffect, useState } from "react";
|
||||||
import './greeting.css';
|
import './greeting.css';
|
||||||
|
|
||||||
type Params = { image: string, link: string, text: string, redactUntilClick?: boolean };
|
function reverse(value: string) {
|
||||||
|
return Array.from(
|
||||||
|
String(value || '')
|
||||||
|
).reverse().join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
type Params = { image: string, link: string, text: string, redactUntilClick?: boolean, index: number };
|
||||||
|
|
||||||
const SocialsEntry: FunctionComponent<Params> = (params: Params) => {
|
const SocialsEntry: FunctionComponent<Params> = (params: Params) => {
|
||||||
const [ content, setContent ] = useState(params.redactUntilClick ? 'Click to reveal' : params.text);
|
const [ content, setContent ] = useState(params.redactUntilClick ? 'Click to reveal' : params.text);
|
||||||
const [ href, setHref ] = useState(params.redactUntilClick ? '#' : params.link);
|
const [ href, setHref ] = useState(params.redactUntilClick ? '#' : params.link);
|
||||||
const [ allowClick, setAllowClick ] = useState(!params.redactUntilClick);
|
const [ allowClick, setAllowClick ] = useState(!params.redactUntilClick);
|
||||||
|
const [ hidden, setHidden ] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => setHidden(false), 100 * params.index + 500);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="greeting-socials-container">
|
<div className={`greeting-socials-container ${hidden ? 'hidden' : ''}`}>
|
||||||
<img className="greeting-socials-image" src={params.image} />
|
<img className="greeting-socials-image" src={params.image} />
|
||||||
<a
|
<a
|
||||||
href={href}
|
href={href}
|
||||||
className="greeting-socials-text"
|
className={`greeting-socials-text`}
|
||||||
onClick={params.redactUntilClick ? (event) => {
|
onClick={params.redactUntilClick ? (event) => {
|
||||||
if (!allowClick) event.preventDefault();
|
if (!allowClick) event.preventDefault();
|
||||||
setContent(params.text);
|
|
||||||
setHref(params.link);
|
|
||||||
setAllowClick(true);
|
setAllowClick(true);
|
||||||
|
|
||||||
|
// Lets hope that this stops most scrapers
|
||||||
|
setContent(reverse(atob(reverse(params.text))));
|
||||||
|
setHref(reverse(atob(reverse(params.link))));
|
||||||
} : undefined}
|
} : undefined}
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
|
|
|
@ -1,3 +1,28 @@
|
||||||
|
@keyframes scroll-hint-arrow {
|
||||||
|
0% {
|
||||||
|
transform: translateY(-50%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: translateY(10%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scroll-hint-text {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.greeting-area {
|
.greeting-area {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
@ -39,6 +64,12 @@
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.greeting-socials-container.hidden {
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.greeting-socials-image {
|
.greeting-socials-image {
|
||||||
|
@ -62,3 +93,34 @@
|
||||||
color: #dddddd;
|
color: #dddddd;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scroll-hint-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
bottom: 5%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-hint-container img {
|
||||||
|
position: relative;
|
||||||
|
height: 30px;
|
||||||
|
animation-name: scroll-hint-arrow;
|
||||||
|
animation-duration: 5s;
|
||||||
|
animation-direction: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-hint-container img.hidden, .scroll-hint-container span.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-hint-container span {
|
||||||
|
position: relative;
|
||||||
|
animation-name: scroll-hint-text;
|
||||||
|
animation-duration: 5s;
|
||||||
|
animation-direction: normal;
|
||||||
|
bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue