Compare commits
26 Commits
bbbae5c8a6
...
legacy
| Author | SHA1 | Date | |
|---|---|---|---|
| a8943fc924 | |||
| 1d9c38e94a | |||
| fa3f7a8403 | |||
| 1d9508f49b | |||
| 6d2ffe6902 | |||
| c352ba7fd3 | |||
| 95087124b5 | |||
| 1d2f617a4e | |||
| 7fc923244e | |||
| f237d73016 | |||
| cae187b939 | |||
| 6f807b4df5 | |||
| ee6e250277 | |||
| 0dfa43c4ed | |||
| b228f3cd8d | |||
| d78fe7b020 | |||
| d8fedfb379 | |||
| 233442b099 | |||
| 0c7eedaee8 | |||
| 7385b7ba41 | |||
| 74f7274a7e | |||
| ab7464eb83 | |||
| 512d102bb2 | |||
| 82e0ee9280 | |||
| ba6a8c1308 | |||
| 7d70ad51e5 |
18
.drone.yml
Normal file
18
.drone.yml
Normal 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
50
.github/workflows/publish.yml
vendored
Normal 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
39
.github/workflows/test.yml
vendored
Normal 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
4
app/.npmrc.githubactions
Normal 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
|
||||
@@ -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",
|
||||
|
||||
98
app/src-tauri/Cargo.lock
generated
98
app/src-tauri/Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -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={{
|
||||
|
||||
64
app/src/components/Timeline/TrackDisplay/Graph.tsx
Normal file
64
app/src/components/Timeline/TrackDisplay/Graph.tsx
Normal 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;
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
108
app/src/components/Timeline/TrackDisplay/TrackPropertyGraph.tsx
Normal file
108
app/src/components/Timeline/TrackDisplay/TrackPropertyGraph.tsx
Normal 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;
|
||||
@@ -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 />
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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);
|
||||
|
||||
32
app/src/services/render.service.ts
Normal file
32
app/src/services/render.service.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
356
app/yarn.lock
356
app/yarn.lock
@@ -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
1
lib/creator_rs/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
target
|
||||
3834
lib/creator_rs/Cargo.lock
generated
Normal file
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
31
lib/creator_rs/Cargo.toml
Normal 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"]
|
||||
@@ -4,7 +4,7 @@ use crate::animation::{
|
||||
primitives::{
|
||||
paint::Paint,
|
||||
transform::{AnimatedTransform, Transform},
|
||||
values::{AnimatedFloatVec2, AnimatedValue},
|
||||
values::animated_values::{AnimatedFloatVec2, AnimatedValue},
|
||||
},
|
||||
timeline::Timeline,
|
||||
};
|
||||
@@ -4,7 +4,7 @@ use crate::animation::{
|
||||
primitives::{
|
||||
paint::Paint,
|
||||
transform::{AnimatedTransform, Transform},
|
||||
values::{AnimatedFloatVec2, AnimatedValue},
|
||||
values::animated_values::{AnimatedFloatVec2, AnimatedValue},
|
||||
},
|
||||
timeline::Timeline,
|
||||
};
|
||||
@@ -3,7 +3,7 @@ use crate::animation::{
|
||||
primitives::{
|
||||
paint::TextPaint,
|
||||
transform::{AnimatedTransform, Transform},
|
||||
values::{AnimatedFloatVec2, AnimatedValue},
|
||||
values::animated_values::{AnimatedFloatVec2, AnimatedValue},
|
||||
},
|
||||
timeline::Timeline,
|
||||
};
|
||||
@@ -2,7 +2,7 @@ use crate::animation::{
|
||||
primitives::{
|
||||
paint::TextPaint,
|
||||
transform::{AnimatedTransform, Transform},
|
||||
values::{AnimatedFloatVec2, AnimatedValue},
|
||||
values::animated_values::{AnimatedFloatVec2, AnimatedValue},
|
||||
},
|
||||
timeline::Timeline,
|
||||
};
|
||||
@@ -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>,
|
||||
@@ -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};
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
2
lib/creator_rs/src/animation/primitives/values/mod.rs
Normal file
2
lib/creator_rs/src/animation/primitives/values/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod animated_values;
|
||||
pub mod values;
|
||||
4
lib/creator_rs/src/animation/primitives/values/values.rs
Normal file
4
lib/creator_rs/src/animation/primitives/values/values.rs
Normal 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);
|
||||
@@ -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),
|
||||
@@ -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();
|
||||
|
||||
1
lib/creator_rs/src/fonts/mod.rs
Normal file
1
lib/creator_rs/src/fonts/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod fonts;
|
||||
3
lib/creator_rs/src/lib.rs
Normal file
3
lib/creator_rs/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod animation;
|
||||
#[cfg(feature = "fonts")]
|
||||
pub mod fonts;
|
||||
1
web/.vercel/project.json
Normal file
1
web/.vercel/project.json
Normal file
@@ -0,0 +1 @@
|
||||
{"orgId":"c0DV5ATsGbVZoMVVr9msnlC7","projectId":"prj_6wyilH72l9zcNlIfA9NUAJ0xON0v"}
|
||||
9
web/deploy.sh
Normal file
9
web/deploy.sh
Normal 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"
|
||||
@@ -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",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
52
web/src/components/Heading.astro
Normal file
52
web/src/components/Heading.astro
Normal 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>
|
||||
@@ -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>
|
||||
))
|
||||
|
||||
18
web/src/components/Layout/Header.astro
Normal file
18
web/src/components/Layout/Header.astro
Normal 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>
|
||||
43
web/src/components/Logo/tempblade.astro
Normal file
43
web/src/components/Logo/tempblade.astro
Normal 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 |
20
web/src/icons/Extensible.svg
Normal file
20
web/src/icons/Extensible.svg
Normal 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
6
web/src/icons/Fast.svg
Normal 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
32
web/src/icons/Open.svg
Normal 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 |
@@ -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>
|
||||
|
||||
@@ -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,35 +8,14 @@ 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>
|
||||
<Section id="test">
|
||||
<h1>Hallo!</h1>
|
||||
<h2>Wie gehts</h2>
|
||||
<h3>Wie gehts</h3>
|
||||
<h4>Wie gehts</h4>
|
||||
<h5>Wie gehts</h5>
|
||||
<p>
|
||||
cssnano is powered by PostCSS, a tool for transforming styles
|
||||
with JavaScript. Specifically, its plugin architecture allows us
|
||||
to compose cssnano out of small modules with limited
|
||||
responsibilities. It also allows you to easily insert cssnano
|
||||
into your build step, along with other processors that can lint
|
||||
your CSS for errors, or transpile future syntax.
|
||||
</p>
|
||||
<Button>Hallo</Button>
|
||||
<Button variant="secondary">Hallo</Button>
|
||||
<Button variant="ghost">Hallo</Button>
|
||||
<Button variant="destructive">Hallo</Button>
|
||||
<Button variant="outline">Hallo</Button>
|
||||
<Button variant="link">Hallo</Button>
|
||||
</Section>
|
||||
</main>
|
||||
</RootLayout>
|
||||
|
||||
27
web/src/pages/legal/imprint.astro
Normal file
27
web/src/pages/legal/imprint.astro
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -1,23 +1,53 @@
|
||||
<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
|
||||
subscriptions. You should own the tools you work with.
|
||||
</p>
|
||||
<p>
|
||||
tempblade Creator aims to get a feasable alternative to current motion
|
||||
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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
95
web/src/sections/bg-voronoi.ts
Normal file
95
web/src/sections/bg-voronoi.ts
Normal 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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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"]);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
186
web/yarn.lock
186
web/yarn.lock
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user