mirror of
https://github.com/RGBCube/rgbcube.github.io
synced 2025-05-14 05:54:58 +00:00
Delete old code
This commit is contained in:
parent
5ee27ea000
commit
984e41b771
14 changed files with 0 additions and 763 deletions
18
.gitignore
vendored
18
.gitignore
vendored
|
@ -1,24 +1,6 @@
|
||||||
*
|
*
|
||||||
|
|
||||||
!src/
|
|
||||||
!src/page/
|
|
||||||
!src/page/cube/
|
|
||||||
!src/routes/
|
|
||||||
!src/routes/index/
|
|
||||||
!src/routes/not_found/
|
|
||||||
|
|
||||||
!.gitattributes
|
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
|
||||||
!Cargo.lock
|
|
||||||
!flake.lock
|
|
||||||
|
|
||||||
!*.css
|
|
||||||
!*.gif
|
|
||||||
!*.html
|
!*.html
|
||||||
!*.js
|
|
||||||
!*.md
|
!*.md
|
||||||
!*.nix
|
|
||||||
!*.rs
|
|
||||||
!*.toml
|
|
||||||
!*.woff2
|
|
||||||
|
|
68
src/asset.rs
68
src/asset.rs
|
@ -1,68 +0,0 @@
|
||||||
use axum::{
|
|
||||||
body::Body,
|
|
||||||
http::header,
|
|
||||||
response::Response,
|
|
||||||
routing,
|
|
||||||
};
|
|
||||||
use bytes::Bytes;
|
|
||||||
use minify_js::{
|
|
||||||
Session,
|
|
||||||
TopLevelMode,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn route(path: &'static str, content: Bytes) -> String {
|
|
||||||
crate::route(
|
|
||||||
path,
|
|
||||||
routing::get(async move || {
|
|
||||||
Response::builder()
|
|
||||||
.header(
|
|
||||||
header::CONTENT_TYPE,
|
|
||||||
mime_guess::from_path(path)
|
|
||||||
.first_or_octet_stream()
|
|
||||||
.to_string(),
|
|
||||||
)
|
|
||||||
.body(Body::from(content.clone()))
|
|
||||||
.unwrap()
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
format!("/assets/{path}")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn __register_asset(
|
|
||||||
path: &'static str,
|
|
||||||
min_path: &'static str,
|
|
||||||
content: Vec<u8>,
|
|
||||||
) -> String {
|
|
||||||
let (minifiable, minified_content) = match path.rsplit_once(".").unwrap_or_default().1 {
|
|
||||||
"js" => {
|
|
||||||
let mut minified = Vec::new();
|
|
||||||
|
|
||||||
minify_js::minify(
|
|
||||||
&Session::new(),
|
|
||||||
TopLevelMode::Module,
|
|
||||||
&content,
|
|
||||||
&mut minified,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
(true, minified)
|
|
||||||
},
|
|
||||||
_ => (false, content.clone()), // TODO: Minify CSS.
|
|
||||||
};
|
|
||||||
|
|
||||||
if minifiable {
|
|
||||||
route(path, Bytes::from(content));
|
|
||||||
route(min_path, Bytes::from(minified_content))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
route(path, Bytes::from(content))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! asset {
|
|
||||||
($path:literal) => {{
|
|
||||||
crate::asset::__register_asset($path, $path, ::embed::bytes!($path).to_vec())
|
|
||||||
}};
|
|
||||||
}
|
|
58
src/main.rs
58
src/main.rs
|
@ -1,58 +0,0 @@
|
||||||
#![feature(lazy_cell, async_closure)]
|
|
||||||
|
|
||||||
mod asset;
|
|
||||||
mod page;
|
|
||||||
mod routes;
|
|
||||||
|
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
use axum::{
|
|
||||||
routing::{
|
|
||||||
self,
|
|
||||||
MethodRouter,
|
|
||||||
},
|
|
||||||
Router,
|
|
||||||
};
|
|
||||||
use tokio::{
|
|
||||||
net::TcpListener,
|
|
||||||
sync::Mutex,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub(crate) static ROUTER: LazyLock<Mutex<Router>> = LazyLock::new(|| Mutex::new(Router::new()));
|
|
||||||
|
|
||||||
pub(crate) fn route(path: &str, handler: MethodRouter<()>) {
|
|
||||||
let mut router = ROUTER.blocking_lock();
|
|
||||||
|
|
||||||
*router = router.clone().route(path, handler);
|
|
||||||
|
|
||||||
log::info!("Registered route {path}.")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn not_found_handler(handler: MethodRouter<()>) {
|
|
||||||
let mut router = ROUTER.blocking_lock();
|
|
||||||
|
|
||||||
*router = router.clone().fallback(handler);
|
|
||||||
|
|
||||||
log::info!("Registered 404 handler.")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
env_logger::builder()
|
|
||||||
.filter_level(log::LevelFilter::Info)
|
|
||||||
.target(env_logger::Target::Stdout)
|
|
||||||
.init();
|
|
||||||
|
|
||||||
route("/", routing::get(routes::index::handler));
|
|
||||||
|
|
||||||
// not_found_handler({
|
|
||||||
// routes::not_found::init();
|
|
||||||
// routes::not_found::handler.into()
|
|
||||||
// });
|
|
||||||
|
|
||||||
let listener = TcpListener::bind("0.0.0.0:80").await.unwrap();
|
|
||||||
|
|
||||||
let app = ROUTER.lock().await;
|
|
||||||
|
|
||||||
axum::serve(listener, app.clone()).await.unwrap();
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,108 +0,0 @@
|
||||||
@font-face {
|
|
||||||
font-family: "Bai Jamjuree";
|
|
||||||
font-weight: 700;
|
|
||||||
src: url("/assets/BaiJamjuree700.woff2") format("woff2");
|
|
||||||
}
|
|
||||||
|
|
||||||
body,
|
|
||||||
html {
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
background-color: #000000;
|
|
||||||
font-family: "Bai Jamjuree", sans;
|
|
||||||
font-size: 450%;
|
|
||||||
|
|
||||||
overscroll-behavior: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 400px) {
|
|
||||||
html {
|
|
||||||
font-size: 200%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 800px) and (min-width: 400px) {
|
|
||||||
html {
|
|
||||||
font-size: 300%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #000000;
|
|
||||||
text-decoration-line: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.frame {
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
|
|
||||||
width: min-content;
|
|
||||||
|
|
||||||
padding: 0 .3em;
|
|
||||||
border-radius: 1em;
|
|
||||||
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scene {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
perspective: 15em;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube {
|
|
||||||
height: 5em;
|
|
||||||
width: 5em;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
transform: translateZ(-2.498em);
|
|
||||||
transform-style: preserve-3d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.face {
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
|
|
||||||
width: 5em;
|
|
||||||
height: 5em;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.front {
|
|
||||||
transform: rotateY(0deg) translateZ(2.498em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top {
|
|
||||||
/* Guess what? Yeah, you guessed right. Safari can't render shit. */
|
|
||||||
transform: rotateX(89.99999999999999deg) translateZ(2.498em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.back {
|
|
||||||
transform: rotateY(180deg) translateZ(2.498em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
transform: rotateX(-89.99999999999999deg) translateZ(2.498em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
transform: rotateY(89.99999999999999deg) translateZ(2.498em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
transform: rotateY(-89.99999999999999deg) translateZ(2.498em);
|
|
||||||
}
|
|
|
@ -1,228 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
class Vec3 {
|
|
||||||
constructor(x, y, z) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
static zero() {
|
|
||||||
return new Vec3(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
length() {
|
|
||||||
return Math.sqrt(this.x ** 2 + this.y ** 2 + this.z ** 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
scale(factor) {
|
|
||||||
this.x *= factor;
|
|
||||||
this.y *= factor;
|
|
||||||
this.z *= factor;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
normalize() {
|
|
||||||
const length = this.length();
|
|
||||||
|
|
||||||
if (length != 0) {
|
|
||||||
this.x /= length;
|
|
||||||
this.y /= length;
|
|
||||||
this.z /= length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static sub(v, t) {
|
|
||||||
return new Vec3(
|
|
||||||
v.x - t.x,
|
|
||||||
v.y - t.y,
|
|
||||||
v.z - t.z,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
static sum(v, t) {
|
|
||||||
return new Vec3(
|
|
||||||
v.x + t.x,
|
|
||||||
v.y + t.y,
|
|
||||||
v.z + t.z,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Quat {
|
|
||||||
constructor(x, y, z, w) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
this.z = z;
|
|
||||||
this.w = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fromAxis(axis) {
|
|
||||||
const angle = axis.length();
|
|
||||||
|
|
||||||
axis.normalize();
|
|
||||||
|
|
||||||
const half = angle / 2;
|
|
||||||
|
|
||||||
const sinHalf = Math.sin(half);
|
|
||||||
const cosHalf = Math.cos(half);
|
|
||||||
|
|
||||||
const x = axis.x * sinHalf;
|
|
||||||
const y = axis.y * sinHalf;
|
|
||||||
const z = axis.z * sinHalf;
|
|
||||||
const w = cosHalf;
|
|
||||||
|
|
||||||
return new Quat(x, y, z, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
static mul(q, r) {
|
|
||||||
return new Quat(
|
|
||||||
q.w * r.x + q.x * r.w + q.y * r.z - q.z * r.y,
|
|
||||||
q.w * r.y - q.x * r.z + q.y * r.w + q.z * r.x,
|
|
||||||
q.w * r.z + q.x * r.y - q.y * r.x + q.z * r.w,
|
|
||||||
q.w * r.w - q.x * r.x - q.y * r.y - q.z * r.z,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let friction = 3;
|
|
||||||
let sensitivity = 0.01;
|
|
||||||
let velocity = Vec3.zero();
|
|
||||||
|
|
||||||
const orientation = {
|
|
||||||
__cube: document.querySelector(".cube"),
|
|
||||||
__value: new Quat(0, 0, 0, 1),
|
|
||||||
|
|
||||||
set(value) {
|
|
||||||
this.__value = value;
|
|
||||||
|
|
||||||
const q = this.__value;
|
|
||||||
this.__cube.style.transform = `rotate3d(${q.x}, ${q.y}, ${q.z}, ${Math.acos(q.w) * 2}rad)`;
|
|
||||||
},
|
|
||||||
|
|
||||||
get() {
|
|
||||||
return this.__value;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
const mouse = {
|
|
||||||
down: false,
|
|
||||||
lastMove: -10000,
|
|
||||||
previous: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
let impulseThisFrame = Vec3.zero();
|
|
||||||
|
|
||||||
const handleUp = () => {
|
|
||||||
mouse.down = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener("mouseup", handleUp);
|
|
||||||
document.addEventListener("touchend", handleUp);
|
|
||||||
|
|
||||||
const handleDown = (event) => {
|
|
||||||
// Disables link dragging that occurs when spinning.
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
mouse.down = true;
|
|
||||||
|
|
||||||
velocity = Vec3.zero();
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener("mousedown", handleDown);
|
|
||||||
document.addEventListener("touchstart", handleDown);
|
|
||||||
|
|
||||||
const handleMove = (event) => {
|
|
||||||
// Disables scrolling.
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
if (!mouse.down) return;
|
|
||||||
|
|
||||||
const newMouse = new Vec3(event.clientX, event.clientY, 0);
|
|
||||||
|
|
||||||
const timeDelta = (window.performance.now() - mouse.lastMove) / 1000;
|
|
||||||
|
|
||||||
if (timeDelta > 0.1) {
|
|
||||||
// This is a fresh scroll.
|
|
||||||
mouse.previous = newMouse;
|
|
||||||
}
|
|
||||||
|
|
||||||
const delta = Vec3.sub(newMouse, mouse.previous);
|
|
||||||
|
|
||||||
mouse.previous = newMouse;
|
|
||||||
mouse.lastMove = window.performance.now();
|
|
||||||
|
|
||||||
const axis = new Vec3(-delta.y, delta.x, 0)
|
|
||||||
.normalize()
|
|
||||||
.scale(delta.length() * sensitivity);
|
|
||||||
|
|
||||||
impulseThisFrame = Vec3.sum(impulseThisFrame, axis);
|
|
||||||
|
|
||||||
const rotation = Quat.fromAxis(axis);
|
|
||||||
|
|
||||||
orientation.set(Quat.mul(rotation, orientation.get()));
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener("mousemove", handleMove);
|
|
||||||
document.addEventListener("touchmove", (event) => {
|
|
||||||
const delta = event.changedTouches[0];
|
|
||||||
|
|
||||||
event.clientX = delta.clientX;
|
|
||||||
event.clientY = delta.clientY;
|
|
||||||
|
|
||||||
handleMove(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
let lastUpdate = 0;
|
|
||||||
|
|
||||||
const updateFrame = (timestamp) => {
|
|
||||||
if (lastUpdate == 0) lastUpdate = timestamp;
|
|
||||||
|
|
||||||
const delta = (timestamp - lastUpdate) / 1000;
|
|
||||||
lastUpdate = timestamp;
|
|
||||||
|
|
||||||
if (mouse.down) {
|
|
||||||
velocity = impulseThisFrame.scale(1 / delta);
|
|
||||||
impulseThisFrame = Vec3.zero();
|
|
||||||
} else {
|
|
||||||
const decay = Math.exp(-delta * friction);
|
|
||||||
|
|
||||||
const effectiveDelta = friction > 0 ? (1 - decay) / friction : delta;
|
|
||||||
|
|
||||||
let theta = effectiveDelta * velocity.length();
|
|
||||||
|
|
||||||
velocity.x *= decay;
|
|
||||||
velocity.y *= decay;
|
|
||||||
velocity.z *= decay;
|
|
||||||
|
|
||||||
if (friction > 0 && velocity.length() < 0.00001) {
|
|
||||||
theta += velocity.length() / friction;
|
|
||||||
|
|
||||||
velocity.x = 0;
|
|
||||||
velocity.y = 0;
|
|
||||||
velocity.z = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window.performance.now() - mouse.lastMove > 10000) {
|
|
||||||
const impulse = new Vec3(1, 1, -1);
|
|
||||||
velocity = Vec3.sum(impulse.scale(effectiveDelta * 3), velocity);
|
|
||||||
}
|
|
||||||
|
|
||||||
const axis = new Vec3(velocity.x, velocity.y, velocity.z)
|
|
||||||
.normalize()
|
|
||||||
.scale(theta);
|
|
||||||
|
|
||||||
const rotation = Quat.fromAxis(axis);
|
|
||||||
|
|
||||||
orientation.set(Quat.mul(rotation, orientation.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(updateFrame);
|
|
||||||
};
|
|
||||||
|
|
||||||
updateFrame(0);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
use maud::{
|
|
||||||
html,
|
|
||||||
Markup,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::asset;
|
|
||||||
|
|
||||||
pub(crate) fn create(asset: &str, faces: [Markup; 6]) -> Markup {
|
|
||||||
crate::page::create(
|
|
||||||
html! {
|
|
||||||
link rel="stylesheet" type="text/css" href=(asset!("cube.css"));
|
|
||||||
link rel="stylesheet" type="text/css" href=(asset);
|
|
||||||
},
|
|
||||||
html! {
|
|
||||||
div class="scene" {
|
|
||||||
div class="cube" {
|
|
||||||
@for (name, content) in ["front", "top", "back", "bottom", "right", "left"].iter().zip(faces) {
|
|
||||||
div class=(format!("face {name}")) {
|
|
||||||
(content)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
script src=(asset!("cube.js"));
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 81 KiB |
|
@ -1,69 +0,0 @@
|
||||||
pub mod cube;
|
|
||||||
|
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
use cargo_toml::Manifest;
|
|
||||||
use maud::{
|
|
||||||
html,
|
|
||||||
Markup,
|
|
||||||
DOCTYPE,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::asset;
|
|
||||||
|
|
||||||
static MANIFEST: LazyLock<Manifest> =
|
|
||||||
LazyLock::new(|| Manifest::from_str(&embed::string!("../../Cargo.toml")).unwrap());
|
|
||||||
|
|
||||||
fn property(name: &str, content: &str) -> Markup {
|
|
||||||
html! {
|
|
||||||
meta property=(name) content=(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pname(name: &str, content: &str) -> Markup {
|
|
||||||
html! {
|
|
||||||
meta name=(name) content=(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn create(head: Markup, body: Markup) -> Markup {
|
|
||||||
html! {
|
|
||||||
(DOCTYPE)
|
|
||||||
|
|
||||||
head {
|
|
||||||
meta charset="UTF-8";
|
|
||||||
|
|
||||||
(pname("viewport", "width=device-width, initial-scale=1.0"))
|
|
||||||
(property("og:type", "website"))
|
|
||||||
|
|
||||||
@let name = "RGBCube";
|
|
||||||
|
|
||||||
title { (name) }
|
|
||||||
(pname("author", name))
|
|
||||||
|
|
||||||
(property("og:site_name", name))
|
|
||||||
(property("og:title", name))
|
|
||||||
|
|
||||||
@let description = MANIFEST.package.as_ref().unwrap().description().unwrap();
|
|
||||||
(pname("description", description))
|
|
||||||
(property("og:description", description))
|
|
||||||
|
|
||||||
link rel="icon" href=(asset!("icon.gif")) type="image/gif";
|
|
||||||
|
|
||||||
(property("og:image", "thumbnail.png"))
|
|
||||||
(property("og:image:type", "image/png"))
|
|
||||||
(property("og:image:height", "1080"))
|
|
||||||
(property("og:image:width", "600"))
|
|
||||||
|
|
||||||
@let url = MANIFEST.package.as_ref().unwrap().homepage().unwrap();
|
|
||||||
(property("og:url", url))
|
|
||||||
link rel="canonical" href=(url);
|
|
||||||
|
|
||||||
(head)
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
.frame:hover {
|
|
||||||
background-color: #FFFF00;
|
|
||||||
}
|
|
||||||
|
|
||||||
.face::after {
|
|
||||||
z-index: -1;
|
|
||||||
|
|
||||||
content: "";
|
|
||||||
|
|
||||||
height: inherit;
|
|
||||||
width: inherit;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
.front {
|
|
||||||
background: linear-gradient(to bottom, cyan, blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.front::after {
|
|
||||||
background: linear-gradient(to bottom, white, magenta);
|
|
||||||
mask-image: linear-gradient(to left, magenta, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top {
|
|
||||||
background: linear-gradient(to bottom, lime, cyan);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top::after {
|
|
||||||
background: linear-gradient(to bottom, yellow, white);
|
|
||||||
mask-image: linear-gradient(to left, white, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.back {
|
|
||||||
background: linear-gradient(to bottom, yellow, red);
|
|
||||||
}
|
|
||||||
|
|
||||||
.back::after {
|
|
||||||
background: linear-gradient(to bottom, lime, black);
|
|
||||||
mask-image: linear-gradient(to left, black, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
background: linear-gradient(to bottom, blue, black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom::after {
|
|
||||||
background: linear-gradient(to bottom, magenta, red);
|
|
||||||
mask-image: linear-gradient(to left, red, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
background: linear-gradient(to bottom, white, magenta);
|
|
||||||
}
|
|
||||||
|
|
||||||
.right::after {
|
|
||||||
background: linear-gradient(to bottom, yellow, red);
|
|
||||||
mask-image: linear-gradient(to left, red, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
background: linear-gradient(to bottom, lime, black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.left::after {
|
|
||||||
background: linear-gradient(to bottom, cyan, blue);
|
|
||||||
mask-image: linear-gradient(to left, blue, transparent);
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
use maud::{
|
|
||||||
html,
|
|
||||||
Markup,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
asset,
|
|
||||||
page::cube,
|
|
||||||
};
|
|
||||||
|
|
||||||
static PAGE: LazyLock<BoxedFuture<Markup>>> = LazyLock::new(|| {
|
|
||||||
cube::create(
|
|
||||||
&asset!("index.css"),
|
|
||||||
[
|
|
||||||
html! {
|
|
||||||
a href="/contact" {
|
|
||||||
div class="frame" {
|
|
||||||
"contact"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
html! {
|
|
||||||
a href="/github" {
|
|
||||||
div class="frame" {
|
|
||||||
"github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
html! {},
|
|
||||||
html! {},
|
|
||||||
html! {},
|
|
||||||
html! {},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
let _ = &*PAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn handler() -> &'static str {
|
|
||||||
// &*PAGE
|
|
||||||
"asd"
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
pub(crate) mod index;
|
|
||||||
pub(crate) mod not_found;
|
|
|
@ -1,29 +0,0 @@
|
||||||
.face {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
grid-template-rows: repeat(2, 1fr);
|
|
||||||
box-shadow: 0 0 10px #AAAAAA;
|
|
||||||
}
|
|
||||||
|
|
||||||
.square {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.magenta {
|
|
||||||
background-color: magenta;
|
|
||||||
}
|
|
||||||
|
|
||||||
.black {
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.frame {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
|
|
||||||
color: black;
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
use maud::{
|
|
||||||
html,
|
|
||||||
Markup,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
asset,
|
|
||||||
page::cube,
|
|
||||||
};
|
|
||||||
|
|
||||||
static PAGE: LazyLock<Markup> = LazyLock::new(|| {
|
|
||||||
let face = html! {
|
|
||||||
div class="frame" { "404" }
|
|
||||||
div class="square black" {}
|
|
||||||
div class="square magenta" {}
|
|
||||||
div class="square magenta" {}
|
|
||||||
div class="square black" {}
|
|
||||||
};
|
|
||||||
|
|
||||||
cube::create(
|
|
||||||
&asset!("404.css"),
|
|
||||||
[
|
|
||||||
face.clone(),
|
|
||||||
face.clone(),
|
|
||||||
face.clone(),
|
|
||||||
face.clone(),
|
|
||||||
face.clone(),
|
|
||||||
face.clone(),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
let _ = &*PAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn handler() -> &'static Markup {
|
|
||||||
&*PAGE
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue