### Web Hello World Setup and Serve Source: https://blinc.rs/docs/web/examples.html Provides instructions for setting up and running the basic `web_hello` Blinc example. It includes cloning the repository, building the project with `wasm-pack`, and serving the static files using a local server script. ```bash git clone https://github.com/project-blinc/Blinc cd Blinc/examples/web_hello wasm-pack build --target web --release ./serve.sh # open http://localhost:8000/ ``` -------------------------------- ### Command to Build Web Examples Source: https://blinc.rs/docs/contributing/examples.html This command builds the web examples for Blinc applications. It is used after adding a new example file. ```bash cargo run -p blinc-build-web-examples ``` -------------------------------- ### Complete Minimal Blinc Application Example Source: https://blinc.rs/docs/contributing/examples.html A full example demonstrating a minimal Blinc application, including documentation comments for the gallery, main function setup, and a simple UI. ```rust //! My New Example //! //! One-paragraph description of what the demo shows. This text //! becomes the gallery page description verbatim — keep it short. //! Bullet points render fine: //! - First thing the example demonstrates //! - Second thing //! //! Run with: cargo run -p blinc_app_examples --example my_new --features windowed use blinc_app::prelude::*; use blinc_app::windowed::WindowedContext; #[cfg(not(target_arch = "wasm32"))] fn main() -> Result<()> { tracing_subscriber::fmt() .with_max_level(tracing::Level::INFO) .init(); let config = WindowConfig { title: "My New Example".to_string(), width: 800, height: 600, ..Default::default() }; // Closure wrapper: on edition 2024 a free fn `-> impl Element` // captures its input lifetime in the return type, which breaks the // higher-ranked `FnMut` bound. The closure form is portable across // editions. See `WindowedApp::run` docs for the `+ use<>` alternative. blinc_app::windowed::WindowedApp::run(config, |ctx| build_ui(ctx)) } pub fn build_ui(ctx: &mut WindowedContext) -> impl ElementBuilder { div() .w(ctx.width) .h(ctx.height) .bg(Color::rgba(0.08, 0.08, 0.12, 1.0)) .items_center() .justify_center() .child( text("Hello, Blinc!") .size(32.0) .color(Color::WHITE), ) } ``` -------------------------------- ### Run Strangler Demo Example Source: https://blinc.rs/docs/web/example-gallery/strangler_demo.html Command to run the 'strangler_demo' example from the blinc_app_examples package, enabling the 'gltf' feature for WebGPU rendering. ```bash __ cargo run -p blinc_app_examples --example strangler_demo \ --features gltf --release ``` -------------------------------- ### WASM Entry Point and UI Setup Source: https://blinc.rs/docs/web/setup.html This is the main entry point for the WASM build. It sets up panic handling, tracing, and initiates the WebApp run. The setup closure is crucial for registering fonts and CSS before the first frame. ```rust #![allow(unused)] #![cfg(target_arch = "wasm32")] fn main() { use blinc_app::web::WebApp; use blinc_app::windowed::WindowedContext; use blinc_core::Color; use blinc_layout::div::{div, Div}; use blinc_layout::text::text; use wasm_bindgen::prelude::*; const FONT: &[u8] = include_bytes!("../fonts/Inter.ttf"); /// wasm-bindgen entry point. The `start` attribute makes this run /// automatically when the browser loads the generated `.js` shim. #[wasm_bindgen(start)] pub fn _start() { // Install the panic hook so any Rust panic shows up in the // browser console with a stack trace instead of a useless // `RuntimeError: unreachable executed`. console_error_panic_hook::set_once(); // Bridge `tracing::*` macros into the browser DevTools console. // INFO level keeps the per-frame DEBUG lines from the renderer // out of the console — at 60fps those drown the JS thread. tracing_wasm::set_as_global_default_with_config( tracing_wasm::WASMLayerConfigBuilder::new() .set_max_level(tracing::Level::INFO) .build(), ); // `WebApp::run` is `async`, but `#[wasm_bindgen(start)]` can't // return a future. Spawn it on the wasm-bindgen-futures executor // instead. wasm_bindgen_futures::spawn_local(async { let result = WebApp::run_with_setup( "blinc-canvas", // Setup callback runs once between init and the first // frame. Use it to register fonts (required — the wasm32 // init path skips system font discovery, so the registry // starts empty), CSS, and any one-shot config. |app| { app.load_font_data(FONT.to_vec()); }, build_ui, ) .await; if let Err(e) = result { web_sys::console::error_1( &format!("WebApp::run failed: {e}").into(), ); } }); } /// User UI builder. Re-invoked by the runner whenever a rebuild is /// requested. fn build_ui(_ctx: &mut WindowedContext) -> Div { div() .w_full() .h_full() .bg(Color::rgba(0.07, 0.07, 0.10, 1.0)) .items_center() .justify_center() .child( text("Hello, WebGPU!") .size(32.0) .color(Color::rgba(0.92, 0.92, 0.95, 1.0)), ) } } ``` -------------------------------- ### Various Aspect Ratio Examples Source: https://blinc.rs/docs/cn/layout.html Provides examples of setting different aspect ratios, including common video and image formats like 16:9, 4:3, 1:1, and 3:4. ```rust #![allow(unused)] fn main() { // 16:9 (video) aspect_ratio(16.0 / 9.0) // 4:3 (classic) aspect_ratio(4.0 / 3.0) // 1:1 (square) aspect_ratio(1.0) // 3:4 (portrait) aspect_ratio(3.0 / 4.0) } ``` -------------------------------- ### macOS Environment Setup for Android Development Source: https://blinc.rs/docs/mobile/android.html Installs Android Studio and sets up necessary environment variables for Android development on macOS. ```bash # macOS brew install --cask android-studio export ANDROID_HOME=$HOME/Library/Android/sdk export ANDROID_NDK_HOME=$ANDROID_HOME/ndk/26.1.10909125 export PATH=$PATH:$ANDROID_HOME/platform-tools ``` -------------------------------- ### Minimum Blinc Web App Source: https://blinc.rs/docs/web/examples.html The 'web_hello' example demonstrates the smallest possible Blinc application. It sets up a canvas, loads a bundled font, and displays centered text on a dark background. This example verifies the end-to-end pipeline including wgpu, wasm-bindgen, requestAnimationFrame, and WebApp::run. ```rust #![allow(unused)] fn main() { use blinc_app::web::WebApp; use blinc_layout::div::{div, Div}; use blinc_layout::text::text; use blinc_core::Color; use wasm_bindgen::prelude::*; const ARIAL: &[u8] = include_bytes!("../fonts/Arial.ttf"); #[wasm_bindgen(start)] pub fn _start() { console_error_panic_hook::set_once(); wasm_bindgen_futures::spawn_local(async { WebApp::run_with_setup( "blinc-canvas", |app| { app.load_font_data(ARIAL.to_vec()); }, build_ui, ).await.unwrap(); }); } fn build_ui(_ctx: &mut blinc_app::windowed::WindowedContext) -> Div { div() .w_full().h_full() .bg(Color::rgba(0.07, 0.07, 0.10, 1.0)) .items_center().justify_center() .child( text("Hello, WebGPU!") .size(32.0) .color(Color::WHITE), ) } } ``` -------------------------------- ### Initialize Theme with WindowedApp Source: https://blinc.rs/docs/core/theming.html Use `WindowedApp::run_with_theme` to install a `ThemeBundle` and set the initial color scheme. This is the recommended entry point for applications. ```rust #![allow(unused)] fn main() { use blinc_app::prelude::*; use blinc_theme::{BlincTheme, ColorScheme}; WindowedApp::run_with_theme( WindowConfig::default(), BlincTheme::bundle(), // any ThemeBundle — `cn_bundle()`, `BlincTheme::bundle()`, // or your own ColorScheme::Dark, // Closure wrapper rather than bare `build_ui`: on edition 2024 a // free fn `-> impl Element` captures its input lifetime in the // return type, which breaks the higher-ranked `FnMut` bound. See // `WindowedApp::run` docs for the alternative (`+ use<>` on the fn). |ctx| build_ui(ctx), ) } ``` -------------------------------- ### Desktop Build Command Source: https://blinc.rs/docs/contributing/examples.html Command to run a Blinc example on the desktop target using cargo. ```bash cargo run -p blinc_app_examples --example my_new --features windowed ``` -------------------------------- ### Using StateContext Utilities Source: https://blinc.rs/docs/core/state.html This example shows how to use the `StateContext` within a `stateful` element's callback to access the current state, create scoped signals and animated values, and retrieve dependency values. It illustrates the basic setup for managing dynamic UI elements. ```rust stateful::() .on_state(|ctx| { // Get current state let state = ctx.state(); // Create scoped signals (persist across rebuilds) let counter = ctx.use_signal("counter", || 0); // Create scoped animated values let opacity = ctx.use_animated_value("opacity", 1.0); // Access dependency values let value: i32 = ctx.dep(0).unwrap_or_default(); // Dispatch events to trigger state transitions // ctx.dispatch(CUSTOM_EVENT); div().bg(color_for_state(state)) }) ``` -------------------------------- ### Install Dioxus CLI Source: https://blinc.rs/docs/advanced/hot-reload.html Install the Dioxus CLI globally using Cargo. This is a one-time setup required to run your application with hot-reloading. ```bash cargo install dioxus-cli ``` -------------------------------- ### Install Xcode Command Line Tools Source: https://blinc.rs/docs/mobile/ios.html Ensures Xcode command line tools are installed and accessible. ```bash xcode-select -p ``` -------------------------------- ### LottiePlayer Example Source: https://blinc.rs/docs/canvas-kit/players.html `blinc_lottie::LottiePlayer` implements `Player`. Wrap it in a sketch to run at any size. ```APIDOC ## LottiePlayer Example `blinc_lottie::LottiePlayer` implements `Player`. Wrap it in a sketch to run at any size: ```rust #![allow(unused)] fn main() { use blinc_app::prelude::*; use blinc_canvas_kit::prelude::*; use blinc_core::{Color, Rect}; use blinc_lottie::LottiePlayer; const LOTTIE_JSON: &str = include_str!("assets/my_animation.json"); struct Loader { player: LottiePlayer, } impl Sketch for Loader { fn draw(&mut self, ctx: &mut SketchContext<'_>, t: f32, _dt: f32) { let size = ctx.width.min(ctx.height); let x = (ctx.width - size) * 0.5; let y = (ctx.height - size) * 0.5; ctx.play(&mut self.player, Rect::new(x, y, size, size), t); } } fn build_ui() -> impl ElementBuilder { let player = LottiePlayer::from_json(LOTTIE_JSON).expect("parse Lottie"); div() .w_full() .h_full() .bg(Color::WHITE) .child(sketch("lottie", Loader { player })) } } ``` `ctx.play(&mut player, rect, t)` is a thin forwarder over `Player::draw_at` — provided so sketches holding a player on `self` don’t hit borrow-checker friction when `draw` also reads other `self` fields. Lottie specifically supports both plain JSON (`from_json`) and `.lottie` archives (`from_dotlottie_bytes`, requires the `dotlottie` feature). See the `blinc_lottie` crate for asset-loading variants. ``` -------------------------------- ### Full Counter Application Example Source: https://blinc.rs/docs/getting-started/first-app.html This is the complete code for a basic counter application. It shows how to set up a window, manage state, and build UI elements. ```rust use blinc_app::prelude::*; use blinc_app::windowed::{WindowedApp, WindowedContext}; use blinc_layout::stateful::stateful; fn main() -> Result<()> { tracing_subscriber::fmt() .with_max_level(tracing::Level::INFO) .init(); let config = WindowConfig { title: "Counter App".to_string(), width: 400, height: 300, resizable: true, ..Default::default() }; WindowedApp::run(config, |ctx| build_ui(ctx)) } fn build_ui(ctx: &WindowedContext) -> impl ElementBuilder { let count = ctx.use_state_keyed("counter", || 0i32); div() .w(ctx.width) .h(ctx.height) .bg(Color::rgba(0.08, 0.08, 0.12, 1.0)) .flex_col() .justify_center() .items_center() .gap(24.0) .child( text("Counter") .size(32.0) .weight(FontWeight::Bold) .color(Color::WHITE) ) .child(count_display(count.clone())) .child( div() .flex_row() .gap(16.0) .child(counter_button(count.clone(), "-", -1)) .child(counter_button(count.clone(), "+", 1)) ) } fn count_display(count: State) -> impl ElementBuilder { stateful::() .deps([count.signal_id()]) .on_state(move |_ctx| { let current = count.get(); div().child( text(&format!("{}", current)) .size(64.0) .weight(FontWeight::Bold) .color(Color::rgba(0.4, 0.6, 1.0, 1.0)) ) }) } fn counter_button( count: State, label: &'static str, delta: i32, ) -> impl ElementBuilder { stateful::() .w(60.0) .h(60.0) .rounded(12.0) .flex_center() .on_state(|ctx| { let bg = match ctx.state() { ButtonState::Idle => Color::rgba(0.2, 0.2, 0.25, 1.0), ButtonState::Hovered => Color::rgba(0.3, 0.3, 0.35, 1.0), ButtonState::Pressed => Color::rgba(0.15, 0.15, 0.2, 1.0), ButtonState::Disabled => Color::rgba(0.1, 0.1, 0.12, 0.5), }; div().bg(bg) }) .on_click(move |_| { count.update(|v| v + delta); }) .child( text(label) .size(28.0) .weight(FontWeight::Bold) .color(Color::WHITE) ) } ``` -------------------------------- ### Android MainActivity Setup Source: https://blinc.rs/docs/mobile/overview.html Set up the MainActivity in Android to load the native library and register default and custom handlers for the Blinc native bridge. ```kotlin companion object { init { System.loadLibrary("my_app") } } // In onCreate: override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // REQUIRED: register the built-in handlers (haptics, device info, // keyboard show/hide, clipboard) before the Rust frame loop starts. BlincNativeBridge.registerDefaults(this) // Optional: register your own custom handlers BlincNativeBridge.registerString("device", "get_battery_level") { val bm = getSystemService(Context.BATTERY_SERVICE) as BatteryManager bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY).toString() } BlincNativeBridge.registerVoid("notify", "show") { val title = args.getString(0) val body = args.getString(1) NotificationHelper.show(this, title, body) } } ``` -------------------------------- ### Basic Tooltip Example Source: https://blinc.rs/docs/cn/data-display.html Demonstrates how to create a simple tooltip with a trigger and content. Use this for providing brief, contextual information on hover. ```rust #![allow(unused)] fn main() { use blinc_cn::prelude::*; tooltip() .child(tooltip_trigger() .child(button("Hover me"))) .child(tooltip_content() .child(text("This is a tooltip"))) } ``` -------------------------------- ### Custom Player Example (Orbit) Source: https://blinc.rs/docs/canvas-kit/players.html Anything that can resolve a pose from a float time implements `Player`. A minimal example: a player that renders an orbiting dot. ```APIDOC ## Custom Player Example (Orbit) Anything that can resolve a pose from a float time implements `Player`. A minimal example: a player that renders an orbiting dot. ```rust #![allow(unused)] fn main() { use blinc_canvas_kit::prelude::*; use blinc_core::{Color, CornerRadius, Brush, Rect}; struct Orbit; impl Player for Orbit { fn duration(&self) -> Option { None } // plays forever fn draw_at(&mut self, ctx: &mut SketchContext<'_>, rect: Rect, t: f32) { let cx = rect.x() + rect.width() * 0.5; let cy = rect.y() + rect.height() * 0.5; let r = rect.width().min(rect.height()) * 0.4; let a = t * std::f32::consts::TAU * 0.5; let x = cx + r * a.cos() - 8.0; let y = cy + r * a.sin() - 8.0; ctx.draw_context().fill_rect( Rect::new(x, y, 16.0, 16.0), CornerRadius::uniform(8.0), Brush::Solid(Color::WHITE), ); } } } ``` Drop `Orbit` into any sketch via `ctx.play(&mut orbit, rect, t)` and it composes with other players, sketches, and UI in the same frame. ``` -------------------------------- ### Blinc project configuration file Source: https://blinc.rs/docs/mobile/cli.html Example structure of the Blinc project configuration file, defining project metadata, targets, and build settings. ```toml [project] name = "my-app" version = "0.1.0" template = "rust" entry = "Cargo.toml" [targets] default = "desktop" supported = ["desktop", "android", "ios"] [targets.desktop] enabled = true command = "cargo run --features desktop" [targets.android] enabled = true platform_dir = "platforms/android" [targets.ios] enabled = true platform_dir = "platforms/ios" [build] blinc_path = "../.." # Path to Blinc framework ``` -------------------------------- ### Building a State Machine Source: https://blinc.rs/docs/architecture/stateful.html Example of constructing a state machine using a builder pattern, defining states and transitions for a button-like interaction. ```rust #![allow(unused)] fn main() { let fsm = StateMachine::builder(initial_state) .on(State::Idle, Event::PointerEnter, State::Hovered) .on(State::Hovered, Event::PointerLeave, State::Idle) .on(State::Hovered, Event::PointerDown, State::Pressed) .on(State::Pressed, Event::PointerUp, State::Hovered) .on_enter(State::Pressed, || { println!("Button pressed!"); }) .build(); } ``` -------------------------------- ### Run Android project Source: https://blinc.rs/docs/mobile/cli.html Builds, installs, and launches the Android application on a connected device or emulator. Supports release builds and targeting specific devices. ```bash blinc run android ``` -------------------------------- ### Animated Timeline Configuration Source: https://blinc.rs/docs/architecture/animation.html Shows how to set up and start an animated timeline, adding individual animations with durations and values. Supports looping and other playback modes. ```rust #![allow(unused)] fn main() { let timeline = ctx.use_animated_timeline(); let entry_id = timeline.lock().unwrap().configure(|t| { // Add animation entries let rotation_id = t.add( 0, // start_ms 1000, // duration_ms 0.0, // from 360.0 // to ); // Configure looping t.set_loop(-1); // -1 = infinite loop // Start the timeline t.start(); rotation_id }); } ``` -------------------------------- ### Alert Dialog Example Source: https://blinc.rs/docs/cn/dialog.html Shows how to implement an alert dialog for destructive actions like account deletion. It includes confirmation prompts and destructive action buttons. ```rust #![allow(unused)] fn main() { let is_open = use_state_keyed("confirm_dialog_open", || false); alert_dialog() .open(is_open.clone()) .on_open_change({ let is_open = is_open.clone(); move |open| is_open.set(open) }) .child(alert_dialog_trigger() .child(button("Delete Account").variant(ButtonVariant::Destructive))) .child(alert_dialog_content() .child(alert_dialog_header() .child(alert_dialog_title("Delete Account")) .child(alert_dialog_description( "Are you sure you want to delete your account? \ All your data will be permanently removed." ))) .child(alert_dialog_footer() .child(alert_dialog_cancel().child( button("Cancel").variant(ButtonVariant::Outline) )) .child(alert_dialog_action().child( button("Delete") .variant(ButtonVariant::Destructive) .on_click(move |_| delete_account()) )))) } ``` -------------------------------- ### Create a Simple Blinc Application Source: https://blinc.rs/docs/getting-started/installation.html A basic Blinc application that creates a window and displays centered text. This example requires the 'windowed' feature to be enabled. ```rust // src/main.rs use blinc_app::prelude::*; use blinc_app::windowed::{WindowedApp, WindowedContext}; fn main() -> Result<()> { WindowedApp::run(WindowConfig::default(), |ctx| { div() .w(ctx.width) .h(ctx.height) .bg(Color::rgba(0.1, 0.1, 0.15, 1.0)) .flex_center() .child(text("Blinc is working!").size(32.0).color(Color::WHITE)) }) } ``` -------------------------------- ### Form Dialog Example Source: https://blinc.rs/docs/cn/dialog.html Demonstrates creating a customizable dialog for editing profile information. It includes input fields for name and email, with save and cancel actions. ```rust #![allow(unused)] fn main() { let is_open = use_state_keyed("form_dialog_open", || false); let name = use_state_keyed("form_dialog_name", || String::new()); let email = use_state_keyed("form_dialog_email", || String::new()); dialog() .open(is_open.clone()) .on_open_change({ let is_open = is_open.clone(); move |open| is_open.set(open) }) .child(dialog_trigger() .child(button("Edit Profile"))) .child(dialog_content() .child(dialog_header() .child(dialog_title("Edit Profile")) .child(dialog_description("Update your profile information"))) .child( div() .flex_col() .gap(16.0) .child( div().flex_col().gap(4.0) .child(label("Name")) .child(input() .value(&name) .on_change({ let name = name.clone(); move |v| name.set(v) })) ) .child( div().flex_col().gap(4.0) .child(label("Email")) .child(input() .value(&email) .on_change({ let email = email.clone(); move |v| email.set(v) })) ) ) .child(dialog_footer() .child(dialog_close().child( button("Cancel").variant(ButtonVariant::Outline) )) .child(button("Save").on_click({ let is_open = is_open.clone(); move |_| { save_profile(); is_open.set(false); } })))) } ``` -------------------------------- ### Basic Blinc Mobile App UI Source: https://blinc.rs/docs/mobile/overview.html Example of a simple Blinc UI component with state management for a counter. Ensure `blinc_app::prelude::*` is imported. ```rust #![allow(unused)] fn main() { use blinc_app::prelude::*; fn app(ctx: &mut WindowedContext) -> impl ElementBuilder { let count = ctx.use_state_keyed("count", || 0i32); div() .w(ctx.width).h(ctx.height) .bg(Color::from_hex(0x1a1a2e)) .flex_col().items_center().justify_center().gap(20.0) .child(text(format!("Count: {}", count.get())).size(48.0).color(Color::WHITE)) .child( button(state.clone(), "+") .on_click(move |_| count.set(count.get() + 1)) ) } } ``` -------------------------------- ### Run glTF Animation Demo Source: https://blinc.rs/docs/web/example-gallery/gltf_animation_demo.html Command to run the glTF animation example using Cargo. Ensure you have the 'gltf' feature enabled and are running in release mode. ```bash cargo run -p blinc_app_examples --example gltf_animation_demo \ --features gltf --release ``` -------------------------------- ### Rust Android Target Setup and Cargo Install Source: https://blinc.rs/docs/mobile/android.html Adds necessary Rust cross-compilation targets for Android and installs the cargo-ndk tool. ```bash rustup target add aarch64-linux-android rustup target add armv7-linux-androideabi rustup target add x86_64-linux-android cargo install cargo-ndk ``` -------------------------------- ### Web Build and Serve Process Source: https://blinc.rs/docs/contributing/examples.html Steps to build and serve a Blinc example for the web target, including generating the wrapper crate, building with wasm-pack, and serving the output. ```bash # 1. Generate (or regenerate) the wasm wrapper crate car go run -p blinc-build-web-examples # 2. Build it with wasm-pack cd examples/_generated/my_new wasm-pack build --target web --release # 3. Serve it ./serve.sh 8000 # Open http://localhost:8000 in Chrome 113+ ``` -------------------------------- ### Setting Initial State for a Stateful Button Source: https://blinc.rs/docs/advanced/state-machines.html Use `.initial()` to define a non-default starting state for a stateful element. This example sets an initial disabled state for a button. ```rust #![allow(unused)] fn main() { fn initially_disabled_button(disabled: bool) -> impl ElementBuilder { stateful::() .initial(if disabled { ButtonState::Disabled } else { ButtonState::Idle }) .on_state(|ctx| { let bg = match ctx.state() { ButtonState::Disabled => Color::GRAY, ButtonState::Idle => Color::BLUE, ButtonState::Hovered => Color::CYAN, ButtonState::Pressed => Color::DARK_BLUE, }; div().bg(bg) }) } } ``` -------------------------------- ### Blinc Application Entry Point Source: https://blinc.rs/docs/getting-started/project-structure.html Sets up the Blinc application window, initializes tracing, and runs the main application builder. ```rust use blinc_app::prelude::*; use blinc_app::windowed::{WindowedApp, WindowedContext}; mod app; mod components; mod screens; mod state; fn main() -> Result<()> { tracing_subscriber::fmt() .with_env_filter( tracing_subscriber::EnvFilter::from_default_env() .add_directive(tracing::Level::INFO.into()), ) .init(); let config = WindowConfig { title: "My App".to_string(), width: 1200, height: 800, resizable: true, ..Default::default() }; WindowedApp::run(config, |ctx| app::build(ctx)) } ``` -------------------------------- ### Install wasm-pack Source: https://blinc.rs/docs/web/setup.html Install the wasm-pack tool, which is used to build and package WebAssembly projects. ```rust cargo install wasm-pack ``` -------------------------------- ### Initialize SceneKit3D with Environment and Camera Source: https://blinc.rs/docs/canvas-kit/scenekit-3d.html This snippet shows how to create a SceneKit3D instance, set an environment map, and configure an orbit camera. It's useful for setting up a basic 3D viewer with interactive camera controls. ```rust #![allow(unused)] fn main() { use blinc_canvas_kit::prelude::*; use blinc_core::{Material, MeshData}; use std::sync::Arc; fn build_ui() -> impl ElementBuilder { let kit = SceneKit3D::new("viewer") .with_environment(generate_studio_environment(256)) .with_camera(OrbitCamera::default() .with_distance(5.0) .with_elevation(0.2)); // Load a mesh — replace with glTF loading in real apps. let mesh: Arc = load_my_mesh(); kit.add_mesh(mesh); div() .w_full() .h_full() .child(kit.element_auto()) } } ``` -------------------------------- ### Install Vulkan Development Libraries Source: https://blinc.rs/docs/getting-started/installation.html Commands to install Vulkan development libraries on Ubuntu/Debian, Fedora, and Arch Linux systems. ```bash # Ubuntu/Debian sudo apt install libvulkan-dev # Fedora sudo dnf install vulkan-devel # Arch sudo pacman -S vulkan-icd-loader ``` -------------------------------- ### Cross-Platform Example Function Signature Source: https://blinc.rs/docs/contributing/examples.html Every cross-target example must define a function with this signature. This function is responsible for building the UI elements. ```rust #![allow(unused)] fn main() { pub fn build_ui(ctx: &mut WindowedContext) -> impl ElementBuilder { // The actual demo UI. } } ``` -------------------------------- ### Create a new Blinc project Source: https://blinc.rs/docs/mobile/cli.html Initializes a new Blinc project with specified template and platform configurations. Sets up Cargo.toml, platform directories, build scripts, and example UI code. ```bash blinc new my-app --template rust ``` -------------------------------- ### Run Rich Text Demo Example Source: https://blinc.rs/docs/widgets/text.html Command to run the rich text demo application, which showcases various text features. Ensure you have the necessary features enabled for windowed applications. ```bash cargo run -p blinc_app_examples --example rich_text_demo --features windowed ``` -------------------------------- ### Minimal Blinc Windowed Application Source: https://blinc.rs/docs/introduction.html A minimal example of a Blinc application using `WindowedApp`. This demonstrates setting up a basic window, background color, and centered text content. ```rust use blinc_app::prelude::*; use blinc_app::windowed::{WindowedApp, WindowedContext}; fn main() -> Result<()> { WindowedApp::run(WindowConfig::default(), |ctx| { div() .w(ctx.width) .h(ctx.height) .bg(Color::rgba(0.1, 0.1, 0.15, 1.0)) .flex_center() .child( div() .glass() .rounded(16.0) .p(32.0) .child(text("Hello, Blinc!").size(24.0).color(Color::WHITE)) ) }) } ``` -------------------------------- ### Documenting Non-Web Examples Source: https://blinc.rs/docs/contributing/examples.html Use a `//! no-web:` doc comment at the top of a file to indicate that an example is not intended for the web target. This prevents the codegen tool from processing it for the web build. ```rust #![allow(unused)] fn main() { //! Multi-Window Demo //! //! no-web: the web target has no multi-window concept — a browser //! tab is a single ``. `open_window_with()` doesn't //! translate to the browser. Kept desktop-only on purpose. //! //! Demonstrates: ... ``` -------------------------------- ### Fetched Font Loading with run_with_async_setup Source: https://blinc.rs/docs/web/fonts-assets.html This pattern is recommended for real applications, especially those with multiple or large fonts. Fonts are fetched as static assets, allowing the browser to cache them independently and keeping the WASM artifact small. The setup closure runs asynchronously. ```Rust #![allow(unused)] fn main() { use blinc_app::web::WebApp; use blinc_app::BlincError; use blinc_platform_web::WebAssetLoader; use wasm_bindgen::prelude::*; #[wasm_bindgen(start)] pub fn _start() { console_error_panic_hook::set_once(); wasm_bindgen_futures::spawn_local(async { WebApp::run_with_async_setup( "blinc-canvas", // The `Box::pin(async move { ... })` ceremony is the // stable-Rust workaround for the lack of `async FnOnce`. // Once async closures stabilize, this drops back to // `|app| async move { ... }`. |app| Box::pin(async move { let bytes = WebAssetLoader::fetch_bytes("fonts/Inter.ttf") .await .map_err(|e| BlincError::Platform(e.to_string()))?; app.load_font_data(bytes); Ok(()) }), build_ui, ) .await .unwrap(); }); } } ``` -------------------------------- ### Animated Spinner Example Source: https://blinc.rs/docs/widgets/canvas.html A complete example demonstrating how to create an animated spinner using the canvas element and Blinc's timeline animation system. It draws spinning segments that rotate over time. ```rust #![allow(unused)] fn main() { use std::f32::consts::PI; fn spinner(ctx: &WindowedContext) -> impl ElementBuilder { let timeline = ctx.use_animated_timeline(); let entry_id = timeline.lock().unwrap().configure(|t| { let id = t.add(0, 1000, 0.0, 360.0); t.set_loop(-1); t.start(); id }); let render_timeline = Arc::clone(&timeline); canvas(move |draw_ctx, bounds| { let angle_deg = render_timeline.lock().unwrap().get(entry_id).unwrap_or(0.0); let angle_rad = angle_deg * PI / 180.0; let cx = bounds.width / 2.0; let cy = bounds.height / 2.0; let radius = 30.0; // Draw spinning segments for i in 0..8 { let segment_angle = angle_rad + (i as f32 * PI / 4.0); let alpha = 1.0 - (i as f32 * 0.1); let x = cx + segment_angle.cos() * radius; let y = cy + segment_angle.sin() * radius; draw_ctx.fill_circle( Point::new(x, y), 4.0, Brush::Solid(Color::rgba(0.4, 0.6, 1.0, alpha)), ); } }) .w(80.0) .h(80.0) } } ``` -------------------------------- ### Starting the System Theme Watcher Source: https://blinc.rs/docs/core/theming.html Start the system theme watcher to automatically update the Blinc theme when the OS color scheme changes. You can use the default interval or specify a custom polling duration. ```rust #![allow(unused)] fn main() { use blinc_theme::{SystemSchemeWatcher, WatcherConfig}; use std::time::Duration; // Start watching with default interval (1 second) let watcher = SystemSchemeWatcher::start(); // Or with a custom polling interval let watcher = SystemSchemeWatcher::start_with_interval(Duration::from_secs(5)); // The watcher runs in a background thread and automatically updates // ThemeState when the system color scheme changes. // Stop watching when done (or let it drop) // watcher.stop(); } ``` -------------------------------- ### CSS Configuration for Pointer Range Source: https://blinc.rs/docs/advanced/pointer-query.html Examples of setting the `pointer-range` CSS property to define the output range for normalized coordinates. The first example uses the default symmetric range, and the second uses a 0 to 1 range. ```css /* Default: symmetric -1 to 1 (good for center origin) */ #card { pointer-range: -1.0 1.0; } /* 0 to 1 (good for top-left origin) */ #card { pointer-range: 0.0 1.0; } ``` -------------------------------- ### Run Application with Custom Theme Source: https://blinc.rs/docs/core/theming.html Install your custom theme bundle using `WindowedApp::run_with_theme`, optionally attaching additional CSS and specifying the initial color scheme. ```rust #![allow(unused)] fn main() { WindowedApp::run_with_theme( config, MyTheme::bundle().with_css(MY_STYLES), ColorScheme::Dark, |ctx| build_ui(ctx), ) } ``` -------------------------------- ### Basic Text Input Usage Source: https://blinc.rs/docs/widgets/inputs.html Demonstrates the basic setup for a text input field, including initial placeholder text and an `on_change` handler to capture input. ```rust #![allow(unused)] fn main() { use blinc_layout::widgets::text_input::{text_input, text_input_state}; fn my_ui(ctx: &WindowedContext) -> impl ElementBuilder { let state = text_input_state("Enter your name..."); text_input(&state) .w(300.0) .on_change(|text| { println!("Input: {}", text); }) } } ``` -------------------------------- ### Complete Form Example Source: https://blinc.rs/docs/cn/form.html Demonstrates the creation of a multi-field form including text inputs, a select dropdown, a checkbox, and a submit button. Use this for building standard forms. ```Rust #![allow(unused)] fn main() { div() .flex_col() .gap(24.0) .max_w(400.0) // Name field .child( div().flex_col().gap(4.0) .child(label("Name")) .child(input() .placeholder("John Doe") .value(&name) .on_change(|v| set_name(v))) ) // Email field .child( div().flex_col().gap(4.0) .child(label("Email")) .child(input() .input_type("email") .placeholder("john@example.com") .value(&email) .on_change(|v| set_email(v))) ) // Country select .child( div().flex_col().gap(4.0) .child(label("Country")) .child(select() .value(&country) .on_change(|v| set_country(v)) .child(select_trigger().child(select_value())) .child(select_content() .child(select_item("us").child(text("United States"))) .child(select_item("uk").child(text("United Kingdom"))) .child(select_item("ca").child(text("Canada"))))) ) // Terms checkbox .child( checkbox() .checked(accepted_terms) .on_change(|v| set_accepted_terms(v)) .child(label("I accept the terms and conditions")) ) // Submit button .child( button("Submit") .full_width(true) .disabled(!accepted_terms) .on_click(|| submit_form()) ) } ``` -------------------------------- ### Demonstrate Various Text Features Source: https://blinc.rs/docs/widgets/text.html A comprehensive example showcasing different text widgets including plain text, rich text with inline HTML-like tags, interactive links, and programmatic range-based styling. ```rust #![allow(unused)] fn main() { use blinc_app::prelude::*; use blinc_core::Color; fn demo_ui() -> impl ElementBuilder { div() .flex_col() .gap(16.0) .p(20.0) // Plain text .child( text("Plain Text Example") .size(24.0) .color(Color::WHITE) .bold() ) // Rich text with inline formatting .child( rich_text("This is bold, italic, and green.") .size(16.0) .default_color(Color::WHITE) ) // Interactive link .child( rich_text(r#"Visit GitHub for more."#) .size(16.0) .default_color(Color::WHITE) ) // Range-based styling .child( rich_text("Programmatic styling with ranges") .bold_range(0..13) .color_range(14..21, Color::CYAN) .underline_range(22..32) .size(16.0) .default_color(Color::WHITE) ) } } ``` -------------------------------- ### Universal Selector Example Source: https://blinc.rs/docs/core/css-styling.html Applies a style to all elements on the page using the universal selector `*`. ```CSS * { opacity: 1.0; } ``` -------------------------------- ### Blinc Scrollable List with Physics Source: https://blinc.rs/docs/web/examples.html The 'web_scroll' example showcases a vertical list of items within a scrollable container. It demonstrates handling wheel input for scrolling, the scroll widget's per-frame physics tick for deceleration, and click events on list items. This example uses `scroll()` with a `no_bounce()` configuration suitable for web environments. ```rust const CARD_COUNT: usize = 24; let mut content = div().w_full().flex_col().p_px(20.0).gap_px(12.0); for idx in 0..CARD_COUNT { let label = format!("Card {}", idx + 1); let card_index = idx + 1; content = content.child( div() .w_full().h_fit() .bg(Color::rgba(0.16, 0.16, 0.21, 1.0)) .rounded(12.0).p_px(16.0) .child(text(&label).size(20.0).color(Color::WHITE)) .on_click(move |_| { web_sys::console::log_1( &format!("clicked card #{}", card_index).into(), ); }), ); } div() .w_full().h_full() .bg(Color::rgba(0.07, 0.07, 0.10, 1.0)) .child( scroll() .w_full() .h(ctx.height - 96.0) .child(content) .on_scroll(|e| { tracing::info!( "scroll delta=({:.1}, {:.1})", e.scroll_delta_x, e.scroll_delta_y, ); }), ) } ``` -------------------------------- ### Add wasm32-unknown-unknown Target Source: https://blinc.rs/docs/web/setup.html Install the wasm32-unknown-unknown target for Rust. This is required for compiling Rust code to WebAssembly. ```rust rustup target add wasm32-unknown-unknown ``` -------------------------------- ### Accessing Theme Variables in Rust Source: https://blinc.rs/docs/core/css-styling.html Example of how to retrieve a CSS variable (theme value) within a Rust application. ```rust #![allow(unused)] fn main() { if let Some(value) = stylesheet.get_variable("brand-color") { println!("Brand color: {}", value); } } ``` -------------------------------- ### Card with Checkbox Options Source: https://blinc.rs/docs/cn/card.html Example of a card containing a header and a content area with checkboxes and labels for user options. ```rust #![allow(unused)] fn main() { card() .child(card_header() .child(card_title("Notifications")) .child(card_description("Configure notification settings"))) .child(card_content() .child( div() .flex_col() .gap(12.0) .child(checkbox().checked(true).child(label("Email notifications"))) .child(checkbox().child(label("Push notifications"))) )) } ``` -------------------------------- ### Stagger Animation Direction Examples Source: https://blinc.rs/docs/animation/motion.html Illustrates different stagger animation directions: forward (default), reverse, and from the center. ```rust #![allow(unused)] fn main() { // Forward (default): 0, 1, 2, 3, 4... StaggerConfig::new(100, preset) // Reverse: 4, 3, 2, 1, 0... StaggerConfig::new(100, preset).reverse() // From center: 2, 1/3, 0/4 (for 5 items) StaggerConfig::new(100, preset).from_center() } ``` -------------------------------- ### Get Animation Values and Progress Source: https://blinc.rs/docs/animation/timelines.html Retrieve the current value of an animation entry, its progress, or the overall timeline progress. ```rust let value = timeline.lock().unwrap().get(entry_id).unwrap_or(0.0); // Get entry progress (0.0 to 1.0) let progress = timeline.lock().unwrap().entry_progress(entry_id); // Get overall timeline progress let total_progress = timeline.lock().unwrap().progress(); ``` -------------------------------- ### Stateful Hover Card Example Source: https://blinc.rs/docs/core/events.html Demonstrates a hover card that changes background color and scale on hover using `stateful`. ```rust #![allow(unused)] fn main() { use blinc_layout::stateful::stateful; fn hover_card() -> impl ElementBuilder { stateful::() .w(200.0) .h(120.0) .rounded(12.0) .on_state(|ctx| { let (bg, scale) = match ctx.state() { ButtonState::Hovered => (Color::rgba(0.2, 0.2, 0.3, 1.0), 1.02), _ => (Color::rgba(0.15, 0.15, 0.2, 1.0), 1.0), }; div().bg(bg).transform(Transform::scale(scale, scale)) }) .child(text("Hover me!").color(Color::WHITE)) } } ```