Compare commits

24 Commits

Author SHA1 Message Date
a8943fc924 update colors
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-30 12:53:10 +02:00
1d9c38e94a remove unneeded import
All checks were successful
continuous-integration/drone/push Build is passing
add tempblade logo
improve styling
improve animations
2023-06-30 12:08:03 +02:00
fa3f7a8403 remove tauri rust src and replace with lib
All checks were successful
continuous-integration/drone/push Build is passing
remove empty files
2023-06-27 16:46:54 +02:00
1d9508f49b remove test lib
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-27 15:07:38 +02:00
6d2ffe6902 move rust code to own library for targeting
All checks were successful
continuous-integration/drone/push Build is passing
multiple environments
like wasm, tauri and more
put non wasm compatible features like rayon multithreading
behind feature flags
2023-06-27 15:05:46 +02:00
c352ba7fd3 add private package secret to tauri build
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-27 00:36:39 +02:00
95087124b5 fix private package installation
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-27 00:33:35 +02:00
1d2f617a4e add github actions
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-27 00:06:22 +02:00
7fc923244e change wording
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-26 23:45:05 +02:00
f237d73016 add graph/visualization for interpolated keyframes
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-26 23:41:07 +02:00
cae187b939 improve bright mode coloring
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-26 10:29:06 +02:00
6f807b4df5 wording/grammar changes
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-26 01:38:38 +02:00
ee6e250277 fix p styling
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-26 01:35:37 +02:00
0dfa43c4ed animate cards
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-26 01:31:02 +02:00
b228f3cd8d update footer
All checks were successful
continuous-integration/drone/push Build is passing
improve landing bg
2023-06-26 01:14:35 +02:00
d78fe7b020 remove non navigateable footer links
All checks were successful
continuous-integration/drone/push Build is passing
add github to footer
add imprint
add marked
2023-06-26 01:02:57 +02:00
d8fedfb379 removed privacy link from footer since theres
All checks were successful
continuous-integration/drone/push Build is passing
no data processing
2023-06-26 00:33:51 +02:00
233442b099 improve mobile layout
All checks were successful
continuous-integration/drone/push Build is passing
update colors
remove landing button
2023-06-26 00:28:46 +02:00
0c7eedaee8 fix drone deploy
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-25 22:01:29 +02:00
7385b7ba41 add ci
All checks were successful
continuous-integration/drone Build is passing
add vercel deploy for web
2023-06-25 21:58:16 +02:00
74f7274a7e add icons
improve styling
improve landing bg
add astro-icon dep
2023-06-25 21:27:37 +02:00
ab7464eb83 Add discord link 2023-06-25 14:48:50 +02:00
512d102bb2 Remove unneeded import 2023-06-25 14:48:44 +02:00
82e0ee9280 add analytics 2023-06-25 14:48:33 +02:00
71 changed files with 5926 additions and 388 deletions

18
.drone.yml Normal file
View File

@@ -0,0 +1,18 @@
kind: pipeline
name: web
type: docker
steps:
- name: deploy web
image: node:alpine
environment:
IS_PROD: true
TOKEN:
from_secret: VERCEL_TOKEN
when:
branch:
- main
commands:
- npm install -g vercel@latest
- cd web
- /bin/sh deploy.sh

50
.github/workflows/publish.yml vendored Normal file
View File

@@ -0,0 +1,50 @@
name: "publish"
on:
push:
branches:
- release
jobs:
publish-tauri:
permissions:
contents: write
strategy:
fail-fast: false
matrix:
platform: [macos-latest, ubuntu-20.04, windows-latest]
runs-on: ${{ matrix.platform }}
defaults:
run:
working-directory: app
steps:
- uses: actions/checkout@v3
- name: setup node
uses: actions/setup-node@v3
with:
node-version: 16
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
- name: setup .npmrc
run: mv .npmrc.githubactions .npmrc
- name: install frontend dependencies
run: yarn install # change this to npm or pnpm depending on which one you use
env:
UNOM_PACKAGES_TOKEN: ${{ secrets.UNOM_PACKAGES_TOKEN }}
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UNOM_PACKAGES_TOKEN: ${{ secrets.UNOM_PACKAGES_TOKEN }}
with:
tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version
releaseName: "App v__VERSION__"
releaseBody: "See the assets to download this version and install."
releaseDraft: true
prerelease: false

39
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: "test-on-pr"
on: [pull_request]
jobs:
test-app:
strategy:
fail-fast: false
matrix:
platform: [macos-latest, ubuntu-20.04, windows-latest]
runs-on: ${{ matrix.platform }}
defaults:
run:
working-directory: app
steps:
- uses: actions/checkout@v3
- name: setup node
uses: actions/setup-node@v3
with:
node-version: 16
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
- name: setup .npmrc
run: mv .npmrc.githubactions .npmrc
- name: install frontend dependencies
run: yarn install # change this to npm or pnpm depending on which one you use
env:
UNOM_PACKAGES_TOKEN: ${{ secrets.UNOM_PACKAGES_TOKEN }}
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UNOM_PACKAGES_TOKEN: ${{ secrets.UNOM_PACKAGES_TOKEN }}

4
app/.npmrc.githubactions Normal file
View File

@@ -0,0 +1,4 @@
//packages.unom.io/:_authToken=${UNOM_PACKAGES_TOKEN}
registry=https://registry.npmjs.org/
@tempblade:registry=https://packages.unom.io
@unom:registry=https://packages.unom.io

View File

@@ -22,8 +22,19 @@
"@radix-ui/react-toolbar": "^1.0.3",
"@tauri-apps/api": "^1.3.0",
"@tempblade/common": "^2.0.1",
"@types/d3-array": "^3.0.5",
"@types/lodash.set": "^4.3.7",
"@unom/style": "^0.2.14",
"@visx/axis": "^3.1.0",
"@visx/event": "^3.0.1",
"@visx/glyph": "^3.0.0",
"@visx/gradient": "^3.0.0",
"@visx/grid": "^3.0.1",
"@visx/group": "^3.0.0",
"@visx/responsive": "^3.0.0",
"@visx/scale": "^3.0.0",
"@visx/shape": "^3.0.0",
"@visx/tooltip": "^3.1.2",
"canvaskit-wasm": "^0.38.1",
"class-variance-authority": "^0.6.0",
"clsx": "^1.2.1",

View File

@@ -418,6 +418,20 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "creator_rs"
version = "0.1.0"
dependencies = [
"font-kit",
"rayon",
"serde",
"serde_json",
"simple-easing",
"tauri",
"uuid",
"wasm-bindgen",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
@@ -441,14 +455,14 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.14"
version = "0.9.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"memoffset 0.9.0",
"scopeguard",
]
@@ -645,9 +659,9 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
[[package]]
name = "dlib"
version = "0.5.0"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
"libloading",
]
@@ -764,7 +778,7 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3cf3a800ff6e860c863ca6d4b16fd999db8b752819c1606884047b73e468535"
dependencies = [
"memoffset",
"memoffset 0.8.0",
"rustc_version 0.4.0",
]
@@ -1081,8 +1095,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]]
@@ -1547,12 +1563,12 @@ checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
[[package]]
name = "libloading"
version = "0.7.4"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb"
dependencies = [
"cfg-if",
"winapi",
"windows-sys 0.48.0",
]
[[package]]
@@ -1694,6 +1710,15 @@ dependencies = [
"autocfg",
]
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg",
]
[[package]]
name = "miniz_oxide"
version = "0.7.1"
@@ -1966,9 +1991,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]]
name = "pest"
version = "2.6.0"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70"
checksum = "f73935e4d55e2abf7f130186537b19e7a4abc886a0252380b59248af473a3fc9"
dependencies = [
"thiserror",
"ucd-trie",
@@ -2570,11 +2595,11 @@ dependencies = [
[[package]]
name = "serde_with"
version = "2.3.3"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe"
checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513"
dependencies = [
"base64 0.13.1",
"base64 0.21.0",
"chrono",
"hex",
"indexmap",
@@ -2586,9 +2611,9 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "2.3.3"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f"
checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070"
dependencies = [
"darling",
"proc-macro2",
@@ -2881,9 +2906,9 @@ checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5"
[[package]]
name = "tauri"
version = "1.3.0"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d42ba3a2e8556722f31336a0750c10dbb6a81396a1c452977f515da83f69f842"
checksum = "7fbe522898e35407a8e60dc3870f7579fea2fc262a6a6072eccdd37ae1e1d91e"
dependencies = [
"anyhow",
"cocoa",
@@ -2929,9 +2954,9 @@ dependencies = [
[[package]]
name = "tauri-build"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "929b3bd1248afc07b63e33a6a53c3f82c32d0b0a5e216e4530e94c467e019389"
checksum = "7d2edd6a259b5591c8efdeb9d5702cb53515b82a6affebd55c7fd6d3a27b7d1b"
dependencies = [
"anyhow",
"cargo_toml",
@@ -2942,14 +2967,13 @@ dependencies = [
"serde_json",
"tauri-utils",
"tauri-winres",
"winnow",
]
[[package]]
name = "tauri-codegen"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5a2105f807c6f50b2fa2ce5abd62ef207bc6f14c9fcc6b8caec437f6fb13bde"
checksum = "54ad2d49fdeab4a08717f5b49a163bdc72efc3b1950b6758245fcde79b645e1a"
dependencies = [
"base64 0.21.0",
"brotli",
@@ -2973,9 +2997,9 @@ dependencies = [
[[package]]
name = "tauri-macros"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8784cfe6f5444097e93c69107d1ac5e8f13d02850efa8d8f2a40fe79674cef46"
checksum = "8eb12a2454e747896929338d93b0642144bb51e0dddbb36e579035731f0d76b7"
dependencies = [
"heck 0.4.1",
"proc-macro2",
@@ -2987,9 +3011,9 @@ dependencies = [
[[package]]
name = "tauri-runtime"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3b80ea3fcd5fefb60739a3b577b277e8fc30434538a2f5bba82ad7d4368c422"
checksum = "108683199cb18f96d2d4134187bb789964143c845d2d154848dda209191fd769"
dependencies = [
"gtk",
"http",
@@ -3008,9 +3032,9 @@ dependencies = [
[[package]]
name = "tauri-runtime-wry"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1c396950b1ba06aee1b4ffe6c7cd305ff433ca0e30acbc5fa1a2f92a4ce70f1"
checksum = "0b7aa256a1407a3a091b5d843eccc1a5042289baf0a43d1179d9f0fcfea37c1b"
dependencies = [
"cocoa",
"gtk",
@@ -3028,12 +3052,13 @@ dependencies = [
[[package]]
name = "tauri-utils"
version = "1.3.0"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6f9c2dafef5cbcf52926af57ce9561bd33bb41d7394f8bb849c0330260d864"
checksum = "03fc02bb6072bb397e1d473c6f76c953cda48b4a2d0cce605df284aa74a12e84"
dependencies = [
"brotli",
"ctor",
"dunce",
"glob",
"heck 0.4.1",
"html5ever",
@@ -3068,16 +3093,13 @@ dependencies = [
name = "tempblade-creator-app"
version = "0.0.0"
dependencies = [
"font-kit",
"creator_rs",
"logging_timer",
"rayon",
"serde",
"serde_json",
"simple-easing",
"tauri",
"tauri-build",
"tint",
"uuid",
]
[[package]]
@@ -3382,15 +3404,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
dependencies = [
"getrandom 0.2.9",
"rand 0.8.5",
"uuid-macro-internal",
"wasm-bindgen",
]
[[package]]
name = "uuid-macro-internal"
version = "1.3.3"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f67b459f42af2e6e1ee213cb9da4dbd022d3320788c3fb3e1b893093f1e45da"
checksum = "8614dda80b9075fbca36bc31b58d1447715b1236af98dee21db521c47a0cc2c0"
dependencies = [
"proc-macro2",
"quote",

View File

@@ -10,20 +10,20 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
tauri-build = { version = "1.3", features = [] }
tauri-build = { version = "1.4", features = [] }
[dependencies]
uuid = { version = "1.3.3", features = ["v4", "fast-rng", "macro-diagnostics"] }
tauri = { version = "1.3", features = ["dialog-open", "dialog-save", "shell-open"] }
creator_core = { path = "../../lib/creator_rs", features = [
"fonts",
"parallelization",
"tauri",
], version = "*", package = "creator_rs" }
tauri = { version = "1.4", features = ["dialog-open", "dialog-save", "shell-open"] }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = "1.0"
tint = "1.0.0"
simple-easing = "1.0.1"
logging_timer = "1.1.0"
rayon = "1.7"
font-kit = "0.11.0"
[features]
# this feature is used for production builds or when `devPath` points to the filesystem

View File

@@ -1,129 +0,0 @@
use super::{
entities::common::AnimationData,
keyframe::{Keyframe, Keyframes},
};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
pub trait AnimatedValue<T> {
fn sort_keyframes(&mut self);
fn get_value_at_frame(&self, curr_frame: i32, animation_data: &AnimationData, fps: i16) -> T;
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AnimatedFloat {
pub keyframes: Keyframes,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AnimatedFloatVec2 {
pub keyframes: (AnimatedFloat, AnimatedFloat),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AnimatedFloatVec3 {
pub keyframes: (AnimatedFloat, AnimatedFloat, AnimatedFloat),
}
impl AnimatedFloat {
pub fn new(val: f32) -> AnimatedFloat {
AnimatedFloat {
keyframes: Keyframes {
values: vec![Keyframe {
id: Uuid::new_v4().to_string().into(),
value: val,
offset: 0.0,
interpolation: None,
}],
},
}
}
}
impl AnimatedFloatVec2 {
pub fn new(x: f32, y: f32) -> AnimatedFloatVec2 {
AnimatedFloatVec2 {
keyframes: (AnimatedFloat::new(x), AnimatedFloat::new(y)),
}
}
}
impl AnimatedFloatVec3 {
pub fn new(x: f32, y: f32, z: f32) -> AnimatedFloatVec3 {
AnimatedFloatVec3 {
keyframes: (
AnimatedFloat::new(x),
AnimatedFloat::new(y),
AnimatedFloat::new(z),
),
}
}
}
impl AnimatedValue<f32> for AnimatedFloat {
fn sort_keyframes(&mut self) {
self.keyframes.sort();
}
fn get_value_at_frame(&self, curr_frame: i32, animation_data: &AnimationData, fps: i16) -> f32 {
self.keyframes
.get_value_at_frame(curr_frame, &animation_data, fps)
}
}
impl AnimatedValue<(f32, f32, f32)> for AnimatedFloatVec3 {
fn sort_keyframes(&mut self) {
self.keyframes.0.sort_keyframes();
self.keyframes.1.sort_keyframes();
self.keyframes.2.sort_keyframes();
}
fn get_value_at_frame(
&self,
curr_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> (f32, f32, f32) {
let x = self
.keyframes
.0
.get_value_at_frame(curr_frame, animation_data, fps);
let y = self
.keyframes
.1
.get_value_at_frame(curr_frame, animation_data, fps);
let z = self
.keyframes
.2
.get_value_at_frame(curr_frame, animation_data, fps);
return (x, y, z);
}
}
impl AnimatedValue<(f32, f32)> for AnimatedFloatVec2 {
fn sort_keyframes(&mut self) {
self.keyframes.0.sort_keyframes();
self.keyframes.1.sort_keyframes();
}
fn get_value_at_frame(
&self,
curr_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> (f32, f32) {
let x = self
.keyframes
.0
.get_value_at_frame(curr_frame, animation_data, fps);
let y = self
.keyframes
.1
.get_value_at_frame(curr_frame, animation_data, fps);
return (x, y);
}
}

View File

@@ -1,21 +1,32 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use crate::{
animation::timeline::calculate_timeline_entities_at_frame,
fonts::{get_system_families, get_system_font, get_system_fonts},
use creator_core::{
__cmd__calculate_timeline_at_curr_frame, __cmd__get_system_families, __cmd__get_system_font,
__cmd__get_system_fonts, __cmd__get_values_at_frame_range_from_animated_float,
__cmd__get_values_at_frame_range_from_animated_float_vec2,
__cmd__get_values_at_frame_range_from_animated_float_vec3,
animation::{
primitives::values::animated_values::{
get_values_at_frame_range_from_animated_float,
get_values_at_frame_range_from_animated_float_vec2,
get_values_at_frame_range_from_animated_float_vec3,
},
timeline::calculate_timeline_at_curr_frame,
},
fonts::fonts::{get_system_families, get_system_font, get_system_fonts},
};
pub mod animation;
pub mod fonts;
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![
calculate_timeline_entities_at_frame,
calculate_timeline_at_curr_frame,
get_system_font,
get_system_families,
get_system_fonts
get_system_fonts,
get_values_at_frame_range_from_animated_float,
get_values_at_frame_range_from_animated_float_vec2,
get_values_at_frame_range_from_animated_float_vec3
])
.run(tauri::generate_context!())
.expect("error while running tauri application");

View File

@@ -17,8 +17,13 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm",
"placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
"shadow-main/10 shadow-[0_0_0_1px]",
"flex h-10 w-full items-center justify-between rounded-md",
"text-main bg-transparent px-3 py-2 text-sm placeholder:text-main outline-none",
"disabled:cursor-not-allowed disabled:opacity-50 transition-all",
"focus:outline-none focus:ring-2 focus:ring-offset-1 focus:shadow-primary",
"focus:ring-primary",
"hover:shadow-primary/50",
className
)}
{...props}
@@ -39,7 +44,8 @@ const SelectContent = React.forwardRef<
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-neutral-accent text-popover-foreground shadow-md animate-in fade-in-80",
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-neutral-accent",
"text-main shadow-md animate-in fade-in-80",
className
)}
{...props}
@@ -58,7 +64,7 @@ const SelectLabel = React.forwardRef<
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
className={cn("py-1.5 pl-8 pr-2 text-sm text-main font-semibold", className)}
{...props}
/>
));
@@ -72,7 +78,7 @@ const SelectItem = React.forwardRef<
ref={ref}
className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
"focus:bg-primary focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
"focus:bg-primary focus:text-neutral dark:focus:text-main text-main data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
)}
{...props}
@@ -83,7 +89,7 @@ const SelectItem = React.forwardRef<
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
<SelectPrimitive.ItemText className="text-main">{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = SelectPrimitive.Item.displayName;
@@ -94,7 +100,7 @@ const SelectSeparator = React.forwardRef<
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-slate-800", className)}
className={cn("-mx-1 my-1 h-px bg-slate-main", className)}
{...props}
/>
));

View File

@@ -8,8 +8,8 @@ import { shallow } from "zustand/shallow";
import KeyframeIndicator from "./KeyframeIndicator";
import { TIMELINE_SCALE, calculateOffset } from "./common";
import { TriangleDownIcon } from "@radix-ui/react-icons";
import TrackPropertiesEditor from "./TrackPropertiesEditor";
import { flattenedKeyframesByEntity } from "utils";
import TrackPropertiesEditor from "./TrackDisplay/TrackPropertiesEditor";
import { cn, flattenedKeyframesByEntity } from "utils";
type TrackProps = {
animationData: z.input<typeof AnimationData>;
@@ -18,6 +18,10 @@ type TrackProps = {
entity: z.input<typeof AnimatedEntity>;
};
const TrackDisplayTypeOptions = ["Default", "Graph"] as const;
export const TrackDisplayType = z.enum(TrackDisplayTypeOptions);
const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
const controls = useDragControls();
@@ -56,20 +60,18 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
onMouseDown={(e) => e.preventDefault()}
onPointerDown={(e) => controls.start(e)}
className={`h-full transition-all rounded-sm min-w-[200px] p-1 px-2 flex flex-col ${
selectedEntity === index ? "bg-highlight" : "bg-neutral-accent"
selectedEntity === index
? "bg-highlight text-neutral dark:text-main"
: "bg-neutral-accent text-main"
}`}
>
<div className="flex flex-row">
<motion.div
onClick={() => setIsExpanded(!isExpanded)}
className="will-change-transform"
className={cn("will-change-transform")}
animate={{ rotate: isExpanded ? 0 : -90 }}
>
<TriangleDownIcon
width="32px"
height="32px"
className="text-white"
/>
<TriangleDownIcon width="32px" height="32px" />
</motion.div>
<h3
onClick={() =>
@@ -77,7 +79,7 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
? deselectEntity()
: selectEntity(index)
}
className="text-white-800 h-2 text-base leading-loose font-semibold select-none cursor-pointer"
className="h-2 text-base leading-loose font-semibold select-none cursor-pointer"
>
{name}
</h3>
@@ -133,10 +135,10 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
},
});
}}
className="z-10 w-4 bg-primary/80 h-full top-0 absolute rounded-md select-none cursor-w-resize"
className="z-10 w-4 bg-primary/50 h-full top-0 absolute rounded-md select-none cursor-w-resize"
/>
<motion.div
className="z-10 w-4 bg-primary/80 h-full top-0 absolute rounded-md select-none cursor-e-resize"
className="z-10 w-4 bg-primary/50 h-full top-0 absolute rounded-md select-none cursor-e-resize"
onMouseDown={(e) => e.preventDefault()}
drag="x"
animate={{

View File

@@ -0,0 +1,64 @@
import { FC } from "react";
import { extent, bisector } from "d3-array";
import { curveNatural } from "@visx/curve";
import { scaleLinear } from "@visx/scale";
import { LinePath } from "@visx/shape";
import { Group } from "@visx/group";
const HEIGHT = 300;
const WIDTH = 1200;
type PropertyValue = {
value: number;
frame: number;
};
const getValue = (d: PropertyValue) => d.value;
const getFrame = (d: PropertyValue) => d.frame;
const PropertyGraph: FC<{
values: Array<{ frame: number; value: number }>;
}> = ({ values }) => {
const framesScale = scaleLinear({
range: [0, WIDTH],
domain: extent(values, getFrame) as [number, number],
nice: true,
});
const valuesScale = scaleLinear({
range: [HEIGHT, 0],
domain: extent(values, getValue) as [number, number],
nice: true,
});
return (
<Group>
<LinePath
curve={curveNatural}
stroke="white"
strokeWidth={3}
data={values}
x={(d) => framesScale(getFrame(d)) ?? 0}
y={(d) => valuesScale(getValue(d)) ?? 0}
/>
</Group>
);
};
const Graphs: FC<{ values: Array<Array<number>> }> = ({ values }) => {
return (
<svg width={WIDTH} height={HEIGHT}>
{values.map((propertyValues) => (
<PropertyGraph
values={propertyValues.map((val, index) => ({
frame: index,
value: val,
}))}
/>
))}
</svg>
);
};
export default Graphs;

View File

@@ -11,15 +11,22 @@ import {
AnimatedNumberKeyframeIndicator,
AnimatedVec2KeyframeIndicator,
AnimatedVec3KeyframeIndicator,
} from "./KeyframeIndicator";
} from "../KeyframeIndicator";
import { ToggleGroup, ToggleGroupItem } from "components/ToggleGroup";
import { produce } from "immer";
import set from "lodash.set";
import { useEntitiesStore } from "stores/entities.store";
import { shallow } from "zustand/shallow";
import { AnimatedValue } from "primitives/Values";
import { motion } from "framer-motion";
import { ease } from "@unom/style";
import { TrackDisplayType } from "../Track";
import TrackPropertyGraph from "./TrackPropertyGraph";
import { LineChart } from "lucide-react";
type DisplayState = {
type: z.input<typeof TrackDisplayType>;
selectedAnimatedProperties: Array<number>;
};
const TrackAnimatedPropertyKeyframes: FC<{
animatedProperty: z.input<typeof AnimatedProperty>;
@@ -70,12 +77,23 @@ const TrackAnimatedPropertyKeyframes: FC<{
const TrackAnimatedProperty: FC<{
animatedProperty: z.input<typeof AnimatedProperty>;
animationData: z.input<typeof AnimationData>;
displayState: DisplayState;
index: number;
onDisplayStateUpdate: (s: DisplayState) => void;
onUpdate: (e: z.input<typeof AnimatedProperty>) => void;
}> = ({ animatedProperty, animationData, onUpdate }) => {
}> = ({
animatedProperty,
animationData,
onUpdate,
displayState,
index,
onDisplayStateUpdate,
}) => {
const [selectedDimension, setSelectedDimension] = useState<"x" | "y" | "z">();
return (
<motion.div
layout
transition={ease.quint(0.8).out}
variants={{ enter: { y: 0, opacity: 1 }, from: { y: -10, opacity: 0 } }}
className="flex flex-row bg-neutral-accent ml-2 align-center"
@@ -115,8 +133,33 @@ const TrackAnimatedProperty: FC<{
Z
</ToggleGroupItem>
)}
<ToggleGroupItem
selected={displayState.selectedAnimatedProperties.includes(index)}
onClick={() => {
if (displayState.selectedAnimatedProperties.includes(index)) {
onDisplayStateUpdate({
...displayState,
selectedAnimatedProperties:
displayState.selectedAnimatedProperties.filter(
(index) => index !== index
),
});
} else {
onDisplayStateUpdate({
...displayState,
selectedAnimatedProperties: [
...displayState.selectedAnimatedProperties,
index,
],
});
}
}}
>
<LineChart />
</ToggleGroupItem>
</ToggleGroup>
</div>
<div className="relative">
<TrackAnimatedPropertyKeyframes
selectedDimension={
@@ -153,30 +196,45 @@ const TrackPropertiesEditor: FC<{
const parsedEntity = AnimatedEntity.parse(nextValue);
console.log("reacreated callback");
entitiesStore.updateEntityById(parsedEntity.id, parsedEntity);
},
[entity]
);
const [displayState, setDisplayState] = useState<DisplayState>({
type: TrackDisplayType.Enum.Default,
selectedAnimatedProperties: [],
});
return (
<motion.div
animate="enter"
initial="from"
variants={{ enter: {}, from: {} }}
transition={{ staggerChildren: 0.05 }}
layout
className="flex flex-col gap-1"
>
{animatedProperties.map((animatedProperty, index) => (
<TrackAnimatedProperty
onUpdate={handleUpdate}
<motion.div layout className="flex flex-row">
<motion.div
animate="enter"
initial="from"
variants={{ enter: {}, from: {} }}
transition={{ staggerChildren: 0.05 }}
className="flex flex-col gap-1"
>
{animatedProperties.map((animatedProperty, index) => (
<TrackAnimatedProperty
index={index}
onDisplayStateUpdate={setDisplayState}
displayState={displayState}
onUpdate={handleUpdate}
animationData={entity.animation_data}
key={index}
animatedProperty={animatedProperty}
/>
))}
</motion.div>
{displayState.selectedAnimatedProperties.length > 0 && (
<TrackPropertyGraph
animationData={entity.animation_data}
key={index}
animatedProperty={animatedProperty}
animatedProperties={displayState.selectedAnimatedProperties.map(
(index) => animatedProperties[index]
)}
/>
))}
)}
</motion.div>
);
};

View File

@@ -0,0 +1,108 @@
import { invoke } from "@tauri-apps/api";
import { AnimationData } from "primitives/AnimatedEntities";
import { AnimatedProperty } from "primitives/AnimatedProperty";
import { AnimatedValue, ValueType } from "primitives/Values";
import { FC, useEffect, useState } from "react";
import { z } from "zod";
import Graph from "./Graph";
type TrackPropertyPathProps = {
animatedProperties: Array<z.input<typeof AnimatedProperty>>;
animationData: z.input<typeof AnimationData>;
};
const TrackPropertyGraph: FC<TrackPropertyPathProps> = ({
animatedProperties,
animationData,
}) => {
const [values, setValues] = useState<Array<Array<number>>>([]);
useEffect(() => {
const tasks: Array<Promise<Array<Array<number>>>> = [];
animatedProperties.forEach((animatedProperty) => {
animatedProperty.animatedValue.type;
const animatedValue = animatedProperty.animatedValue;
const commonValues: {
animatedValue: z.input<typeof AnimatedValue>;
startFrame: number;
endFrame: number;
fps: number;
animationData: z.input<typeof AnimationData>;
} = {
animatedValue: AnimatedValue.parse(animatedValue),
startFrame: 0,
endFrame: 600,
fps: 60,
animationData: AnimationData.parse(animationData),
};
switch (animatedValue.type) {
case ValueType.Enum.Number:
tasks.push(
invoke(
"get_values_at_frame_range_from_animated_float",
commonValues
).then((data) => {
const numbers = data as Array<number>;
return [numbers];
})
);
break;
case ValueType.Enum.Vec2:
tasks.push(
invoke(
"get_values_at_frame_range_from_animated_float_vec2",
commonValues
).then((data) => {
const vectors = data as [Array<number>, Array<number>];
const xValues = vectors.map((vec2) => vec2[0]);
const yValues = vectors.map((vec2) => vec2[1]);
return [xValues, yValues];
})
);
break;
case ValueType.Enum.Vec3:
tasks.push(
invoke(
"get_values_at_frame_range_from_animated_float_vec3",
commonValues
).then((data) => {
const vectors = data as [
Array<number>,
Array<number>,
Array<number>
];
const xValues = vectors.map((vec2) => vec2[0]);
const yValues = vectors.map((vec2) => vec2[1]);
const zValues = vectors.map((vec2) => vec2[2]);
return [xValues, yValues, zValues];
})
);
break;
}
});
Promise.all(tasks).then((values) => {
const flatValues = values.flat();
console.log("flattened Values", flatValues);
setValues(flatValues);
});
}, animatedProperties);
return (
<div>
<Graph values={values} />
</div>
);
};
export default TrackPropertyGraph;

View File

@@ -31,10 +31,10 @@ const Timeline: FC<TimelineProps> = () => {
<div className="flex flex-row">
<div className="flex flex-row">
<button onClick={() => setPlaying(true)} className="w-8 h-8">
<PlayIcon color="white" width="100%" height="100%" />
<PlayIcon className="text-main" width="100%" height="100%" />
</button>
<button onClick={() => setPlaying(false)} className="w-8 h-8">
<PauseIcon color="white" width="100%" height="100%" />
<PauseIcon className="text-main" width="100%" height="100%" />
</button>
</div>
<Timestamp />

View File

@@ -90,7 +90,7 @@ export class Drawer {
const parsedAnimatedEntities = AnimatedEntities.parse(animatedEntities);
const data = await invoke("calculate_timeline_entities_at_frame", {
const data = await invoke("calculate_timeline_at_curr_frame", {
timeline: {
entities: parsedAnimatedEntities,
render_state: renderState,

View File

@@ -1,6 +1,5 @@
import { z } from "zod";
import { Interpolation } from "./Interpolation";
import { v4 as uuid } from "uuid";
export const Keyframe = z.object({
id: z.string().uuid(),

View File

@@ -5,6 +5,8 @@ import { v4 as uuid } from "uuid";
export const Vec2 = z.array(z.number()).length(2);
export const Vec3 = z.array(z.number()).length(3);
const ValueTypeOptions = ["Vec2", "Vec3", "Number"] as const;
export const ValueType = z.enum(ValueTypeOptions);

View File

@@ -0,0 +1,32 @@
import { Timeline } from "primitives/Timeline";
// TODO: publish package maybe provide wrapper etc.
import * as creatorWasm from "../../../lib/creator_rs/pkg";
import { z } from "zod";
import { useTimelineStore } from "stores/timeline.store";
import { useEntitiesStore } from "stores/entities.store";
import { useRenderStateStore } from "stores/render-state.store";
export class RenderService {
render() {
}
calculate() {
const timelineStore = useTimelineStore.getState();
const entitiesStore = useEntitiesStore.getState();
const renderStateStore = useRenderStateStore.getState();
let timeline: z.input<typeof Timeline> = {
...timelineStore,
entities: entitiesStore.entities,
render_state: renderStateStore.renderState
}
timeline = Timeline.parse(timeline);
const renderedEntities = creatorWasm.calculate_timeline_from_json_at_curr_frame(JSON.stringify(timeline));
console.log(renderedEntities);
}
}

View File

@@ -13,24 +13,16 @@
@apply text-lg;
}
span {
@apply text-white;
}
a {
@apply text-blue-600 underline;
}
select,
input {
@apply box-border bg-transparent shadow-main/10 hover:shadow-primary/50
focus:ring-primary focus:ring-2 focus:ring-offset-2
focus:ring-primary focus:ring-2 focus:ring-offset-1
focus:shadow-primary selection:bg-secondary selection:text-black
outline-none px-3 py-2 rounded-md shadow-[0_0_0_1px];
}
input {
@apply appearance-none items-center justify-center
outline-none px-3 py-2 rounded-md shadow-[0_0_0_1px]
appearance-none items-center justify-center
w-full text-base leading-none transition-all;
}

View File

@@ -971,6 +971,52 @@
resolved "https://packages.unom.io/@tempblade%2fcommon/-/common-2.0.1.tgz"
integrity sha512-8uCqsfu2tcQq4O4XODS7Hn7Mj9hZh+Rh+Y0Fsej9Bbemn/WwlIT0WrUSzWGMZLcTspvgl6kz/ljBzCqLAa3Yyw==
"@types/d3-array@^3.0.5":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.5.tgz#857c1afffd3f51319bbc5b301956aca68acaa7b8"
integrity sha512-Qk7fpJ6qFp+26VeQ47WY0mkwXaiq8+76RJcncDEfMc2ocRzXLO67bLFRNI4OX1aGBoPzsM5Y2T+/m1pldOgD+A==
"@types/d3-color@*":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.0.tgz#6594da178ded6c7c3842f3cc0ac84b156f12f2d4"
integrity sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==
"@types/d3-interpolate@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz#e7d17fa4a5830ad56fe22ce3b4fac8541a9572dc"
integrity sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==
dependencies:
"@types/d3-color" "*"
"@types/d3-path@^1", "@types/d3-path@^1.0.8":
version "1.0.9"
resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c"
integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==
"@types/d3-scale@^4.0.2":
version "4.0.3"
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.3.tgz#7a5780e934e52b6f63ad9c24b105e33dd58102b5"
integrity sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==
dependencies:
"@types/d3-time" "*"
"@types/d3-shape@^1.3.1":
version "1.3.8"
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.8.tgz#c3c15ec7436b4ce24e38de517586850f1fea8e89"
integrity sha512-gqfnMz6Fd5H6GOLYixOZP/xlrMtJms9BaS+6oWxTKHNqPGZ93BkWWupQSCYm6YHqx6h9wjRupuJb90bun6ZaYg==
dependencies:
"@types/d3-path" "^1"
"@types/d3-time@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.0.tgz#e1ac0f3e9e195135361fa1a1d62f795d87e6e819"
integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==
"@types/d3-time@^2.0.0":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342"
integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==
"@types/lodash.set@^4.3.7":
version "4.3.7"
resolved "https://registry.npmjs.org/@types/lodash.set/-/lodash.set-4.3.7.tgz"
@@ -978,7 +1024,7 @@
dependencies:
"@types/lodash" "*"
"@types/lodash@*":
"@types/lodash@*", "@types/lodash@^4.14.172":
version "4.14.195"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz"
integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==
@@ -993,6 +1039,13 @@
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
"@types/react-dom@*":
version "18.2.6"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.6.tgz#ad621fa71a8db29af7c31b41b2ea3d8a6f4144d1"
integrity sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A==
dependencies:
"@types/react" "*"
"@types/react-dom@^18.0.6":
version "18.2.4"
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz"
@@ -1026,6 +1079,156 @@
dependencies:
css-color-converter "^2.0.0"
"@visx/axis@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@visx/axis/-/axis-3.1.0.tgz#775b221e5abfdec25304c607eeae8cda1a8bade6"
integrity sha512-JDj/1VYx0JO0pHFtwoFtYcnqdoZFh/dpHImEl169S5nTslSFlIoNTXA/ekpBP6ELkEZ59gmF1X5k29x6MFBwCA==
dependencies:
"@types/react" "*"
"@visx/group" "3.0.0"
"@visx/point" "3.0.1"
"@visx/scale" "3.0.0"
"@visx/shape" "3.0.0"
"@visx/text" "3.0.0"
classnames "^2.3.1"
prop-types "^15.6.0"
"@visx/bounds@3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/bounds/-/bounds-3.0.0.tgz#cf357cbff90a1fe5f95eb9d9288dd8794b744a7f"
integrity sha512-YQaSSER9erxlhppzRms6cvYdKqcIwk6eksrGdbJkBoHobhPo1JCIUXlmrA4qgrEnXInPJpueGE+PE5F+Dk12DA==
dependencies:
"@types/react" "*"
"@types/react-dom" "*"
prop-types "^15.5.10"
"@visx/curve@3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/curve/-/curve-3.0.0.tgz#c54568472e00a38483c58cf52e4a6ddb2887c2d4"
integrity sha512-kvHJDLBeczTQ87ZExSTfRxej06l6o6UiQ0NHf9+xpAin06y6Qk1ThOHHWJTGM6KGzwlu7jEauJGHwZs6nMhDvA==
dependencies:
"@types/d3-shape" "^1.3.1"
d3-shape "^1.0.6"
"@visx/event@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@visx/event/-/event-3.0.1.tgz#d5358f52ff5ef30036d955bd2b68b96472ff2d6f"
integrity sha512-tK1EUYQLLStBuoCMbm8LJ3VbDyCVI8HjT0pMRQxm+C75FSIVWvrThgrfrC9sWOFnEMEYWspZO7hI5zjsPKjLQA==
dependencies:
"@types/react" "*"
"@visx/point" "3.0.1"
"@visx/glyph@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/glyph/-/glyph-3.0.0.tgz#218a96aa0ccba95dc77e46ab08d26ad89198f3a8"
integrity sha512-r1B0IocfWfhTABKjam0qqsWKjxLxZfGwefnwn8IcfELSd9iAUtLbI/46nP4roQRHhB/Wl3RBbgA97fZw8f1MxA==
dependencies:
"@types/d3-shape" "^1.3.1"
"@types/react" "*"
"@visx/group" "3.0.0"
classnames "^2.3.1"
d3-shape "^1.2.0"
prop-types "^15.6.2"
"@visx/gradient@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/gradient/-/gradient-3.0.0.tgz#39b55dd5a0b34feb219fcb2ea5525388c5ae0c1b"
integrity sha512-UoM9R9PIPLO/w7hCW9gFncrLdpKNqh13sLS9/0Iy6b75uP2l05FLG2HX4kXljeyOrj4/XyzRCMYm0HHk/p5iMA==
dependencies:
"@types/react" "*"
prop-types "^15.5.7"
"@visx/grid@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@visx/grid/-/grid-3.0.1.tgz#d91085ed92e7e1c0c2e58710bc33b2f0f33b8e74"
integrity sha512-cln5CVvFG58C5Uz1Uf0KRBFmGmgD1NALOQdYDu5yPsTuY2yLzVYPvCIlYBMdUtE0uzfNq972SmkZHfZYs03jxQ==
dependencies:
"@types/react" "*"
"@visx/curve" "3.0.0"
"@visx/group" "3.0.0"
"@visx/point" "3.0.1"
"@visx/scale" "3.0.0"
"@visx/shape" "3.0.0"
classnames "^2.3.1"
prop-types "^15.6.2"
"@visx/group@3.0.0", "@visx/group@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/group/-/group-3.0.0.tgz#e7f9752599bcc7e141ff5317a2a9a502577ab8df"
integrity sha512-SFjXhTMcsaVAb1/TVL1KM5vn8gQTIVgSx0ATdDl4BJSFp2ym1lO8LY4jpV4SFweaHnWxVwrrfGLTn5QsYnvmjQ==
dependencies:
"@types/react" "*"
classnames "^2.3.1"
prop-types "^15.6.2"
"@visx/point@3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@visx/point/-/point-3.0.1.tgz#77587ddaabf6f3023f09f8a0ce33a2c27c9d64c8"
integrity sha512-S5WOBMgEP2xHcgs3A2BFB2vwzrk0tMmn3PGZAbQJ+lu4HlnalDP72klUnxLTH8xclNNvpUHtHM5eLIJXyHx6Pw==
"@visx/responsive@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/responsive/-/responsive-3.0.0.tgz#e183c54ce04cffe756378872d30ac88c66a137ac"
integrity sha512-immnxQwOWlrxbnlCIqJWuDpPfrM6tglgMTN1WsyXyGluLMJqhuuxqxllfXaRPkQFS4fcvs66KCEELdazh96U2w==
dependencies:
"@types/lodash" "^4.14.172"
"@types/react" "*"
lodash "^4.17.21"
prop-types "^15.6.1"
"@visx/scale@3.0.0", "@visx/scale@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/scale/-/scale-3.0.0.tgz#727123f0c930d3346a4473e926831c45997e0312"
integrity sha512-WSf+wrxZEvu5TPGfGTafzzX1MbogbIxfD9ZKM9p7xfw65v23G0dNMy4bqVBUbOJigONoQkIZyqQ+gz5AJ/ioIg==
dependencies:
"@types/d3-interpolate" "^3.0.1"
"@types/d3-scale" "^4.0.2"
"@types/d3-time" "^2.0.0"
d3-interpolate "^3.0.1"
d3-scale "^4.0.2"
d3-time "^2.1.1"
"@visx/shape@3.0.0", "@visx/shape@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/shape/-/shape-3.0.0.tgz#a1d4bd0e12cc94c164252f175997932a09c24652"
integrity sha512-t6lpP9bIA1vwChDwiOUWl92ro29XF/M8IVNWRA0pm4LGxGGTACvxG3Agfcdi3JprahUVqPpnRCwuR36PDanq3Q==
dependencies:
"@types/d3-path" "^1.0.8"
"@types/d3-shape" "^1.3.1"
"@types/lodash" "^4.14.172"
"@types/react" "*"
"@visx/curve" "3.0.0"
"@visx/group" "3.0.0"
"@visx/scale" "3.0.0"
classnames "^2.3.1"
d3-path "^1.0.5"
d3-shape "^1.2.0"
lodash "^4.17.21"
prop-types "^15.5.10"
"@visx/text@3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/text/-/text-3.0.0.tgz#9099c3605027b9ab4c54bde97518a648136c3629"
integrity sha512-LW6v5T/gpd9RGw83/ScXncYc6IlcfzXTpaN8WbbxLRI65gdvSqrykwAMR0cbpQmzoVFuZXljqOf0QslHGnBg1w==
dependencies:
"@types/lodash" "^4.14.172"
"@types/react" "*"
classnames "^2.3.1"
lodash "^4.17.21"
prop-types "^15.7.2"
reduce-css-calc "^1.3.0"
"@visx/tooltip@^3.1.2":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@visx/tooltip/-/tooltip-3.1.2.tgz#6c7bb36a296f4501adb99b59487412e39fe06f44"
integrity sha512-p46qztGRNkEDbxzc3V1virahvz3UQ29TzddUjA0oaTIBCrOd9UJuLvv1Tq9OpeUYPdbrO/ZRwaEeri2pbwv04Q==
dependencies:
"@types/react" "*"
"@visx/bounds" "3.0.0"
classnames "^2.3.1"
prop-types "^15.5.10"
react-use-measure "^2.0.4"
"@vitejs/plugin-react@^3.0.0":
version "3.1.0"
resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz"
@@ -1081,6 +1284,11 @@ autoprefixer@^10.4.14:
picocolors "^1.0.0"
postcss-value-parser "^4.2.0"
balanced-match@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
integrity sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
@@ -1162,6 +1370,11 @@ class-variance-authority@^0.6.0:
dependencies:
clsx "1.2.1"
classnames@^2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
clsx@1.2.1, clsx@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz"
@@ -1228,6 +1441,86 @@ csstype@^3.0.2:
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
d3-array@2:
version "2.12.1"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81"
integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==
dependencies:
internmap "^1.0.0"
"d3-array@2 - 3", "d3-array@2.10.0 - 3":
version "3.2.4"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5"
integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==
dependencies:
internmap "1 - 2"
"d3-color@1 - 3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
"d3-format@1 - 3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641"
integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==
"d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
dependencies:
d3-color "1 - 3"
d3-path@1, d3-path@^1.0.5:
version "1.0.9"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
d3-scale@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396"
integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==
dependencies:
d3-array "2.10.0 - 3"
d3-format "1 - 3"
d3-interpolate "1.2.0 - 3"
d3-time "2.1.1 - 3"
d3-time-format "2 - 4"
d3-shape@^1.0.6, d3-shape@^1.2.0:
version "1.3.7"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
dependencies:
d3-path "1"
"d3-time-format@2 - 4":
version "4.1.0"
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
dependencies:
d3-time "1 - 3"
"d3-time@1 - 3", "d3-time@2.1.1 - 3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7"
integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==
dependencies:
d3-array "2 - 3"
d3-time@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682"
integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==
dependencies:
d3-array "2"
debounce@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==
debug@^4.1.0, debug@^4.1.1:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
@@ -1423,6 +1716,16 @@ inherits@2:
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
"internmap@1 - 2":
version "2.0.3"
resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
internmap@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz"
@@ -1496,7 +1799,12 @@ lodash.set@^4.3.2:
resolved "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz"
integrity sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==
loose-envify@^1.0.0, loose-envify@^1.1.0:
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -1522,6 +1830,11 @@ magic-string@^0.27.0:
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.13"
math-expression-evaluator@^1.2.14:
version "1.4.0"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz#3d66031117fbb7b9715ea6c9c68c2cd2eebd37e2"
integrity sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw==
merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
@@ -1576,7 +1889,7 @@ normalize-range@^0.1.2:
resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
object-assign@^4.0.1:
object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@@ -1676,6 +1989,15 @@ postcss@^8.4.23:
picocolors "^1.0.0"
source-map-js "^1.0.2"
prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.13.1"
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
@@ -1689,6 +2011,11 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-refresh@^0.14.0:
version "0.14.0"
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz"
@@ -1722,6 +2049,13 @@ react-style-singleton@^2.2.1:
invariant "^2.2.4"
tslib "^2.0.0"
react-use-measure@^2.0.4:
version "2.1.1"
resolved "https://registry.yarnpkg.com/react-use-measure/-/react-use-measure-2.1.1.tgz#5824537f4ee01c9469c45d5f7a8446177c6cc4ba"
integrity sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==
dependencies:
debounce "^1.2.1"
react@^18.2.0:
version "18.2.0"
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
@@ -1743,6 +2077,22 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
reduce-css-calc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716"
integrity sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==
dependencies:
balanced-match "^0.4.2"
math-expression-evaluator "^1.2.14"
reduce-function-call "^1.0.1"
reduce-function-call@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f"
integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ==
dependencies:
balanced-match "^1.0.0"
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz"

1
lib/creator_rs/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
target

3834
lib/creator_rs/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

31
lib/creator_rs/Cargo.toml Normal file
View File

@@ -0,0 +1,31 @@
[package]
name = "creator_rs"
version = "0.1.0"
edition = "2021"
authors = ["Enrico Bühler <buehler@unom.io>"]
description = "Motion Design toolkit with spring, eased and linear based value interpolation, timeline functionality and more"
license = "MIT"
repository = "https://github.com/tempblade/creator"
[lib]
crate-type = ["cdylib", "lib"]
[dependencies]
rayon = { version = "1.7", optional = true }
font-kit = { version = "0.11", optional = true }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = "1.0"
simple-easing = "1.0"
tauri = { version = "1.4", optional = true, features = [
"dialog-open",
"dialog-save",
"shell-open",
] }
uuid = { version = "1.3", features = ["v4", "macro-diagnostics", "js"] }
wasm-bindgen = "0.2"
[features]
tauri = ["dep:tauri"]
parallelization = ["dep:rayon"]
fonts = ["dep:font-kit"]

View File

@@ -4,7 +4,7 @@ use crate::animation::{
primitives::{
paint::Paint,
transform::{AnimatedTransform, Transform},
values::{AnimatedFloatVec2, AnimatedValue},
values::animated_values::{AnimatedFloatVec2, AnimatedValue},
},
timeline::Timeline,
};

View File

@@ -4,7 +4,7 @@ use crate::animation::{
primitives::{
paint::Paint,
transform::{AnimatedTransform, Transform},
values::{AnimatedFloatVec2, AnimatedValue},
values::animated_values::{AnimatedFloatVec2, AnimatedValue},
},
timeline::Timeline,
};

View File

@@ -3,7 +3,7 @@ use crate::animation::{
primitives::{
paint::TextPaint,
transform::{AnimatedTransform, Transform},
values::{AnimatedFloatVec2, AnimatedValue},
values::animated_values::{AnimatedFloatVec2, AnimatedValue},
},
timeline::Timeline,
};

View File

@@ -2,7 +2,7 @@ use crate::animation::{
primitives::{
paint::TextPaint,
transform::{AnimatedTransform, Transform},
values::{AnimatedFloatVec2, AnimatedValue},
values::animated_values::{AnimatedFloatVec2, AnimatedValue},
},
timeline::Timeline,
};

View File

@@ -6,11 +6,12 @@ use super::{
entities::common::AnimationData,
interpolations::{interpolate_rendered_keyframes, InterpolationType},
utils::render_keyframe,
values::values::Float,
};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Keyframe {
pub value: f32,
pub value: Float,
pub offset: f32,
pub id: Arc<str>,
pub interpolation: Option<InterpolationType>,

View File

@@ -1,6 +1,6 @@
use super::{
entities::common::AnimationData,
values::{AnimatedFloatVec2, AnimatedFloatVec3, AnimatedValue},
values::animated_values::{AnimatedFloatVec2, AnimatedFloatVec3, AnimatedValue},
};
use crate::animation::timeline::Timeline;
use serde::{Deserialize, Serialize};

View File

@@ -0,0 +1,268 @@
use crate::animation::primitives::{
entities::common::AnimationData,
keyframe::{Keyframe, Keyframes},
};
#[cfg(feature = "parallelization")]
use rayon::prelude::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use super::values::{Float, FloatVec2, FloatVec3};
pub trait AnimatedValue<T> {
fn sort_keyframes(&mut self);
fn get_value_at_frame(&self, curr_frame: i32, animation_data: &AnimationData, fps: i16) -> T;
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<T>;
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AnimatedFloat {
pub keyframes: Keyframes,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AnimatedFloatVec2 {
pub keyframes: (AnimatedFloat, AnimatedFloat),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AnimatedFloatVec3 {
pub keyframes: (AnimatedFloat, AnimatedFloat, AnimatedFloat),
}
#[cfg_attr(feature = "tauri", tauri::command)]
pub fn get_values_at_frame_range_from_animated_float(
animated_value: AnimatedFloat,
start_frame: i32,
end_frame: i32,
animation_data: AnimationData,
fps: i16,
) -> Vec<Float> {
animated_value.get_values_at_frame_range(start_frame, end_frame, &animation_data, fps)
}
#[cfg_attr(feature = "tauri", tauri::command)]
pub fn get_values_at_frame_range_from_animated_float_vec2(
animated_value: AnimatedFloatVec2,
start_frame: i32,
end_frame: i32,
animation_data: AnimationData,
fps: i16,
) -> Vec<FloatVec2> {
animated_value.get_values_at_frame_range(start_frame, end_frame, &animation_data, fps)
}
#[cfg_attr(feature = "tauri", tauri::command)]
pub fn get_values_at_frame_range_from_animated_float_vec3(
animated_value: AnimatedFloatVec3,
start_frame: i32,
end_frame: i32,
animation_data: AnimationData,
fps: i16,
) -> Vec<FloatVec3> {
animated_value.get_values_at_frame_range(start_frame, end_frame, &animation_data, fps)
}
impl AnimatedFloat {
pub fn new(val: f32) -> AnimatedFloat {
AnimatedFloat {
keyframes: Keyframes {
values: vec![Keyframe {
id: Uuid::new_v4().to_string().into(),
value: val,
offset: 0.0,
interpolation: None,
}],
},
}
}
}
impl AnimatedFloatVec2 {
pub fn new(x: f32, y: f32) -> AnimatedFloatVec2 {
AnimatedFloatVec2 {
keyframes: (AnimatedFloat::new(x), AnimatedFloat::new(y)),
}
}
}
impl AnimatedFloatVec3 {
pub fn new(x: f32, y: f32, z: f32) -> AnimatedFloatVec3 {
AnimatedFloatVec3 {
keyframes: (
AnimatedFloat::new(x),
AnimatedFloat::new(y),
AnimatedFloat::new(z),
),
}
}
}
impl AnimatedValue<f32> for AnimatedFloat {
fn sort_keyframes(&mut self) {
self.keyframes.sort();
}
fn get_value_at_frame(&self, curr_frame: i32, animation_data: &AnimationData, fps: i16) -> f32 {
self.keyframes
.get_value_at_frame(curr_frame, &animation_data, fps)
}
#[cfg(feature = "parallelization")]
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<f32> {
let values = (start_frame..end_frame)
.into_par_iter()
.map(|i| self.get_value_at_frame(i, animation_data, fps))
.collect();
values
}
#[cfg(not(feature = "parallelization"))]
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<f32> {
let values = (start_frame..end_frame)
.into_iter()
.map(|i| self.get_value_at_frame(i, animation_data, fps))
.collect();
values
}
}
impl AnimatedValue<(f32, f32, f32)> for AnimatedFloatVec3 {
fn sort_keyframes(&mut self) {
self.keyframes.0.sort_keyframes();
self.keyframes.1.sort_keyframes();
self.keyframes.2.sort_keyframes();
}
fn get_value_at_frame(
&self,
curr_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> (f32, f32, f32) {
let x = self
.keyframes
.0
.get_value_at_frame(curr_frame, animation_data, fps);
let y = self
.keyframes
.1
.get_value_at_frame(curr_frame, animation_data, fps);
let z = self
.keyframes
.2
.get_value_at_frame(curr_frame, animation_data, fps);
return (x, y, z);
}
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<(f32, f32, f32)> {
let x =
self.keyframes
.0
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let y =
self.keyframes
.1
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let z =
self.keyframes
.2
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let vectors: Vec<(f32, f32, f32)> = x
.into_iter()
.enumerate()
.map(|(index, val_x)| {
let val_y: f32 = *y.get(index).unwrap();
let val_z: f32 = *z.get(index).unwrap();
(val_x, val_y, val_z)
})
.collect();
vectors
}
}
impl AnimatedValue<(f32, f32)> for AnimatedFloatVec2 {
fn sort_keyframes(&mut self) {
self.keyframes.0.sort_keyframes();
self.keyframes.1.sort_keyframes();
}
fn get_value_at_frame(
&self,
curr_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> (f32, f32) {
let x = self
.keyframes
.0
.get_value_at_frame(curr_frame, animation_data, fps);
let y = self
.keyframes
.1
.get_value_at_frame(curr_frame, animation_data, fps);
return (x, y);
}
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<(f32, f32)> {
let x =
self.keyframes
.0
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let y =
self.keyframes
.1
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let vectors: Vec<(f32, f32)> = x
.into_iter()
.enumerate()
.map(|(index, val_x)| {
let val_y: f32 = *y.get(index).unwrap();
(val_x, val_y)
})
.collect();
vectors
}
}

View File

@@ -0,0 +1,2 @@
pub mod animated_values;
pub mod values;

View File

@@ -0,0 +1,4 @@
pub type Float = f32;
pub type FloatVec2 = (f32, f32);
pub type FloatVec3 = (f32, f32, f32);
pub type FloatVec4 = (f32, f32, f32, f32);

View File

@@ -1,12 +1,3 @@
use std::str::FromStr;
use crate::animation::primitives::{
interpolations::{EasingFunction, InterpolationType, SpringProperties},
keyframe::{Keyframe, Keyframes},
};
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use super::primitives::{
entities::{
common::{AnimatedEntity, AnimationData, Cache, Entity},
@@ -14,8 +5,17 @@ use super::primitives::{
text::AnimatedTextEntity,
},
paint::{Color, FillStyle, Paint, PaintStyle, StrokeStyle, TextAlign, TextPaint},
values::{AnimatedFloat, AnimatedFloatVec2},
values::animated_values::{AnimatedFloat, AnimatedFloatVec2},
};
use crate::animation::primitives::{
interpolations::{EasingFunction, InterpolationType, SpringProperties},
keyframe::{Keyframe, Keyframes},
};
#[cfg(feature = "parallelization")]
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use wasm_bindgen::prelude::*;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Input {
@@ -38,6 +38,7 @@ pub struct RenderState {
}
impl Timeline {
#[cfg(feature = "parallelization")]
fn calculate(&self) -> Vec<Entity> {
let mut entities = self.entities.clone();
@@ -50,6 +51,20 @@ impl Timeline {
return entities;
}
#[cfg(not(feature = "parallelization"))]
fn calculate(&self) -> Vec<Entity> {
let mut entities = self.entities.clone();
let entities = entities
.iter_mut()
.map(|entity| entity.calculate(self))
.filter(|entity| entity.is_some())
.map(|entity| entity.unwrap())
.collect();
return entities;
}
}
fn build_bg(offset: f32, paint: Paint, size: (i32, i32)) -> AnimatedRectEntity {
@@ -126,11 +141,24 @@ fn build_bg(offset: f32, paint: Paint, size: (i32, i32)) -> AnimatedRectEntity {
return bg_box;
}
#[tauri::command]
pub fn calculate_timeline_entities_at_frame(timeline: Timeline) -> Vec<Entity> {
#[cfg_attr(feature = "tauri", tauri::command)]
pub fn calculate_timeline_at_curr_frame(timeline: Timeline) -> Vec<Entity> {
timeline.calculate()
}
#[wasm_bindgen]
pub fn calculate_timeline_from_json_at_curr_frame(timeline_json: &str) -> String {
// TODO: Handle failure instead of unwrap
let timeline: Timeline = serde_json::from_str(timeline_json).unwrap();
let entities = calculate_timeline_at_curr_frame(timeline);
// TODO: Handle failure instead of unwrap
let entities_json = serde_json::to_string(&entities).unwrap();
entities_json
}
pub fn test_timeline_entities_at_frame(
render_state: RenderState,
size: (i32, i32),

View File

@@ -1,6 +1,6 @@
use font_kit::source::SystemSource;
#[tauri::command]
#[cfg_attr(feature = "tauri", tauri::command)]
pub fn get_system_fonts() -> Option<Vec<String>> {
let source = SystemSource::new();
@@ -24,7 +24,7 @@ pub fn get_system_fonts() -> Option<Vec<String>> {
}
}
#[tauri::command]
#[cfg_attr(feature = "tauri", tauri::command)]
pub fn get_system_families() -> Option<Vec<String>> {
let source = SystemSource::new();
@@ -33,7 +33,7 @@ pub fn get_system_families() -> Option<Vec<String>> {
found_families.ok()
}
#[tauri::command]
#[cfg_attr(feature = "tauri", tauri::command)]
pub fn get_system_font(font_name: String) -> Option<Vec<u8>> {
let source = SystemSource::new();

View File

@@ -0,0 +1 @@
pub mod fonts;

View File

@@ -0,0 +1,3 @@
pub mod animation;
#[cfg(feature = "fonts")]
pub mod fonts;

1
web/.vercel/project.json Normal file
View File

@@ -0,0 +1 @@
{"orgId":"c0DV5ATsGbVZoMVVr9msnlC7","projectId":"prj_6wyilH72l9zcNlIfA9NUAJ0xON0v"}

9
web/deploy.sh Normal file
View File

@@ -0,0 +1,9 @@
[ -z $TOKEN ] && printf "Token is missing" && exit 1
if [ -z $IS_PROD ]; then
printf "\nTEST DEPLOYMENT\n"
else
printf "\nPRODUCTION DEPLOYMENT\n" && PROD="--prod"
fi
URL=$(vercel --yes --global-config ./.vercel --token $TOKEN $PROD) && printf "\nDEPLOYMENT SUCCESSFUL\n$URL"

View File

@@ -11,11 +11,14 @@
},
"dependencies": {
"@astrojs/tailwind": "^3.1.3",
"@types/marked": "^5.0.0",
"@unom/style": "^0.2.14",
"astro": "^2.5.0",
"astro-icon": "^0.8.1",
"autoprefixer": "^10.4.14",
"class-variance-authority": "^0.6.0",
"clsx": "^1.2.1",
"marked": "^5.1.0",
"motion": "^10.16.2",
"postcss": "^8.4.24",
"postcss-custom-media": "^9.1.5",

View File

@@ -3,7 +3,7 @@ import type { HTMLAttributes } from "astro/types";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const button = cva(
export const button = cva(
cn(
"inline-flex items-center justify-center rounded-md text-sm font-medium",
"transition-colors focus-visible:outline-none",
@@ -15,6 +15,8 @@ const button = cva(
variants: {
variant: {
default: "bg-main text-neutral hocus:bg-main/80",
primary:
"bg-primary dark:bg-primary/50 text-neutral dark:text-main hocus:bg-primary/80 dark:hocus:bg-primary/80",
destructive:
"bg-error text-destructive-foreground hocus:bg-destructive/90",
outline:

View File

@@ -3,7 +3,7 @@ import type { HTMLAttributes } from "astro/types";
import { VariantProps, cva } from "class-variance-authority";
const card = cva(
"rounded-card transition-colors bg-neutral-accent ring-2 ring-main/10",
"card rounded-card transition-colors bg-neutral-accent ring-2 ring-main/10",
{
variants: {
interactable: {
@@ -12,7 +12,7 @@ const card = cva(
hocus:shadow-lg hocus:ring-2 hocus:outline-none",
},
padding: {
true: "p-card",
true: "py-6 px-8",
false: "p-0",
},
},
@@ -23,9 +23,14 @@ export interface Props
extends HTMLAttributes<"div">,
VariantProps<typeof card> {}
const { interactable = false, padding = true, ...props } = Astro.props;
const {
interactable = false,
padding = true,
class: _class,
...props
} = Astro.props;
---
<div {...props} class={card({ interactable, padding })}>
<div {...props} class={card({ interactable, padding, class: _class })}>
<slot />
</div>

View File

@@ -1,18 +1,26 @@
---
import Card from "../Card.astro";
import { Icon } from "astro-icon";
export interface Props {
title: string;
iconName: string;
description: string;
}
const { title, description } = Astro.props;
const { title, description, iconName } = Astro.props;
---
<Card>
<h4>
<Card class="w-[300px] shrink-0 grow">
<div
class="text-primary w-12 mb-4 shadow-current drop-shadow-[0px_0px_10px_hsl(var(--color-primary)_/_0.5)]"
>
<Icon name={iconName} />
</div>
<h4 class="text-lg font-bold">
{title}
</h4>
<p>
<p class="text-secondary">
{description}
</p>
</Card>

View File

@@ -0,0 +1,52 @@
---
import { cn } from "@/lib/utils";
import type { HTMLAttributes } from "astro/types";
import { VariantProps, cva } from "class-variance-authority";
const heading = cva("max-w-3xl m-[var(--section-heading-margin)]", {
variants: {
main: {
true: "font-bold",
false: "font-semibold",
},
padding: {
true: "py-4",
false: "p-0",
},
},
});
export interface Props
extends HTMLAttributes<"h1" | "h2">,
VariantProps<typeof heading> {
subtitle?: string;
}
const { main = false, padding = true, subtitle } = Astro.props;
const titleClass = cn(
heading({ main, padding }),
subtitle ? "mb-[calc(var(--section_heading-margin-bottom)_/_2)]" : ""
);
---
<div class="z-0 relative">
{
main ? (
<h1 class={titleClass}>
<slot />
</h1>
) : (
<h2 class={titleClass}>
<slot />
</h2>
)
}
{
subtitle && (
<h3 class="font-normal m-[var(--section-heading-margin)] max-w-3xl">
{subtitle}
</h3>
)
}
</div>

View File

@@ -1,13 +1,25 @@
---
import Section from "../Section.astro";
type NavigationItem = {
path: string;
label: string;
};
enum NavigationItemType {
Link,
Text,
}
type NavigationItem =
| {
path: string;
label: string;
type: NavigationItemType.Link;
}
| {
type: NavigationItemType.Text;
content: string;
};
type NavigationGroup = {
title: string;
class?: string;
items: Array<NavigationItem>;
};
@@ -17,25 +29,38 @@ const tree: Array<NavigationGroup> = [
items: [
{
path: "/",
type: NavigationItemType.Link,
label: "Landing",
},
{
path: "/blog",
label: "Blog",
path: "https://github.com/tempblade/creator",
type: NavigationItemType.Link,
label: "GitHub",
},
{
path: "/contact",
label: "Contact",
path: "https://tempblade.com",
type: NavigationItemType.Link,
label: "tempblade",
},
],
},
{
title: "Legal",
items: [
{ path: "/legal/imprint", label: "Imprint" },
{
path: "/legal/privacy-policy",
label: "Privacy Policy",
path: "/legal/imprint",
label: "Imprint",
type: NavigationItemType.Link,
},
],
},
{
title: "",
class: "ml-auto mr-0 self-end",
items: [
{
type: NavigationItemType.Text,
content: "Made with ❤️ in Rottweil",
},
],
},
@@ -44,15 +69,20 @@ const tree: Array<NavigationGroup> = [
<footer class="bg-neutral-accent">
<Section>
<div class="flex flex-row flex-wrap gap-12">
<div class="flex flex-row flex-wrap gap-12 w-full pb-8">
{
tree.map((group) => (
<div>
<h3 class="mb-2">{group.title}</h3>
<div class={group.class}>
{group.title && <h3 class="mb-2">{group.title}</h3>}
<div class="flex flex-col">
{group.items.map((item) => (
<a href={item.path}>{item.label}</a>
))}
{group.items.map((item) => {
switch (item.type) {
case NavigationItemType.Link:
return <a href={item.path}>{item.label}</a>;
case NavigationItemType.Text:
return <p>{item.content}</p>;
}
})}
</div>
</div>
))

View File

@@ -0,0 +1,18 @@
---
import Button, { button } from "../Button.astro";
import TempbladeLogo from "components/Logo/tempblade.astro";
---
<header class="fixed top-0 w-full h-16 z-50">
<div
class="flex flex-row justify-between h-full w-full max-w-section m-auto p-main"
>
<div class="w-16 h-8 flex">
<TempbladeLogo />
</div>
<a
class={button({ variant: "primary", size: "default" })}
href="https://github.com/tempblade/creator/releases">Download</a
>
</div>
</header>

View File

@@ -0,0 +1,43 @@
<svg
width="100%"
height="100%"
viewBox="0 0 372 306"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-miterlimit:1.5;"
>
<g>
<g id="Tb">
<path
id="T"
d="M250.532,6.303L250.532,56.321L157.88,56.321L157.88,233.339L100.536,233.339L100.536,56.321L6.186,56.321L6.186,6.303L250.532,6.303Z"
style="fill:url(#_Linear2);fill-rule:nonzero;"></path>
<path
id="b"
class="stroke-main"
d="M133.511,6.303L133.511,41.339L172.011,41.339L172.171,248.131L204.414,248.131L204.414,280.374L317.268,280.374L317.268,248.131L349.511,248.131L349.511,151.4L317.268,151.4L317.268,119.156L235.046,119.156L235.046,151.4"
style="fill:none;stroke-width:30.45px;"></path>
</g>
</g>
<defs>
<linearGradient
id="_Linear2"
x1="0"
y1="0"
x2="1"
y2="0"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(244.346,0,0,227.036,6.18639,119.821)"
><stop
offset="0"
class="text-main"
style="stop-color:currentColor;stop-opacity:1"></stop>
<stop
offset="1"
class="text-main/50"
style="stop-color:currentColor;stop-opacity:1"></stop>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<polygon points="455.76 263.72 455.76 291.15 455.76 318.59 455.76 346.02 455.76 373.45 483.19 373.45 483.19 346.02 483.19 318.59 483.19 291.15 483.19 263.72 455.76 263.72"/>
<rect x="428.32" y="373.45" width="27.43" height="27.43"/>
<rect x="428.32" y="236.28" width="27.43" height="27.43"/>
<polygon points="373.45 400.89 346.02 400.89 346.02 428.32 373.45 428.32 400.89 428.32 428.32 428.32 428.32 400.89 400.89 400.89 373.45 400.89"/>
<polygon points="400.89 236.28 428.32 236.28 428.32 208.85 400.89 208.85 373.45 208.85 346.02 208.85 346.02 236.28 373.45 236.28 400.89 236.28"/>
<rect x="318.59" y="373.45" width="27.43" height="27.43"/>
<rect x="318.59" y="236.28" width="27.43" height="27.43"/>
<polygon points="318.59 318.59 318.59 291.15 318.59 263.72 291.15 263.72 291.15 291.15 291.15 318.59 291.15 346.02 291.15 373.45 318.59 373.45 318.59 346.02 318.59 318.59"/>
<polygon points="291.15 126.55 318.59 126.55 318.59 153.98 346.02 153.98 346.02 181.41 373.45 181.41 373.45 153.98 373.45 126.55 346.02 126.55 346.02 99.11 318.59 99.11 318.59 71.68 291.15 71.68 263.72 71.68 263.72 44.24 236.28 44.24 208.85 44.24 181.41 44.24 181.41 71.68 181.41 99.11 208.85 99.11 208.85 71.68 236.28 71.68 236.28 99.11 263.72 99.11 263.72 126.55 236.28 126.55 236.28 153.98 208.85 153.98 208.85 181.41 208.85 208.85 181.41 208.85 153.98 208.85 153.98 236.28 181.41 236.28 208.85 236.28 208.85 263.72 236.28 263.72 263.72 263.72 263.72 236.28 236.28 236.28 236.28 208.85 236.28 181.41 263.72 181.41 263.72 153.98 291.15 153.98 291.15 126.55"/>
<polygon points="236.28 346.02 208.85 346.02 208.85 373.45 208.85 400.89 181.41 400.89 153.98 400.89 126.55 400.89 126.55 428.32 153.98 428.32 181.41 428.32 208.85 428.32 236.28 428.32 236.28 400.89 263.72 400.89 263.72 373.45 236.28 373.45 236.28 346.02"/>
<rect x="181.41" y="318.59" width="27.43" height="27.43"/>
<rect x="153.98" y="291.15" width="27.43" height="27.43"/>
<rect x="126.55" y="263.72" width="27.43" height="27.43"/>
<rect x="99.11" y="236.28" width="27.43" height="27.43"/>
<polygon points="71.68 428.32 44.24 428.32 44.24 400.89 16.81 400.89 16.81 428.32 16.81 455.76 44.24 455.76 71.68 455.76 99.11 455.76 126.55 455.76 126.55 428.32 99.11 428.32 71.68 428.32"/>
<polygon points="99.11 291.15 99.11 263.72 71.68 263.72 71.68 291.15 71.68 318.59 99.11 318.59 99.11 291.15"/>
<polygon points="71.68 373.45 71.68 346.02 71.68 318.59 44.24 318.59 44.24 346.02 44.24 373.45 44.24 400.89 71.68 400.89 71.68 373.45"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

6
web/src/icons/Fast.svg Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<polygon points="66.99 184.64 93.14 184.64 119.28 184.64 145.42 184.64 171.57 184.64 197.71 184.64 223.86 184.64 250 184.64 276.14 184.64 302.29 184.64 302.29 158.5 302.29 132.35 302.29 106.21 328.43 106.21 328.43 80.07 302.29 80.07 302.29 53.92 276.14 53.92 276.14 27.78 250 27.78 223.86 27.78 223.86 53.92 223.86 80.07 223.86 106.21 197.71 106.21 171.57 106.21 145.42 106.21 119.28 106.21 93.14 106.21 66.99 106.21 40.85 106.21 40.85 132.35 14.71 132.35 14.71 158.5 14.71 184.64 40.85 184.64 66.99 184.64"/>
<polygon points="459.15 236.93 459.15 210.78 433.01 210.78 433.01 184.64 406.86 184.64 406.86 158.5 380.72 158.5 380.72 132.35 354.58 132.35 328.43 132.35 328.43 158.5 328.43 184.64 328.43 210.78 302.29 210.78 276.14 210.78 250 210.78 223.86 210.78 197.71 210.78 171.57 210.78 145.42 210.78 119.28 210.78 93.14 210.78 93.14 236.93 66.99 236.93 66.99 263.07 93.14 263.07 93.14 289.22 119.28 289.22 145.42 289.22 171.57 289.22 197.71 289.22 223.86 289.22 250 289.22 276.14 289.22 302.29 289.22 328.43 289.22 328.43 315.36 328.43 341.5 328.43 367.65 354.58 367.65 380.72 367.65 380.72 341.5 406.86 341.5 406.86 315.36 433.01 315.36 433.01 289.22 459.15 289.22 459.15 263.07 485.29 263.07 485.29 236.93 459.15 236.93"/>
<polygon points="302.29 367.65 302.29 341.5 302.29 315.36 276.14 315.36 250 315.36 223.86 315.36 197.71 315.36 171.57 315.36 145.42 315.36 119.28 315.36 93.14 315.36 66.99 315.36 40.85 315.36 14.71 315.36 14.71 341.5 14.71 367.65 40.85 367.65 40.85 393.79 66.99 393.79 93.14 393.79 119.28 393.79 145.42 393.79 171.57 393.79 197.71 393.79 223.86 393.79 223.86 419.93 223.86 446.08 223.86 472.22 250 472.22 276.14 472.22 276.14 446.08 302.29 446.08 302.29 419.93 328.43 419.93 328.43 393.79 302.29 393.79 302.29 367.65"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

32
web/src/icons/Open.svg Normal file
View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<g>
<rect x="261.76" y="155.3" width="23.53" height="23.53"/>
<rect x="214.71" y="155.3" width="23.53" height="23.53"/>
<polygon points="379.41 178.83 379.41 155.3 355.88 155.3 355.88 131.78 332.35 131.78 308.82 131.78 285.29 131.78 285.29 155.3 308.82 155.3 332.35 155.3 332.35 178.83 355.88 178.83 355.88 202.36 379.41 202.36 379.41 225.89 355.88 225.89 355.88 249.42 332.35 249.42 332.35 272.94 308.82 272.94 308.82 296.47 285.29 296.47 285.29 320 261.76 320 261.76 343.53 238.24 343.53 238.24 320 214.71 320 214.71 296.47 191.18 296.47 191.18 272.94 167.65 272.94 167.65 249.42 144.12 249.42 144.12 225.89 120.6 225.89 120.6 202.36 144.12 202.36 144.12 178.83 167.65 178.83 167.65 155.3 191.18 155.3 214.71 155.3 214.71 131.78 191.18 131.78 167.65 131.78 144.12 131.78 144.12 155.3 120.6 155.3 120.6 178.83 97.07 178.83 97.07 202.36 97.07 225.89 97.07 249.42 120.6 249.42 120.6 272.94 144.12 272.94 144.12 296.47 167.65 296.47 167.65 320 191.18 320 191.18 343.53 214.71 343.53 214.71 367.06 238.24 367.06 238.24 390.58 261.76 390.58 261.76 367.06 285.29 367.06 285.29 343.53 308.82 343.53 308.82 320 332.35 320 332.35 296.47 355.88 296.47 355.88 272.94 379.41 272.94 379.41 249.42 402.93 249.42 402.93 225.89 402.93 202.36 402.93 178.83 379.41 178.83"/>
<rect x="238.24" y="178.83" width="23.53" height="23.53"/>
</g>
<g>
<polygon points="461.26 108.83 437.73 108.83 437.73 132.36 437.73 155.89 461.26 155.89 461.26 132.36 461.26 108.83"/>
<rect x="414.2" y="85.3" width="23.53" height="23.53"/>
<rect x="390.68" y="61.78" width="23.53" height="23.53"/>
<polygon points="367.15 38.25 343.62 38.25 343.62 61.78 367.15 61.78 390.68 61.78 390.68 38.25 367.15 38.25"/>
<polygon points="320.09 14.72 296.56 14.72 273.04 14.72 250.49 14.72 249.51 14.72 226.96 14.72 203.44 14.72 179.91 14.72 156.38 14.72 156.38 38.25 179.91 38.25 203.44 38.25 226.96 38.25 250.49 38.25 250.49 38.25 273.04 38.25 296.56 38.25 320.09 38.25 343.62 38.25 343.62 14.72 320.09 14.72"/>
<polygon points="296.56 461.75 273.04 461.75 250.49 461.75 249.51 461.75 226.96 461.75 203.44 461.75 179.91 461.75 156.38 461.75 156.38 485.28 179.91 485.28 203.44 485.28 226.96 485.28 250.49 485.28 250.49 485.28 273.04 485.28 296.56 485.28 320.09 485.28 343.62 485.28 343.62 461.75 320.09 461.75 296.56 461.75"/>
<polygon points="343.62 438.22 343.62 461.75 367.15 461.75 390.68 461.75 390.68 438.22 367.15 438.22 343.62 438.22"/>
<rect x="390.68" y="414.7" width="23.53" height="23.53"/>
<rect x="414.2" y="391.17" width="23.53" height="23.53"/>
<polygon points="437.73 367.64 437.73 391.17 461.26 391.17 461.26 367.64 461.26 344.11 437.73 344.11 437.73 367.64"/>
<polygon points="484.79 250 484.79 226.47 484.79 202.94 484.79 179.42 484.79 155.89 461.26 155.89 461.26 179.42 461.26 202.94 461.26 226.47 461.26 250 461.26 250 461.26 273.53 461.26 297.06 461.26 320.58 461.26 344.11 484.79 344.11 484.79 320.58 484.79 297.06 484.79 273.53 484.79 250 484.79 250"/>
<polygon points="38.74 297.06 38.74 273.53 38.74 250 15.21 250 15.21 273.53 15.21 297.06 15.21 320.58 15.21 344.11 38.74 344.11 38.74 320.58 38.74 297.06"/>
<polygon points="62.27 344.11 38.74 344.11 38.74 367.64 38.74 391.17 62.27 391.17 62.27 367.64 62.27 344.11"/>
<rect x="62.27" y="391.17" width="23.53" height="23.53"/>
<rect x="85.8" y="414.7" width="23.53" height="23.53"/>
<polygon points="132.85 438.22 109.32 438.22 109.32 461.75 132.85 461.75 156.38 461.75 156.38 438.22 132.85 438.22"/>
<polygon points="109.32 38.25 109.32 61.78 132.85 61.78 156.38 61.78 156.38 38.25 132.85 38.25 109.32 38.25"/>
<rect x="85.8" y="61.78" width="23.53" height="23.53"/>
<rect x="62.27" y="85.3" width="23.53" height="23.53"/>
<polygon points="38.74 132.36 38.74 155.89 62.27 155.89 62.27 132.36 62.27 108.83 38.74 108.83 38.74 132.36"/>
<polygon points="15.21 179.42 15.21 202.94 15.21 226.47 15.21 250 38.74 250 38.74 226.47 38.74 202.94 38.74 179.42 38.74 155.89 15.21 155.89 15.21 179.42"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1,5 +1,6 @@
---
import Footer from "@/components/Layout/Footer.astro";
import Header from "@/components/Layout/Header.astro";
import "@/styles/global.css";
export interface Props {
@@ -16,10 +17,15 @@ const { title } = Astro.props;
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<script
defer
data-domain="creator.tempblade.com"
src="https://analytics.unom.io/js/plausible.js"></script>
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<Header />
<slot />
<Footer />
</body>

View File

@@ -1,7 +1,6 @@
---
import RootLayout from "@/layouts/RootLayout.astro";
import Section from "@/components/Section.astro";
import Button from "@/components/Button.astro";
import Landing from "@/sections/Landing.astro";
import Introduction from "@/sections/Introduction.astro";
import Features from "@/sections/Features.astro";
@@ -9,13 +8,13 @@ import Features from "@/sections/Features.astro";
<RootLayout title="tempblade - Creator">
<main>
<Section>
<Section padding={false}>
<Landing />
</Section>
<Section>
<Introduction />
</Section>
<Section>
<Section padding={false}>
<Features />
</Section>
</main>

View File

@@ -0,0 +1,27 @@
---
import Heading from "@/components/Heading.astro";
import Section from "@/components/Section.astro";
import RootLayout from "@/layouts/RootLayout.astro";
import { marked } from "marked";
const response = await fetch("https://api.enrico.buehler.earth/api/imprint", {
headers: {
"Content-Type": "application/json; charset='utf-8'",
},
});
const json = await response.json();
const markdownContent = json.data.attributes.content;
console.log(markdownContent);
const content = marked.parse(markdownContent);
---
<RootLayout title="Imprint">
<Section>
<Heading main>Imprint</Heading>
</Section>
<Section>
<article set:html={content} />
</Section>
</RootLayout>

View File

@@ -1,26 +1,72 @@
---
import CardFeature from "@/components/Cards/CardFeature.astro";
import Heading from "@/components/Heading.astro";
type Feature = {
title: string;
iconName: string;
description: string;
};
const features: Array<Feature> = [
{
title: "Fast",
iconName: "Fast",
description:
"Thanks to rust with multithreading and skia we're really fast!",
},
{
title: "Extensible",
iconName: "Extensible",
description:
"Modular structured and thanks to our dual language approach you even decide in which language you want to extend!",
},
{
title: "Community driven & Free",
iconName: "Open",
description:
"The project is MIT licensed and we're open to new ideas for further development. Also since this product is not profit driven we won't screw you over!",
},
];
---
<div class="flex flex-row">
{
features.map((feature) => (
<CardFeature
title={feature.title}
description={feature.description}
/>
))
}
<div>
<div class="p-main py-0">
<Heading>Core Features & Values</Heading>
</div>
<div
id="features-cards-container"
class="flex flex-row flex-nowrap overflow-x-auto snap-x snap-mandatory gap-card overflow-y-clip p-main snap-center"
>
{
features.map((feature) => (
<CardFeature
iconName={feature.iconName}
title={feature.title}
description={feature.description}
/>
))
}
</div>
</div>
<script>
import { animate, inView, stagger } from "motion";
import { ease } from "@unom/style";
const cardsContainer = document.getElementById("features-cards-container");
const cards = document.querySelectorAll("#features-cards-container .card");
if (cardsContainer) {
inView(cardsContainer, () => {
animate(
cards,
{
scale: [0.8, 1],
opacity: [0, 1],
},
{ ...ease.quint(0.8).out, delay: stagger(0.1) }
);
});
}
</script>

View File

@@ -1,5 +1,11 @@
<div class="flex flex-col gap-4">
<h2>The next generation motion design tool</h2>
---
import Heading from "@/components/Heading.astro";
---
<div id="introduction-content-container" class="flex flex-col gap-4">
<Heading>
The Next Generation Motion Design Tool - Free & Open Source
</Heading>
<p>
We believe tools for expressing yourself should be accessible to
everybody. Not constrained to proprietary operating systems or monthly
@@ -9,15 +15,39 @@
tempblade Creator aims to become a viable alternative to current motion
design tools, and even exceed them in certain aspects like
extensibility. This is only possible due to our open source approach.
Currently we are in a early alpha stage, and the program has to be seen
as a proof of concept rather then a finished product.
Currently we are in an early alpha stage, and the program as it is right
now has to be seen as a proof of concept rather then a finished product.
</p>
<p>
You're a developer, like our idea and want to help? Join our discord or
check out the repository!
<a href="https://discord.gg/map44Dt6sK">Our Discord</a>
</p>
<p>
You're not a developer but still want to support the work? I've got a
patreon!
</p>
</div>
<script>
import { ease } from "@unom/style";
import { animate, inView, stagger } from "motion";
const contentContainer = document.getElementById(
"introduction-content-container"
);
const children = document.querySelectorAll(
"#introduction-content-container *"
);
if (contentContainer) {
inView(contentContainer, () => {
animate(
children,
{ y: [20, 0], opacity: [0, 1] },
{ ...ease.quint(0.8).out, delay: stagger(0.1) }
);
});
}
</script>

View File

@@ -1,38 +1,54 @@
---
import Button from "@/components/Button.astro";
import TempbladeLogo from "@/components/Logo/tempblade.astro";
---
<div class="h-[80vh] relative">
<div
<div class="h-[80vh] relative w-full overflow-x-hidden">
<aside
style="filter:blur(70px);"
class="z-0 absolute top-0 flex items-center w-full h-full justify-center object-center object-contain"
id="landing-bg-container"
>
<canvas
width="1920"
height="1080"
style="filter:blur(100px)"
class="w-[800px]"
id="landing-bg"></canvas>
</div>
<canvas width="1920" height="1080" class="w-[900px]" id="landing-bg"
></canvas>
</aside>
<div
class="z-10 relative w-full h-full flex items-center flex-col justify-center"
>
<div class="flex flex-col justify-center items-center gap-2">
<h1 class="text-5xl text-center font-black">tempblade Creator</h1>
<h2 class="text-center text-xl font-normal">
Rust Based Open Source Motion Design Editor & Toolkit
<div
id="landing-content-container"
class="flex flex-col justify-center items-center gap-2 p-main dark:text-neutral"
>
<!-- <div data-animate class="w-12 h-12">
<TempbladeLogo />
</div> -->
<h1
data-animate
class="text-6xl lg:text-8xl text-center font-black text-current"
>
Creator
</h1>
<h2 class="text-center text-xl font-normal max-w-xs">
<span class="inline-block" data-animate>
Rust Based Open Source</span
><br />
<span class="inline-block" data-animate>
Motion Design Editor & Toolkit</span
>
</h2>
<Button>Explore now!</Button>
</div>
</div>
</div>
<script>
import { animate, inView } from "motion";
import { animate, inView, stagger } from "motion";
import { ease } from "@unom/style";
const landingBgContainer = document.getElementById("landing-bg");
const children = document.querySelectorAll(
"#landing-content-container [data-animate]"
);
if (landingBgContainer) {
inView(landingBgContainer, () => {
animate(
@@ -43,6 +59,17 @@ import Button from "@/components/Button.astro";
},
{ ...ease.quint(2).out }
);
animate(
children,
{ y: [50, 0], opacity: [0, 1] },
{
opacity: {
easing: "linear",
},
...ease.quint(0.8).out,
delay: stagger(0.1),
}
);
});
}
</script>

View File

@@ -0,0 +1,95 @@
interface Point {
x: number;
y: number;
color: string;
}
interface VoronoiCell {
site: Point;
vertices: Point[];
}
function generateVoronoiPattern(
canvas: HTMLCanvasElement,
points: Array<Point>
) {
const ctx = canvas.getContext("2d");
if (ctx) {
// Draw Voronoi regions
for (let x = 0; x < canvas.width; x++) {
for (let y = 0; y < canvas.height; y++) {
let closestPointIndex = 0;
let closestDistance = distance(x, y, points[0].x, points[0].y);
for (let i = 1; i < points.length; i++) {
const dist = distance(x, y, points[i].x, points[i].y);
if (dist < closestDistance) {
closestDistance = dist;
closestPointIndex = i;
}
}
const { x: px, y: py, color } = points[closestPointIndex];
ctx.fillStyle = color;
ctx.fillRect(x, y, 1, 1);
}
}
}
}
function distance(x1: number, y1: number, x2: number, y2: number) {
const dx = x2 - x1;
const dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
// Get canvas element and generate Voronoi pattern
const canvas = document.getElementById("landing-bg") as HTMLCanvasElement;
const initialPoints: Array<Point> = [{
x: 200,
y: 200,
color: "#8AFFAD",
},
{
x: 800,
y: 500,
color: "#326CCC",
},
{
x: 1100,
y: 300,
color: "#95B2F5",
},
{
x: 1200,
y: 600,
color: "#32C3E3",
},
{
x: 300,
y: 900,
color: "purple",
},]
const draw = (time: number) => {
const radius = 200;
const angle = time % 360;
const radian = angle * (Math.PI / 180);
const x = Math.cos(radian) * radius;
const y = Math.sin(radian) * radius;
const points = initialPoints.map((p) => ({ ...p, x: p.x + x, y: p.y + y }));
generateVoronoiPattern(canvas, points);
//requestAnimationFrame(draw);
}
requestAnimationFrame(draw);

View File

@@ -1,75 +1,126 @@
interface Point {
x: number;
y: number;
color: string;
x: number;
y: number;
color: string;
radius: number;
}
interface VoronoiCell {
site: Point;
vertices: Point[];
}
function generateVoronoiPattern(
canvas: HTMLCanvasElement,
points: Array<Point>
) {
const ctx = canvas.getContext("2d");
if (ctx) {
// Draw Voronoi regions
for (let x = 0; x < canvas.width; x++) {
for (let y = 0; y < canvas.height; y++) {
let closestPointIndex = 0;
let closestDistance = distance(x, y, points[0].x, points[0].y);
for (let i = 1; i < points.length; i++) {
const dist = distance(x, y, points[i].x, points[i].y);
if (dist < closestDistance) {
closestDistance = dist;
closestPointIndex = i;
}
}
const { x: px, y: py, color } = points[closestPointIndex];
ctx.fillStyle = color;
ctx.fillRect(x, y, 1, 1);
}
}
}
}
function distance(x1: number, y1: number, x2: number, y2: number) {
const dx = x2 - x1;
const dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
// Get canvas element and generate Voronoi pattern
const canvas = document.getElementById("landing-bg") as HTMLCanvasElement;
generateVoronoiPattern(canvas, [
{
x: 200,
y: 200,
color: "#8AFFAD",
},
{
x: 800,
const initialPoints: Array<Point> = [{
x: 500,
y: 400,
color: "purple",
radius: Math.random() * 200
},
{
x: 900,
y: 500,
color: "#326CCC",
},
{
x: 1100,
y: 300,
radius: Math.random() * 200
},
{
x: 1600,
y: 400,
color: "#95B2F5",
},
{
radius: Math.random() * 200
},
{
x: 1200,
y: 600,
color: "#32C3E3",
},
{
x: 300,
y: 900,
radius: Math.random() * 200
},
{
x: 600,
y: 500,
color: "#8AFFAD",
radius: Math.random() * 200
},
{
x: 900,
y: 300,
color: "purple",
},
]);
radius: Math.random() * 200
},
]
export class GradientBackground {
context: CanvasRenderingContext2D;
constructor(context: CanvasRenderingContext2D) {
this.context = context;
this.draw = this.draw.bind(this);
}
draw(time: number) {
const { width, height } = this.context.canvas;
this.context.clearRect(0, 0, width, height * 2);
this.context.save();
this.context.translate(width * 0.5, height * 0.5);
const angle = (time * 0.01) % 360;
const radian = angle * (Math.PI / 180);
this.context.rotate(radian);
this.context.translate(width * -0.5, height * -0.5);
initialPoints.forEach((point, index) => {
const { color, radius } = point;
// Calculate the position/angle on a circle by the time
const angle = time * 0.05 + index * 10 % 360;
// Convert the angle to radian
const radian = angle * (Math.PI / 180);
// Calculate the offset based on the radius
const offsetX = Math.cos(radian) * radius;
const offsetY = Math.sin(radian) * radius;
// Calculate the position based on offset and initial position
const x = offsetX + point.x;
const y = offsetY + point.y;
// Create the gradient
const gradient = this.context.createRadialGradient(x, y, 0, x, y, 500);
gradient.addColorStop(0, color);
gradient.addColorStop(1, "rgba(0,0,0,0)");
this.context.fillStyle = gradient;
this.context.globalCompositeOperation = "lighten";
// Draw a rect with the gradient
this.context.fillRect(0, 0, width, height);
})
this.context.restore();
return requestAnimationFrame(this.draw);
}
}
const ctx = canvas.getContext("2d");
if (ctx) {
const bg = new GradientBackground(ctx);
requestAnimationFrame(bg.draw);
}

View File

@@ -5,7 +5,8 @@
:root {
--color-main: 0 0% 0%;
--color-primary: 0 0% 0%;
--color-main: 0 0% 10%;
--color-primary: 280 80% 50%;
--color-neutral: 0 0% 100%;
--color-neutral-accent: 0 0% 93%;
--color-highlight: 264 100% 50%;
@@ -17,15 +18,18 @@
--spacing-main: 20px;
--gap-card: 1rem;
--max-width-section: 100%;
}
@media (prefers-color-scheme: dark) {
:root {
--color-main: 0 0% 100%;
--color-primary: 0 0% 0%;
--color-neutral: 264 100% 6%;
--color-neutral-accent: 271 100% 10%;
--color-secondary: 0 0% 80%;
--color-primary: 280 90% 60%;
--color-neutral: 240 100% 4%;
--color-neutral-accent: 250 70% 6%;
--color-highlight: 336 100% 60%;
--color-success: 132 100% 78%;
--color-error: 335 100% 62%;
@@ -75,6 +79,26 @@ h4 {
@apply text-lg;
}
p {
@apply max-w-[600px];
[astro-icon] {
fill: currentColor;
}
article {
& h1, h2, h3, h4, h5 {
@apply mt-6;
}
& h1, h2, h3, h4, h5, p, ol, ul {
@apply mb-4;
}
}
p,
li {
@apply max-w-[600px] whitespace-pre-line text-base text-secondary;
line-height: 1.5;
}

View File

@@ -1,3 +1,5 @@
const plugin = require("tailwindcss/plugin");
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
@@ -55,5 +57,9 @@ module.exports = {
},
},
},
plugins: [],
plugins: [
plugin(function ({ addVariant }) {
addVariant("hocus", ["&:hover", "&:focus"]);
}),
],
};

View File

@@ -613,6 +613,11 @@
deepmerge "^4.2.2"
escalade "^3.1.1"
"@trysound/sax@0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
"@types/babel__core@^7.1.19":
version "7.20.1"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b"
@@ -665,6 +670,11 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.30.tgz#44cb52f32a809734ca562e685c6473b5754a7818"
integrity sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==
"@types/marked@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-5.0.0.tgz#3235b9133054e6586eedabfb77aa7d4a4bafbfcf"
integrity sha512-YcZe50jhltsCq7rc9MNZC/4QB/OnA2Pd6hrOSTOFajtabN+38slqgDDCeE/0F83SjkKBQcsZUj7VLWR0H5cKRA==
"@types/mdast@^3.0.0":
version "3.0.11"
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.11.tgz#dc130f7e7d9306124286f6d6cee40cf4d14a3dc0"
@@ -808,6 +818,15 @@ array-iterate@^2.0.0:
resolved "https://registry.yarnpkg.com/array-iterate/-/array-iterate-2.0.1.tgz#6efd43f8295b3fee06251d3d62ead4bd9805dd24"
integrity sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==
astro-icon@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/astro-icon/-/astro-icon-0.8.1.tgz#2259640cea3818326957dfba66ae17aa43f1d3cb"
integrity sha512-APk+fbFnoyGdIVSPFrdrOW9YBK96/1fYuVe7ULTGW92+z00RKB8GfLJiUvzNVXUAX2rZJCFmruGVF4rrhcTYsg==
dependencies:
node-fetch "^3.1.0"
resolve-pkg "^2.0.0"
svgo "^2.8.0"
astro@^2.5.0:
version "2.6.4"
resolved "https://registry.yarnpkg.com/astro/-/astro-2.6.4.tgz#37880a65cca438971643fd6473e7fe8ae2578f11"
@@ -917,6 +936,11 @@ bl@^5.0.0:
inherits "^2.0.4"
readable-stream "^3.4.0"
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
boxen@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-6.2.1.tgz#b098a2278b2cd2845deef2dff2efc38d329b434d"
@@ -1135,6 +1159,11 @@ commander@^4.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
commander@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
common-ancestor-path@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7"
@@ -1173,16 +1202,52 @@ css-color-converter@^2.0.0:
color-name "^1.1.4"
css-unit-converter "^1.1.2"
css-select@^4.1.3:
version "4.3.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b"
integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==
dependencies:
boolbase "^1.0.0"
css-what "^6.0.1"
domhandler "^4.3.1"
domutils "^2.8.0"
nth-check "^2.0.1"
css-tree@^1.1.2, css-tree@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
dependencies:
mdn-data "2.0.14"
source-map "^0.6.1"
css-unit-converter@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21"
integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==
css-what@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
csso@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529"
integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==
dependencies:
css-tree "^1.1.2"
data-uri-to-buffer@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e"
integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==
debug@^4.0.0, debug@^4.1.0, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
@@ -1262,6 +1327,36 @@ dlv@^1.1.3:
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
dom-serializer@^1.0.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.2.0"
entities "^2.0.0"
domelementtype@^2.0.1, domelementtype@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domhandler@^4.2.0, domhandler@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
dependencies:
domelementtype "^2.2.0"
domutils@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
dependencies:
dom-serializer "^1.0.1"
domelementtype "^2.2.0"
domhandler "^4.2.0"
dset@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.2.tgz#89c436ca6450398396dc6538ea00abc0c54cd45a"
@@ -1295,6 +1390,11 @@ emoji-regex@^9.2.2:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
entities@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
es-module-lexer@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f"
@@ -1433,6 +1533,14 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
fetch-blob@^3.1.2, fetch-blob@^3.1.4:
version "3.2.0"
resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9"
integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==
dependencies:
node-domexception "^1.0.0"
web-streams-polyfill "^3.0.3"
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
@@ -1464,6 +1572,13 @@ find-yarn-workspace-root2@1.2.16:
micromatch "^4.0.2"
pkg-dir "^4.2.0"
formdata-polyfill@^4.0.10:
version "4.0.10"
resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423"
integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==
dependencies:
fetch-blob "^3.1.2"
fraction.js@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950"
@@ -1942,6 +2057,11 @@ markdown-table@^3.0.0:
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.3.tgz#e6331d30e493127e031dd385488b5bd326e4a6bd"
integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==
marked@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/marked/-/marked-5.1.0.tgz#cf51f03ba04dfb3469774029fd0106d258658767"
integrity sha512-z3/nBe7aTI8JDszlYLk7dDVNpngjw0o1ZJtrA9kIfkkHcIF+xH7mO23aISl4WxP83elU+MFROgahqdpd05lMEQ==
mdast-util-definitions@^5.0.0:
version "5.1.2"
resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz#9910abb60ac5d7115d6819b57ae0bcef07a3f7a7"
@@ -2080,6 +2200,11 @@ mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0:
dependencies:
"@types/mdast" "^3.0.0"
mdn-data@2.0.14:
version "2.0.14"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
@@ -2436,6 +2561,20 @@ nlcst-to-string@^3.0.0:
dependencies:
"@types/nlcst" "^1.0.0"
node-domexception@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
node-fetch@^3.1.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e"
integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==
dependencies:
data-uri-to-buffer "^4.0.0"
fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10"
node-releases@^2.0.12:
version "2.0.12"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039"
@@ -2465,6 +2604,13 @@ npm-run-path@^5.1.0:
dependencies:
path-key "^4.0.0"
nth-check@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
dependencies:
boolbase "^1.0.0"
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -2847,6 +2993,18 @@ remark-smartypants@^2.0.0:
retext-smartypants "^5.1.0"
unist-util-visit "^4.1.0"
resolve-from@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
resolve-pkg@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-2.0.0.tgz#ac06991418a7623edc119084edc98b0e6bf05a41"
integrity sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==
dependencies:
resolve-from "^5.0.0"
resolve@^1.1.7, resolve@^1.17.0, resolve@^1.22.2:
version "1.22.2"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
@@ -3020,6 +3178,11 @@ source-map-js@^1.0.2:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
space-separated-tokens@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f"
@@ -3030,6 +3193,11 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
stable@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
stdin-discarder@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/stdin-discarder/-/stdin-discarder-0.1.0.tgz#22b3e400393a8e28ebf53f9958f3880622efde21"
@@ -3160,6 +3328,19 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
svgo@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24"
integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==
dependencies:
"@trysound/sax" "0.2.0"
commander "^7.2.0"
css-select "^4.1.3"
css-tree "^1.1.3"
csso "^4.2.0"
picocolors "^1.0.0"
stable "^0.1.8"
synckit@^0.8.4:
version "0.8.5"
resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3"
@@ -3515,6 +3696,11 @@ web-namespaces@^2.0.0:
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692"
integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==
web-streams-polyfill@^3.0.3:
version "3.2.1"
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
which-pm-runs@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.1.0.tgz#35ccf7b1a0fce87bd8b92a478c9d045785d3bf35"