Initial setup pachinko
This commit is contained in:
parent
3f379750a6
commit
1f2dff7ced
13 changed files with 2367 additions and 1764 deletions
3727
Cargo.lock
generated
3727
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -3,5 +3,7 @@
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = "thin"
|
lto = true
|
||||||
opt-level = 'z'
|
opt-level = 'z'
|
||||||
|
panic = "abort"
|
||||||
|
strip = true
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,14 @@ FROM rust:1 AS builder
|
||||||
WORKDIR /usr/src/website
|
WORKDIR /usr/src/website
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends binaryen brotli \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN rustup target add wasm32-unknown-unknown
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
RUN cargo install wasm-bindgen-cli
|
RUN cargo install wasm-bindgen-cli
|
||||||
|
|
||||||
RUN ./build-wasm.sh
|
RUN ./build-wasm.sh release
|
||||||
RUN cargo build --release -p server
|
RUN cargo build --release -p server
|
||||||
|
|
||||||
FROM debian:trixie-slim
|
FROM debian:trixie-slim
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,5 @@
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy = { version = "0.18", default-features = false, features = [
|
avian2d = "0.7"
|
||||||
"3d",
|
bevy = { version = "0.19", default-features = false, features = ["2d"] }
|
||||||
"tonemapping_luts",
|
|
||||||
"web",
|
|
||||||
"webgl2",
|
|
||||||
] }
|
|
||||||
|
|
|
||||||
172
app/src/main.rs
172
app/src/main.rs
|
|
@ -1,8 +1,15 @@
|
||||||
use bevy::prelude::*;
|
use avian2d::prelude::*;
|
||||||
|
use bevy::{
|
||||||
|
input::common_conditions::input_just_pressed,
|
||||||
|
prelude::*,
|
||||||
|
window::{PrimaryWindow, WindowResized},
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
.insert_resource(ClearColor(Color::srgb_u8(26, 26, 46)))
|
||||||
|
.add_plugins((
|
||||||
|
DefaultPlugins.set(WindowPlugin {
|
||||||
primary_window: Some(Window {
|
primary_window: Some(Window {
|
||||||
fit_canvas_to_parent: true,
|
fit_canvas_to_parent: true,
|
||||||
prevent_default_event_handling: false,
|
prevent_default_event_handling: false,
|
||||||
|
|
@ -10,38 +17,157 @@ fn main() {
|
||||||
..default()
|
..default()
|
||||||
}),
|
}),
|
||||||
..default()
|
..default()
|
||||||
}))
|
}),
|
||||||
|
PhysicsPlugins::default(),
|
||||||
|
))
|
||||||
|
.insert_resource(Time::<Physics>::default().with_relative_speed(5.0))
|
||||||
.add_systems(Startup, setup)
|
.add_systems(Startup, setup)
|
||||||
|
.add_systems(
|
||||||
|
Update,
|
||||||
|
(
|
||||||
|
update_screen_edges,
|
||||||
|
spawn_ball.run_if(input_just_pressed(MouseButton::Left)),
|
||||||
|
),
|
||||||
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Clone, Copy)]
|
||||||
|
enum ScreenEdge {
|
||||||
|
Top,
|
||||||
|
Bottom,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
fn setup(
|
fn setup(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
window: Query<&Window, With<PrimaryWindow>>,
|
||||||
) {
|
) {
|
||||||
commands.spawn((
|
commands.spawn(Camera2d);
|
||||||
Mesh3d(meshes.add(Circle::new(4.0))),
|
|
||||||
MeshMaterial3d(materials.add(Color::WHITE)),
|
|
||||||
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
|
||||||
));
|
|
||||||
|
|
||||||
commands.spawn((
|
if let Ok(window) = window.single() {
|
||||||
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
spawn_screen_edges(&mut commands, &mut meshes, &mut materials, window.size());
|
||||||
MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
|
}
|
||||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
}
|
||||||
));
|
|
||||||
|
|
||||||
commands.spawn((
|
#[derive(Component, Clone, Copy)]
|
||||||
PointLight {
|
struct Ball;
|
||||||
shadows_enabled: true,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
Transform::from_xyz(4.0, 8.0, 4.0),
|
|
||||||
));
|
|
||||||
|
|
||||||
|
fn spawn_ball(
|
||||||
|
mouse_button: Res<ButtonInput<MouseButton>>,
|
||||||
|
window: Single<&Window, With<PrimaryWindow>>,
|
||||||
|
camera_query: Single<(&Camera, &GlobalTransform)>,
|
||||||
|
time: Res<Time>,
|
||||||
|
mut commands: Commands,
|
||||||
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
) {
|
||||||
|
const CIRCLE_RADIUS: f32 = 5.0;
|
||||||
|
|
||||||
|
let (camera, camera_transform) = *camera_query;
|
||||||
|
if mouse_button.just_pressed(MouseButton::Left)
|
||||||
|
&& let Some(cursor_position) = window.cursor_position()
|
||||||
|
&& let Ok(world_position) = camera.viewport_to_world_2d(camera_transform, cursor_position)
|
||||||
|
{
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Camera3d::default(),
|
RigidBody::Dynamic,
|
||||||
Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
|
Collider::circle(CIRCLE_RADIUS),
|
||||||
|
Restitution::PERFECTLY_ELASTIC.with_combine_rule(CoefficientCombine::Max),
|
||||||
|
Mesh2d(meshes.add(Circle::new(CIRCLE_RADIUS))),
|
||||||
|
MeshMaterial2d(materials.add(Color::hsl(time.elapsed_secs().sin() * 360.0, 1.0, 0.5))),
|
||||||
|
Transform::from_xyz(world_position.x, world_position.y, 0.0),
|
||||||
|
Ball,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_screen_edges(
|
||||||
|
commands: &mut Commands,
|
||||||
|
meshes: &mut Assets<Mesh>,
|
||||||
|
materials: &mut Assets<ColorMaterial>,
|
||||||
|
size: Vec2,
|
||||||
|
) {
|
||||||
|
const EDGE_COLOR: Color = Color::srgb_u8(255, 255, 255);
|
||||||
|
|
||||||
|
let material = materials.add(EDGE_COLOR);
|
||||||
|
|
||||||
|
for edge in [
|
||||||
|
ScreenEdge::Top,
|
||||||
|
ScreenEdge::Bottom,
|
||||||
|
ScreenEdge::Left,
|
||||||
|
ScreenEdge::Right,
|
||||||
|
] {
|
||||||
|
let (collider, transform, rect_size) = edge_shape(edge, size);
|
||||||
|
commands.spawn((
|
||||||
|
RigidBody::Static,
|
||||||
|
collider,
|
||||||
|
transform,
|
||||||
|
edge,
|
||||||
|
Mesh2d(meshes.add(Rectangle::from_size(rect_size))),
|
||||||
|
MeshMaterial2d(material.clone()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn edge_shape(edge: ScreenEdge, size: Vec2) -> (Collider, Transform, Vec2) {
|
||||||
|
const EDGE_THICKNESS: f32 = 5.0;
|
||||||
|
|
||||||
|
let half = size / 2.0;
|
||||||
|
let thickness = EDGE_THICKNESS;
|
||||||
|
|
||||||
|
match edge {
|
||||||
|
ScreenEdge::Top => {
|
||||||
|
let rect = Vec2::new(size.x, thickness);
|
||||||
|
(
|
||||||
|
Collider::rectangle(rect.x, rect.y),
|
||||||
|
Transform::from_xyz(0.0, half.y - thickness / 2.0, 0.0),
|
||||||
|
rect,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ScreenEdge::Bottom => {
|
||||||
|
let rect = Vec2::new(size.x, thickness);
|
||||||
|
(
|
||||||
|
Collider::rectangle(rect.x, rect.y),
|
||||||
|
Transform::from_xyz(0.0, -half.y + thickness / 2.0, 0.0),
|
||||||
|
rect,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ScreenEdge::Left => {
|
||||||
|
let rect = Vec2::new(thickness, size.y);
|
||||||
|
(
|
||||||
|
Collider::rectangle(rect.x, rect.y),
|
||||||
|
Transform::from_xyz(-half.x + thickness / 2.0, 0.0, 0.0),
|
||||||
|
rect,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ScreenEdge::Right => {
|
||||||
|
let rect = Vec2::new(thickness, size.y);
|
||||||
|
(
|
||||||
|
Collider::rectangle(rect.x, rect.y),
|
||||||
|
Transform::from_xyz(half.x - thickness / 2.0, 0.0, 0.0),
|
||||||
|
rect,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_screen_edges(
|
||||||
|
mut resized: PopulatedMessageReader<WindowResized>,
|
||||||
|
mut edges: Query<(&ScreenEdge, &mut Collider, &mut Transform, &Mesh2d)>,
|
||||||
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
) {
|
||||||
|
for event in resized.read() {
|
||||||
|
let size = Vec2::new(event.width, event.height);
|
||||||
|
for (edge, mut collider, mut transform, mesh2d) in &mut edges {
|
||||||
|
let (new_collider, new_transform, rect_size) = edge_shape(*edge, size);
|
||||||
|
*collider = new_collider;
|
||||||
|
*transform = new_transform;
|
||||||
|
if let Some(mut mesh) = meshes.get_mut(&mesh2d.0) {
|
||||||
|
*mesh = Rectangle::from_size(rect_size).into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,22 @@ fi
|
||||||
cargo build $CARGO_FLAGS --target wasm32-unknown-unknown -p app
|
cargo build $CARGO_FLAGS --target wasm32-unknown-unknown -p app
|
||||||
|
|
||||||
mkdir -p static
|
mkdir -p static
|
||||||
wasm-bindgen --out-name 3dscene \
|
# Drop stale bindgen / compression outputs from prior builds.
|
||||||
|
rm -f static/2dscene*
|
||||||
|
|
||||||
|
wasm-bindgen --out-name 2dscene \
|
||||||
--out-dir static \
|
--out-dir static \
|
||||||
--target web \
|
--target web \
|
||||||
"target/wasm32-unknown-unknown/$PROFILE_DIR/app.wasm"
|
"target/wasm32-unknown-unknown/$PROFILE_DIR/app.wasm"
|
||||||
|
|
||||||
|
if [ "$PROFILE" != "dev" ]; then
|
||||||
|
wasm-opt -Oz --all-features -o static/2dscene_bg.wasm static/2dscene_bg.wasm
|
||||||
|
|
||||||
|
# Precompress assets Axum will negotiate via Accept-Encoding.
|
||||||
|
for f in static/2dscene_bg.wasm static/2dscene.js; do
|
||||||
|
gzip -9 -k -f "$f"
|
||||||
|
brotli -q 11 -f -k "$f"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
cp web/index.html static/
|
cp web/index.html static/
|
||||||
|
|
|
||||||
62
flake.lock
62
flake.lock
|
|
@ -1,30 +1,30 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"flake-utils": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1788450739,
|
||||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
|
||||||
"owner": "numtide",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-parts",
|
||||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "numtide",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-parts",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1771369470,
|
"lastModified": 1789149629,
|
||||||
"narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=",
|
"narHash": "sha256-H6GwaZzZf+4npqv0tph94w9tZddSjFjmQrVsW0z78uk=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "0182a361324364ae3f436a63005877674cf45efb",
|
"rev": "eaad089433ca2bb662274377d33df3d0e51ef28b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -34,9 +34,24 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1788057806,
|
||||||
|
"narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-parts": "flake-parts",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"rust-overlay": "rust-overlay"
|
"rust-overlay": "rust-overlay"
|
||||||
}
|
}
|
||||||
|
|
@ -48,11 +63,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1771556776,
|
"lastModified": 1789372034,
|
||||||
"narHash": "sha256-zKprqMQDl3xVfhSSYvgru1IGXjFdxryWk+KqK0I20Xk=",
|
"narHash": "sha256-mu6atvdBHYpDsFhJkPtSsS6auSWAnWONVJMCvpL0900=",
|
||||||
"owner": "oxalica",
|
"owner": "oxalica",
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"rev": "8b3f46b8a6d17ab46e533a5e3d5b1cc2ff228860",
|
"rev": "a5f41d15ba0e9442542c5324fbccd7a87105a90d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -60,21 +75,6 @@
|
||||||
"repo": "rust-overlay",
|
"repo": "rust-overlay",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
|
||||||
33
flake.nix
33
flake.nix
|
|
@ -2,41 +2,46 @@
|
||||||
description = "Bevy WASM website";
|
description = "Bevy WASM website";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
|
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
rust-overlay = {
|
rust-overlay = {
|
||||||
url = "github:oxalica/rust-overlay";
|
url = "github:oxalica/rust-overlay";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs = inputs@{
|
||||||
{
|
flake-parts,
|
||||||
self,
|
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
rust-overlay,
|
rust-overlay,
|
||||||
flake-utils,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
flake-utils.lib.eachDefaultSystem (
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
system:
|
systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
"x86_64-darwin"
|
||||||
|
"aarch64-darwin"
|
||||||
|
];
|
||||||
|
|
||||||
|
perSystem = { pkgs, system, ... }:
|
||||||
let
|
let
|
||||||
overlays = [ (import rust-overlay) ];
|
overlays = [ (import rust-overlay) ];
|
||||||
pkgs = import nixpkgs {
|
rustPkgs = import nixpkgs {
|
||||||
inherit system overlays;
|
inherit system overlays;
|
||||||
};
|
};
|
||||||
rustToolchain = pkgs.rust-bin.stable.latest.default.override {
|
rustToolchain = rustPkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
|
||||||
extensions = [ "rust-src" ];
|
|
||||||
targets = [ "wasm32-unknown-unknown" ];
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
rustToolchain
|
rustToolchain
|
||||||
pkgs.wasm-bindgen-cli
|
pkgs.wasm-bindgen-cli
|
||||||
|
pkgs.binaryen
|
||||||
|
pkgs.brotli
|
||||||
|
pkgs.just
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
);
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
36
justfile
Normal file
36
justfile
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# List available recipes
|
||||||
|
default:
|
||||||
|
@just --list
|
||||||
|
|
||||||
|
# Build the Bevy app to WASM (release by default; use `just build dev` for debug)
|
||||||
|
build profile="release":
|
||||||
|
./build-wasm.sh {{profile}}
|
||||||
|
|
||||||
|
# Build WASM in debug mode
|
||||||
|
build-dev:
|
||||||
|
./build-wasm.sh dev
|
||||||
|
|
||||||
|
# Build the HTTP server (release)
|
||||||
|
build-server:
|
||||||
|
cargo build --release -p server
|
||||||
|
|
||||||
|
# Build WASM + server for production
|
||||||
|
build-all: build build-server
|
||||||
|
|
||||||
|
# Run the server (serves ./static on :3000)
|
||||||
|
serve:
|
||||||
|
cargo run -p server
|
||||||
|
|
||||||
|
# Build WASM (release) then run the server
|
||||||
|
run: build
|
||||||
|
cargo run --release -p server
|
||||||
|
|
||||||
|
# Type-check the workspace
|
||||||
|
check:
|
||||||
|
cargo clippy --target wasm32-unknown-unknown -p app
|
||||||
|
cargo clippy --target x86_64-unknown-linux-gnu -p server
|
||||||
|
|
||||||
|
# Remove build artifacts
|
||||||
|
clean:
|
||||||
|
rm -rf static
|
||||||
|
cargo clean
|
||||||
3
rust-toolchain.toml
Normal file
3
rust-toolchain.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "1.98.1"
|
||||||
|
targets = ["wasm32-unknown-unknown", "x86_64-unknown-linux-gnu"]
|
||||||
|
|
@ -6,4 +6,4 @@
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tower-http = { version = "0.6", features = ["fs"] }
|
tower-http = { version = "0.7", features = ["fs"] }
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,13 @@ use tower_http::services::ServeDir;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
let static_files = ServeDir::new("static")
|
||||||
|
.precompressed_gzip()
|
||||||
|
.precompressed_br();
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/health", get(|| async { "OK" }))
|
.route("/health", get(|| async { "OK" }))
|
||||||
.fallback_service(ServeDir::new("static"));
|
.fallback_service(static_files);
|
||||||
|
|
||||||
println!("Listening on http://0.0.0.0:3000");
|
println!("Listening on http://0.0.0.0:3000");
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,17 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>3D Scene</title>
|
<title>Personal Website</title>
|
||||||
<style>
|
<style>
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #1a1a2e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -27,7 +23,7 @@
|
||||||
<body>
|
<body>
|
||||||
<canvas id="bevy-canvas"></canvas>
|
<canvas id="bevy-canvas"></canvas>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import init from './3dscene.js';
|
import init from './2dscene.js';
|
||||||
init();
|
init();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue