aboutsummaryrefslogtreecommitdiff
path: root/front/src
diff options
context:
space:
mode:
Diffstat (limited to 'front/src')
-rw-r--r--front/src/app.css41
-rw-r--r--front/src/app.tsx3
-rw-r--r--front/src/components/animated_bg.tsx114
-rw-r--r--front/src/components/navbar.css7
-rw-r--r--front/src/pages/games.tsx2
-rw-r--r--front/src/pages/home.tsx26
-rw-r--r--front/src/pages/projects.tsx14
7 files changed, 183 insertions, 24 deletions
diff --git a/front/src/app.css b/front/src/app.css
index b4086a2..b16cfea 100644
--- a/front/src/app.css
+++ b/front/src/app.css
@@ -24,6 +24,25 @@
filter: drop-shadow(0 0 2em #673ab8aa);
}
+/* fade in */
+@keyframes fade-in {
+ 0% {
+ opacity: 0;
+ transform: translateY(1em);
+ }
+ 60% {
+ transform: translateY(-0.2em);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.main-info > * {
+ animation: fade-in 0.2s ease-in;
+}
+
.main-info {
text-align: center;
}
@@ -64,7 +83,21 @@
color: #e5c07b;
}
+.back-shadows {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: -1;
+ background: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, var(--color-bg) 10%, var(--color-bg) 90%, rgba(0, 0, 0, 0) 100%);
+}
+
@media (max-width: 480px) {
+ .back-shadows {
+ margin: auto;
+ max-width: 80%;
+ }
.main-info-title {
font-size: 32pt;
}
@@ -75,6 +108,10 @@
}
@media (max-width: 1150px) and (min-width: 480px) {
+ .back-shadows {
+ margin: auto;
+ max-width: 60%;
+ }
.main-info-title {
font-size: 42pt;
}
@@ -85,6 +122,10 @@
}
@media (min-width: 1150px) {
+ .back-shadows {
+ margin: auto;
+ max-width: 40%;
+ }
.main-info-title {
font-size: 42pt;
}
diff --git a/front/src/app.tsx b/front/src/app.tsx
index 5ba8e6f..ba081c9 100644
--- a/front/src/app.tsx
+++ b/front/src/app.tsx
@@ -6,6 +6,7 @@ import Home from './pages/home'
import { Router, Route, CustomHistory } from 'preact-router';
import Projects from './pages/projects';
import { HashHistory, createHashHistory } from 'history';
+import { AnimatedBg } from './components/animated_bg';
const hashHistoryAdapter = (hashHistory: HashHistory): CustomHistory => {
return {
@@ -21,6 +22,7 @@ export function App() {
return (
<>
<Navbar />
+ <div class="back-shadows"></div>
<div id="app-main">
<Router history={history}>
<Route path="/" component={Home} />
@@ -28,6 +30,7 @@ export function App() {
<Route path="/games" component={Games} />
<Route path="/projects" component={Projects} />
</Router>
+ <AnimatedBg />
</div>
</>
)
diff --git a/front/src/components/animated_bg.tsx b/front/src/components/animated_bg.tsx
new file mode 100644
index 0000000..6a8ab3a
--- /dev/null
+++ b/front/src/components/animated_bg.tsx
@@ -0,0 +1,114 @@
+import { Shaders, Node, GLSL } from "gl-react";
+import { Surface } from "gl-react-dom";
+import React from "preact/compat";
+import { PropsWithChildren } from "preact/compat";
+
+const shaders = Shaders.create({
+ letters: {
+ frag: GLSL`
+precision highp float;
+varying vec2 uv;
+uniform vec3 color;
+uniform sampler2D t;
+uniform float time;
+uniform vec2 tiles;
+uniform float symbol_count;
+
+vec2 map_to_symbol_uv(vec2 image_coord, float symbol_index) {
+ float symbol_width = 1.0 / symbol_count;
+ float symbol_height = 1.0;
+ float symbol_x = symbol_index * symbol_width;
+ return vec2(symbol_x + image_coord.x * symbol_width, image_coord.y * symbol_height);
+}
+
+vec2 tile_index(vec2 p, vec2 tiles) {
+ return vec2(floor(p.x * tiles.x), floor(p.y * tiles.y));
+}
+
+vec2 tilefy (vec2 p, vec2 tiles) {
+ return vec2(fract(p.x * tiles.x), fract(p.y * tiles.y));
+}
+
+float randf(float n) {
+ return fract(sin(n) * 43758.5453123);
+}
+
+void main() {
+ vec2 tile = tile_index(uv, tiles);
+ float tilerand = randf(tile.x + tile.y * tiles.x);
+ float v = tilerand + randf(floor(tilerand * time));
+ float diff = fract(tilerand * time);
+ float s = floor(v * 9.0);
+ vec2 tp = tilefy(uv, tiles);
+ vec2 tp_center = vec2(0.5, 0.5);
+ float d = distance(tp, tp_center);
+ float scale = min(sin(diff * 3.1415) * 1.2, 1.0);
+ tp = tp_center + (tp - tp_center) / scale;
+ if (tp.x < 0.0 || tp.x > 1.0 || tp.y < 0.0 || tp.y > 1.0) {
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
+ return;
+ }
+ vec2 p = map_to_symbol_uv(tp, mod(s, symbol_count));
+ vec4 c = texture2D(t, p);
+ c.rgb *= color;
+ c.a *= uv.y * 4.0;
+ gl_FragColor = vec4(c.rgb * c.a, c.a);
+}
+`
+ }
+});
+
+const fps = 60;
+
+const AnimatedBgInternal = ({ tick }: { tick: number }) => {
+ const t = "/assets/images/symbols.png";
+
+ return (
+ <div style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", zIndex: -10 }}>
+ <Surface width={window.innerWidth} height={window.innerHeight / 2}>
+ <Node
+ shader={shaders.letters}
+ uniforms={{
+ t,
+ color: [42 / 255, 42 / 255, 80 / 255],
+ tiles: [Math.ceil(window.innerWidth / 32), Math.ceil(window.innerHeight / 64)],
+ symbol_count: 9,
+ time: tick / 60
+ }}
+ uniformsOptions={{
+ t: { interpolation: "nearest" }
+ }} />
+ </Surface>
+ </div>
+ );
+}
+
+// a higher order component that provides a tick prop
+// that updates every 1/refreshRate seconds
+//
+// accepts a JSX component as an argument
+const timeLoop = (
+ C: (props: PropsWithChildren<{ tick: number }>) => React.JSX.Element,
+ { refreshRate }: { refreshRate: number }
+) => {
+ return class TimeLoop extends React.Component {
+ interval: any;
+ state = { tick: 0 };
+
+ componentDidMount() {
+ this.interval = setInterval(() => {
+ this.setState({ tick: this.state.tick + 1 });
+ }, 1000 / refreshRate);
+ }
+
+ componentWillUnmount() {
+ clearInterval(this.interval);
+ }
+
+ render() {
+ return <C {...this.props} tick={this.state.tick} />;
+ }
+ };
+}
+
+export const AnimatedBg = timeLoop(AnimatedBgInternal, { refreshRate: fps });
diff --git a/front/src/components/navbar.css b/front/src/components/navbar.css
index 466fdd6..9120052 100644
--- a/front/src/components/navbar.css
+++ b/front/src/components/navbar.css
@@ -1,7 +1,7 @@
/* on big screens, navbar is fixed to the top of the screen */
.navbar-container {
position: fixed;
- background-color: var(--color-bg);
+ /* gradient from top to bottom, full to transparent */
top: 0;
width: 100%;
z-index: 9999;
@@ -16,11 +16,12 @@
}
.navbar {
- margin-top: 20pt;
- margin-bottom: 12pt;
+ padding-top: 20pt;
+ padding-bottom: 12pt;
align-items: center;
justify-content: center;
align-self: center;
+ background: linear-gradient(to bottom, var(--color-bg) 0%, var(--color-bg) 75%, rgba(0, 0, 0, 0) 100%);
}
.navbar-icon {
diff --git a/front/src/pages/games.tsx b/front/src/pages/games.tsx
index 2ff4eff..6d0d2bd 100644
--- a/front/src/pages/games.tsx
+++ b/front/src/pages/games.tsx
@@ -11,7 +11,7 @@ export default function Games() {
Game Projects
</div>
<div class="main-info-subtitle">
- my game projects, mostly from game jams
+ games I've worked on
</div>
<div class="projects-container">
{
diff --git a/front/src/pages/home.tsx b/front/src/pages/home.tsx
index 9b29803..df76b84 100644
--- a/front/src/pages/home.tsx
+++ b/front/src/pages/home.tsx
@@ -9,20 +9,20 @@ export default function Home() {
aka Duckonaut, EchoDuck
</div>
<img src="assets/images/duckpfp.png" class="main-info-image logo grow" />
- </div>
- <div class="about-paragraph">
- <p>
- Hello! I'm a programmer, game designer, and artist. I'm currently a student at the Warsaw University of
- Technology, studying Computer Science. A list of the games I've worked on is in the <a class="games-link"
- href="#/games">games</a> section. Other projects I've been a part of are available in the <a class="projects-link"
- href="#/projects">projects</a> section.
- I also enjoy some lower-level programming and learning about the inner workings of various systems. The main
- technologies I use are <span class="highlight">C#</span>, <span class="highlight">Unity</span>
- , <span class="highlight">Python</span>, <span class="highlight">Rust</span> and <span class="highlight">C</span>,
- although I'm also familiar with <span class="highlight">Godot</span>, <span class="highlight">C++</span>
- , <span class="highlight">Java</span> and some <span class="highlight">JavaScript</span> and <span class="highlight">TypeScript</span>.
- </p>
+ <div class="about-paragraph">
+ <p>
+ Hello! I'm a programmer, game designer, and artist. I'm currently a student at the Warsaw University of
+ Technology, studying Computer Science. A list of the games I've worked on is in the <a class="games-link"
+ href="#/games">games</a> section. Other projects I've been a part of are available in the <a class="projects-link"
+ href="#/projects">projects</a> section.
+ I also enjoy some lower-level programming and learning about the inner workings of various systems. The main
+ technologies I use are <span class="highlight">C#</span>, <span class="highlight">Unity</span>
+ , <span class="highlight">Python</span>, <span class="highlight">Rust</span> and <span class="highlight">C</span>,
+ although I'm also familiar with <span class="highlight">Godot</span>, <span class="highlight">C++</span>
+ , <span class="highlight">Java</span> and some <span class="highlight">JavaScript</span> and <span class="highlight">TypeScript</span>.
+ </p>
+ </div>
</div>
</>
);
diff --git a/front/src/pages/projects.tsx b/front/src/pages/projects.tsx
index ed68529..2753f91 100644
--- a/front/src/pages/projects.tsx
+++ b/front/src/pages/projects.tsx
@@ -13,14 +13,14 @@ export default function Projects() {
<div class="main-info-subtitle">
projects that are not games
</div>
- </div>
- <div class="projects-container">
- {
- projects.map((project) => (
- Project(project)
- ))
- }
+ <div class="projects-container">
+ {
+ projects.map((project) => (
+ Project(project)
+ ))
+ }
+ </div>
</div>
</>
);