diff options
Diffstat (limited to 'front/src/components')
| -rw-r--r-- | front/src/components/animated_bg.tsx | 126 | ||||
| -rw-r--r-- | front/src/components/carousel.css | 68 | ||||
| -rw-r--r-- | front/src/components/carousel.tsx | 31 | ||||
| -rw-r--r-- | front/src/components/navbar-item.tsx | 8 | ||||
| -rw-r--r-- | front/src/components/navbar.css | 278 | ||||
| -rw-r--r-- | front/src/components/navbar.tsx | 20 | ||||
| -rw-r--r-- | front/src/components/project.css | 137 | ||||
| -rw-r--r-- | front/src/components/project.tsx | 98 |
8 files changed, 0 insertions, 766 deletions
diff --git a/front/src/components/animated_bg.tsx b/front/src/components/animated_bg.tsx deleted file mode 100644 index b5fdbb0..0000000 --- a/front/src/components/animated_bg.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import { Shaders, Node, GLSL } from "gl-react"; -import { Surface } from "gl-react-dom"; -import React, { FunctionComponent } 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: FunctionComponent<PropsWithChildren<{ tick: number }>>, - { 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} />; - } - }; -} - -const checkWebGL = () => { - try { - const canvas = document.createElement("canvas"); - return !!( - window.WebGLRenderingContext && - (canvas.getContext("webgl") || canvas.getContext("experimental-webgl")) - ); - } catch (e) { - return false; - } -} - -export const AnimatedBg = checkWebGL() ? timeLoop(AnimatedBgInternal, { refreshRate: fps }) : () => <div />; diff --git a/front/src/components/carousel.css b/front/src/components/carousel.css deleted file mode 100644 index f311805..0000000 --- a/front/src/components/carousel.css +++ /dev/null @@ -1,68 +0,0 @@ -.carousel-content { - align-self: center; - max-height: 100%; - white-space: nowrap; - -ms-overflow-style: none; /* hide scrollbar in IE and Edge */ - scrollbar-width: none; /* hide scrollbar in Firefox */ -} - -.carousel-item { - width: 100%; - flex-shrink: 0; - height: auto; - float: left; - text-align: center; - transition: all 250ms linear; - white-space: nowrap; - vertical-align: middle; -} - -.slick-slider { - margin: 24px; -} - -.slick-slide { - margin: 0 auto; - border-radius: 10px; - text-align: center; - float: none !important; - display: inline-block !important; - vertical-align: middle; - min-height: 1px; -} - -.carousel-item > * { - border-radius: 10px; - vertical-align: middle; - width: 100%; - height: auto; -} - -.slick-dots li button::before { - color: var(--color-fg) !important; -} - -@media (max-width: 1150px) { - .carousel-wrapper { - margin: 60px auto; - width: 330px; - height: 220px; - } -} - -@media (max-width: 1150px) and (min-width: 480px) { - .carousel-wrapper { - margin: 60px auto; - width: 480px; - height: 360px; - } -} - -@media (min-width: 1150px) { - .carousel-wrapper { - float: right; - width: 480px; - height: 360px; - } -} - diff --git a/front/src/components/carousel.tsx b/front/src/components/carousel.tsx deleted file mode 100644 index af9279b..0000000 --- a/front/src/components/carousel.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import './carousel.css'; -import Slider, { Settings } from 'react-slick'; -import "slick-carousel/slick/slick.css"; -import "slick-carousel/slick/slick-theme.css"; - -export default function Carousel(props: { children: any }) { - const settings: Settings = { - dots: true, - infinite: true, - speed: 500, - slidesToShow: 1, - slidesToScroll: 1 - }; - - return ( - <div class="carousel-wrapper"> - <Slider {...settings}> - { - props.children instanceof Array ? - props.children.map((child: any) => { - return ( - <div class="carousel-item">{child}</div> - ); - }) - : - <div class="carousel-item">{props.children}</div> - } - </Slider> - </div> - ); -} diff --git a/front/src/components/navbar-item.tsx b/front/src/components/navbar-item.tsx deleted file mode 100644 index c2f2306..0000000 --- a/front/src/components/navbar-item.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import * as preact from "preact"; - -export function NavbarItem(props: any) { - const { name, href, children, rel } = props; - - return (preact.createElement("div", { className: "navbar-item" }, - preact.createElement("a", { className: "navbar-item-" + name, href: href, rel: rel }, children))); -} diff --git a/front/src/components/navbar.css b/front/src/components/navbar.css deleted file mode 100644 index 9120052..0000000 --- a/front/src/components/navbar.css +++ /dev/null @@ -1,278 +0,0 @@ -/* on big screens, navbar is fixed to the top of the screen */ -.navbar-container { - position: fixed; - /* gradient from top to bottom, full to transparent */ - top: 0; - width: 100%; - z-index: 9999; - margin: auto; -} - -/* on smaller ones, make it behave as a normal element laid out at the top of the page */ -@media (max-width: 1150px) { - .navbar-container { - position: static; - } -} - -.navbar { - 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 { - font-family: Hack, monospace; - font-weight: 500; - color: #646cff; - font-size: 1.5em; - padding: 0.5em; - margin: 0.5em; -} - -.navbar { - align-self: center; - display: block; - width: 100%; - text-align: center; -} - -.navbar-item { - font-family: Hack, monospace; - font-size: 18pt; - text-align: center; - float: none; - clear: left; - display: inline-block; - margin: 0 0.25em; - transition: all 0.2s ease-in-out; -} - -.navbar-item:hover { - padding-left: 0.5em; - padding-right: 0.5em; - transition: all 0.2s ease-in-out; -} - -.navbar-current { - font-weight: bold; -} - -/* home */ - -.navbar-item-home:link { - color: #98C379; - text-decoration: none; -} - -.navbar-item-home:visited { - color: #98C379; - text-decoration: none; -} - -.navbar-item-home:hover { - color: #afd088; - text-decoration: underline; -} - -.navbar-item-home:active { - color: #afd088; - text-decoration: underline; -} - -/* games */ - -.navbar-item-games:link { - color: #e06c75; - text-decoration: none; -} - -.navbar-item-games:visited { - color: #e06c75; - text-decoration: none; -} - -.navbar-item-games:hover { - color: #ef7a80; - text-decoration: underline; -} - -.navbar-item-games:active { - color: #ef7a90; - text-decoration: underline; -} - -/* projects */ - -.navbar-item-projects:link { - color: #d19a66; - text-decoration: none; -} - -.navbar-item-projects:visited { - color: #d19a66; - text-decoration: none; -} - -.navbar-item-projects:hover { - color: #dfa873; - text-decoration: underline; -} - -.navbar-item-projects:active { - color: #dffa73; - text-decoration: underline; -} - -/* github */ - -.navbar-item-github:link { - color: #c678dd; - text-decoration: none; -} - -.navbar-item-github:visited { - color: #c678dd; - text-decoration: none; -} - -.navbar-item-github:hover { - color: #d286eb; - text-decoration: underline; -} - -.navbar-item-github:active { - color: #d286eb; - text-decoration: underline; -} - -/* itch */ - -.navbar-item-itch:link { - color: #e06c75; - text-decoration: none; -} - -.navbar-item-itch:visited { - color: #e06c75; - text-decoration: none; -} - -.navbar-item-itch:hover { - color: #ef7a80; - text-decoration: underline; -} - -.navbar-item-itch:active { - color: #ef7a90; - text-decoration: underline; -} - -/* twitter */ - -.navbar-item-twitter:link { - text-decoration: none; -} - -.navbar-item-twitter:visited { - text-decoration: none; -} - -.navbar-item-twitter:hover { - text-decoration: underline; -} - -.navbar-item-twitter:active { - text-decoration: underline; -} - -/* mastodon */ - -.navbar-item-mastodon:link { - color: #6a4ae0; - text-decoration: none; -} - -.navbar-item-mastodon:visited { - color: #6a4ae0; - text-decoration: none; -} - -.navbar-item-mastodon:hover { - color: #7a55e8; - text-decoration: underline; -} - -.navbar-item-mastodon:active { - color: #7a55e8; - text-decoration: underline; -} - -/* cohost */ - -.navbar-item-cohost:link { - color: #b63b73; - text-decoration: none; -} - -.navbar-item-cohost:visited { - color: #b63b73; - text-decoration: none; -} - -.navbar-item-cohost:hover { - color: #c54a7f; - text-decoration: underline; -} - -.navbar-item-cohost:active { - color: #c54a7f; - text-decoration: underline; -} - -/* tumblr */ - -.navbar-item-tumblr:link { - color: #00b8ff; - text-decoration: none; -} - -.navbar-item-tumblr:visited { - color: #00b8ff; - text-decoration: none; -} - -.navbar-item-tumblr:hover { - color: #00c5ff; - text-decoration: underline; -} - -.navbar-item-tumblr:active { - color: #00c5ff; - text-decoration: underline; -} - -/* contact */ - -.navbar-item-contact:link { - color: #e5c07b; - text-decoration: none; -} - -.navbar-item-contact:visited { - color: #e5c07b; - text-decoration: none; -} - -.navbar-item-contact:hover { - color: #f2ce89; - text-decoration: underline; -} - -.navbar-item-contact:active { - color: #f2ce89; - text-decoration: underline; -} diff --git a/front/src/components/navbar.tsx b/front/src/components/navbar.tsx deleted file mode 100644 index ba3d7d7..0000000 --- a/front/src/components/navbar.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import './navbar.css'; - -import { NavbarItem } from './navbar-item'; - -export function Navbar() { - return ( - <div class="navbar-container"> - <div class="navbar"> - <NavbarItem name="home" href="/">[Home]</NavbarItem> - <NavbarItem name="games" href="/games">[Games]</NavbarItem> - <NavbarItem name="projects" href="/projects">[Other Projects]</NavbarItem> - <NavbarItem name="github" href="https://github.com/Duckonaut">[GitHub]</NavbarItem> - <NavbarItem name="itch" href="https://duckonaut.itch.io/">[Itch.io]</NavbarItem> - <NavbarItem name="twitter" href="https://twitter.com/duckonaut">[Twitter]</NavbarItem> - <NavbarItem name="mastodon" href="https://mastodon.gamedev.place/@duckonaut" rel="me">[Mastodon]</NavbarItem> - <NavbarItem name="contact" href="/contact">[Contact]</NavbarItem> - </div> - </div> - ); -} diff --git a/front/src/components/project.css b/front/src/components/project.css deleted file mode 100644 index 89ce30f..0000000 --- a/front/src/components/project.css +++ /dev/null @@ -1,137 +0,0 @@ -.icon { - display: inline; - width: 32px; - height: 32px; - transition: 0.3s; - transform-origin: center; - filter: brightness(70%) -} - -.icon:hover { - filter: brightness(80%); -} - -.icon-row { - width: 320px; - height: 36px; -} - -.icon-container { - height: 36px; - float: right; -} - -.icon-text { - width: auto; - height: 36px; - line-height: 36px; - float: left; - vertical-align: middle; - margin-right: 8px; - color: #5c6370; -} - -.projects-container { - width: 100%; - max-width: 1120px; - margin: auto; - margin-top: 24pt; - margin-bottom: 48pt; - align-items: center; - justify-content: center; - align-self: center; -} - -.project { - display: table; - align-self: center; - clear: both; - margin-bottom: 24pt; -} - -.project-info { - font-size: 14pt; -} - -.project-description { - font-size: 16pt; - text-align: justify; -} - -.project-image-gallery { - margin-left: 24px; - margin-right: 10px; -} - -@media (max-width: 1150px) { - .project-title { - text-align: center; - font-size: 24pt; - margin-bottom: 8px; - text-decoration-line: underline; - } - - .project-image-gallery { - margin: 60px auto; - width: 330px; - height: 220px; - } - - .project-info { - float: none; - width: 90%; - margin: auto; - } - - .project-description { - font-size: 14pt; - } -} - -@media (max-width: 1150px) and (min-width: 480px) { - .project-title { - text-align: center; - font-size: 24pt; - margin-bottom: 8px; - text-decoration-line: underline; - } - .project-image-gallery { - margin: 60px auto; - width: 480px; - height: 360px; - } - - .project-info { - float: none; - width: 90%; - margin: auto; - } - - .project-description { - font-size: 14pt; - } -} - -@media (min-width: 1150px) { - .project-title { - text-align: left; - font-size: 32pt; - margin-bottom: 8px; - text-decoration-line: underline; - } - .project-image-gallery { - float: right; - width: 480px; - height: 360px; - } - .project-info { - float: left; - max-width: 600px; - } - - .project-description { - font-size: 16pt; - } -} - - diff --git a/front/src/components/project.tsx b/front/src/components/project.tsx deleted file mode 100644 index cd5cb89..0000000 --- a/front/src/components/project.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import Carousel from "./carousel"; -import './project.css'; - -enum ProjectType { - GAME = "game", - PROJECT = "project", -} - -export enum ProjectTech { - CSHARP = "csharp", - RUST = "rust", - C = "c", - CPP = "cpp", - JAVASCRIPT = "javascript", - TYPESCRIPT = "typescript", - HTML = "html", - CSS = "css", - - PREACT = "preact", - UNITY = "unity", - GODOT = "godot", - MONOGAME = "monogame", -} - -export enum ProjectTarget { - WEB = "html5", - WINDOWS = "windows", - LINUX = "linux", - MACOS = "macos", - ANDROID = "android", - XBOX = "xbox", - PLAYSTATION = "playstation", - SWITCH = "switch", - HYPRLAND = "hyprland", -} - -export interface ProjectDescriptor { - name: string; - name_normalized: string; - type: ProjectType; - link: string; - tech: ProjectTech[]; - targets: ProjectTarget[]; - images: string[]; - description: string; -} - -function getProjectImageLink(project: ProjectDescriptor, image: string) { - return `assets/${project.type}s/${project.name_normalized}/${image}`; -} - -function getProjectTechIconLink(tech: ProjectTech) { - return `assets/images/${tech}.png`; -} - -function getProjectTargetIconLink(target: ProjectTarget) { - return `assets/images/${target}.png`; -} - -export function Project(props: ProjectDescriptor) { - return ( - <div class="project"> - <div class="project-title"><a href={props.link}>{props.name}</a></div> - <div class="project-info"> - <div class="icon-row"> - <div class="icon-text">Made using</div> - <div class="icon-container"> - {props.tech.map((tech) => ( - <img class="grow icon" src={getProjectTechIconLink(tech)} /> - ))} - </div> - </div> - <div class="icon-row"> - <div class="icon-text">Available on</div> - <div class="icon-container"> - {props.targets.map((target) => ( - <img class="grow icon" src={getProjectTargetIconLink(target)} /> - ))} - </div> - </div> - <hr /> - <div class="project-description"> - { - // use description as html - <div dangerouslySetInnerHTML={{ __html: props.description }} /> - } - </div> - </div> - {props.images && props.images.length > 0 && - <Carousel> - {props.images.map((image) => ( - <img class="project-image" src={getProjectImageLink(props, image)} /> - ))} - </Carousel> - } - </div> - ); -} |
