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">
|
||||
<Navbar />
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,14 @@ import { FunctionComponent } from "react";
|
|||
import './greeting.css';
|
||||
import WelcomeText from './WelcomeText';
|
||||
import Socials from './Socials';
|
||||
import ScrollHint from './ScrollHint';
|
||||
|
||||
const Greeting: FunctionComponent = () => {
|
||||
return (
|
||||
<div className="greeting-area">
|
||||
<WelcomeText />
|
||||
<Socials />
|
||||
<ScrollHint />
|
||||
</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 = () => {
|
||||
return (
|
||||
<div className="greeting-socials">
|
||||
<SocialsEntry 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 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 image="/assets/email.svg" link="mailto:me@janderedev.xyz" text="me@janderedev.xyz" redactUntilClick={true} />
|
||||
<SocialsEntry index={0} image="/assets/revolt_r.svg" link="https://rvlt.gg/jan" text="@jan" />
|
||||
<SocialsEntry index={1} image="/assets/discord.svg" link="https://discord.gg/4pZgvqgYJ8" text={"J\u0430n#2756"} />
|
||||
<SocialsEntry index={2} image="/assets/github.svg" link="https://github.com/janderedev" text="JandereDev" />
|
||||
<SocialsEntry index={3} image="/assets/misskey.svg" link="https://miruku.cafe/@jan" text="@jan@miruku.cafe" />
|
||||
<SocialsEntry index={4} image="/assets/email.svg" link="==gCtFWasR3b60WZApWYuRWZyVGZlZnL4lne" text="K0WZApWYuRWZyVGZlZnL4lne" redactUntilClick={true} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,24 +1,37 @@
|
|||
import { FunctionComponent, useState } from "react";
|
||||
import { FunctionComponent, useEffect, useState } from "react";
|
||||
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 [ content, setContent ] = useState(params.redactUntilClick ? 'Click to reveal' : params.text);
|
||||
const [ href, setHref ] = useState(params.redactUntilClick ? '#' : params.link);
|
||||
const [ allowClick, setAllowClick ] = useState(!params.redactUntilClick);
|
||||
const [ hidden, setHidden ] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => setHidden(false), 100 * params.index + 500);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="greeting-socials-container">
|
||||
<div className={`greeting-socials-container ${hidden ? 'hidden' : ''}`}>
|
||||
<img className="greeting-socials-image" src={params.image} />
|
||||
<a
|
||||
href={href}
|
||||
className="greeting-socials-text"
|
||||
className={`greeting-socials-text`}
|
||||
onClick={params.redactUntilClick ? (event) => {
|
||||
if (!allowClick) event.preventDefault();
|
||||
setContent(params.text);
|
||||
setHref(params.link);
|
||||
setAllowClick(true);
|
||||
|
||||
// Lets hope that this stops most scrapers
|
||||
setContent(reverse(atob(reverse(params.text))));
|
||||
setHref(reverse(atob(reverse(params.link))));
|
||||
} : undefined}
|
||||
>
|
||||
{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 {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
|
@ -39,6 +64,12 @@
|
|||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
padding-bottom: 8px;
|
||||
opacity: 1;
|
||||
transition: opacity .5s;
|
||||
}
|
||||
|
||||
.greeting-socials-container.hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.greeting-socials-image {
|
||||
|
@ -62,3 +93,34 @@
|
|||
color: #dddddd;
|
||||
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