mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-29 09:08:58 +00:00
bi-directional timeline updates...
This commit is contained in:
@@ -61,7 +61,7 @@ fn draw_camera_keyframes(
|
|||||||
gizmos.line(origin, origin + z_axis, Color::BLUE);
|
gizmos.line(origin, origin + z_axis, Color::BLUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
let seek_time = **r_seek_time;
|
let seek_time = r_seek_time.time;
|
||||||
let keyframes_sorted = q_cam_keyframes
|
let keyframes_sorted = q_cam_keyframes
|
||||||
.iter()
|
.iter()
|
||||||
.sorted_by(|(a, _), (b, _)| a.partial_cmp(&b.0).unwrap())
|
.sorted_by(|(a, _), (b, _)| a.partial_cmp(&b.0).unwrap())
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ impl Plugin for AnimPlugin {
|
|||||||
camera::CameraAnimPlugin,
|
camera::CameraAnimPlugin,
|
||||||
timeline_animation::TimelinePlugin,
|
timeline_animation::TimelinePlugin,
|
||||||
));
|
));
|
||||||
|
|
||||||
#[cfg(feature = "wasm")]
|
|
||||||
app.add_systems(Update, wasm::update_global_seek_time);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use bevy::{
|
|||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use space_editor::space_prefab::editor_registry::EditorRegistryExt;
|
use space_editor::space_prefab::editor_registry::EditorRegistryExt;
|
||||||
|
|
||||||
pub struct TimelinePlugin;
|
pub struct TimelinePlugin;
|
||||||
@@ -14,15 +15,38 @@ impl Plugin for TimelinePlugin {
|
|||||||
app.register_type::<TimedAnimationClip>()
|
app.register_type::<TimedAnimationClip>()
|
||||||
.editor_registry::<TimedAnimationClip>()
|
.editor_registry::<TimedAnimationClip>()
|
||||||
.register_type::<AnimationTarget>()
|
.register_type::<AnimationTarget>()
|
||||||
.editor_registry::<AnimationTarget>();
|
.editor_registry::<AnimationTarget>()
|
||||||
|
.add_event::<TimelineEvent>();
|
||||||
|
|
||||||
app.insert_resource(GlobalSeekTime(0.));
|
app.insert_resource(GlobalSeekTime {
|
||||||
|
time: 0.,
|
||||||
|
playing: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
#[cfg(feature = "wasm")]
|
||||||
|
app.add_systems(
|
||||||
|
Update,
|
||||||
|
(
|
||||||
|
wasm::update_global_seek_time,
|
||||||
|
wasm::notify_seek_time_changes.map(bevy::utils::error),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource, Clone, Copy, Debug, Default, Deref, DerefMut, Reflect)]
|
#[derive(Event, Clone, Copy, Debug)]
|
||||||
|
pub enum TimelineEvent {
|
||||||
|
Play,
|
||||||
|
Pause,
|
||||||
|
Seek(f32),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Resource, Clone, Copy, Debug, Default, Reflect, Serialize, Deserialize)]
|
||||||
#[reflect(Resource)]
|
#[reflect(Resource)]
|
||||||
pub struct GlobalSeekTime(pub f32);
|
pub struct GlobalSeekTime {
|
||||||
|
pub time: f32,
|
||||||
|
pub playing: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component, Clone, Debug, Reflect, PartialEq)]
|
#[derive(Component, Clone, Debug, Reflect, PartialEq)]
|
||||||
#[reflect(Component, MapEntities)]
|
#[reflect(Component, MapEntities)]
|
||||||
@@ -83,23 +107,62 @@ pub struct AnimationTarget;
|
|||||||
|
|
||||||
#[cfg(feature = "wasm")]
|
#[cfg(feature = "wasm")]
|
||||||
mod wasm {
|
mod wasm {
|
||||||
use bevy::prelude::*;
|
use bevy::{prelude::*, window::PrimaryWindow};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
use crate::wasm::{StaticBuffer, WasmMessageBuffer};
|
use crate::wasm::{StaticBuffer, WasmMessageBuffer};
|
||||||
|
|
||||||
use super::GlobalSeekTime;
|
use super::{GlobalSeekTime, TimelineEvent};
|
||||||
|
|
||||||
static SEEK_TIME: WasmMessageBuffer<f32> = WasmMessageBuffer::new();
|
static SEEK_TIME: WasmMessageBuffer<TimelineEvent> = WasmMessageBuffer::new();
|
||||||
|
|
||||||
#[wasm_bindgen(js_name = seekTime)]
|
#[wasm_bindgen(js_name = seekTime)]
|
||||||
pub fn seek_time(timestamp: f32) {
|
pub fn seek_time(timestamp: f32) {
|
||||||
SEEK_TIME.write_message(timestamp);
|
SEEK_TIME.write_message(TimelineEvent::Seek(timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn update_global_seek_time(mut r_seek_time: ResMut<GlobalSeekTime>) {
|
#[wasm_bindgen(js_name = play)]
|
||||||
|
pub fn play() {
|
||||||
|
SEEK_TIME.write_message(TimelineEvent::Play);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_name = pause)]
|
||||||
|
pub fn pause() {
|
||||||
|
SEEK_TIME.write_message(TimelineEvent::Pause);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn update_global_seek_time(mut e_timeline_event: EventWriter<TimelineEvent>) {
|
||||||
if let Some(timestamp) = SEEK_TIME.take_message() {
|
if let Some(timestamp) = SEEK_TIME.take_message() {
|
||||||
**r_seek_time = timestamp;
|
e_timeline_event.send(timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(typescript_custom_section)]
|
||||||
|
const SEEK_TIME_CHANGED_EVENT: &str = r#"
|
||||||
|
export interface SeekTimeChanged extends CustomEvent {
|
||||||
|
type: "seek-time-changed";
|
||||||
|
detail: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
export interface GlobalEventHandlersEventMap {
|
||||||
|
"seek-time-changed": CameraKeyframesEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
pub(super) fn notify_seek_time_changes(
|
||||||
|
r_global_seek_time: Res<GlobalSeekTime>,
|
||||||
|
q_window: Query<&Window, With<PrimaryWindow>>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let Ok(window) = q_window.get_single() else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
crate::wasm::dispatch_to_js(
|
||||||
|
window,
|
||||||
|
"seek-time-changed",
|
||||||
|
&serde_json::to_value(r_global_seek_time.as_ref()).map_err(|e| format!("{e}"))?,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user