Skip to content

Incorectly scaled coordinates of events compared to webview for transformed elements #596

Description

@Klemen2

In blitz you have to divide pan amount with window scale to achieve the same result as webview so that new elements are added to the transform.
Platform tested: windows 11

Blitz:

blitz.mp4

Webview:

web.mp4
use std::collections::HashMap;

use dioxus_native::prelude::*;
//use dioxus_native::use_window;

pub fn main() {
    dioxus_native::launch(app);
}

const WIDTH: f32 = 100.;
const HEIGHT: f32 = 100.;

const PAN_X: f32 = 200.0;
const PAN_Y: f32 = 200.0;
const ZOOM: f32 = 0.5;

fn app() -> Element {
    let mut data = use_store(Data::default);
    //let window = use_window();

    let onclick = move |evt: Event<MouseData>| {
        let coords = evt.client_coordinates();
        //let scale = window.scale_factor() as f32;

        let x = (coords.x as f32 - PAN_X /*/ scale*/) / ZOOM - WIDTH / 2.;
        let y = (coords.y as f32 - PAN_Y /*/ scale*/) / ZOOM - HEIGHT / 2.;

        data.write().add_element(x, y);
    };

    rsx!(
        style { {CSS} }
        div {
            position: "absolute",
            top: 0,
            left: 0,
            width: "100vw",
            height: "100vh",
            onclick,
            div {
                position: "absolute",
                top: 0,
                left: 0,
                transform_origin: "0 0",
                width: 0,
                height: 0,
                transform: format!("translate({}px, {}px) scale({})", PAN_X, PAN_Y, ZOOM),
                for (id, item) in data.elements().iter() {
                    PositionedItem { id, data: item }
                }
            }
        }
    )
}

#[component]
fn PositionedItem(id: usize, data: Store<PositionedElement>) -> Element {
    rsx!(
        div {
            position: "absolute",
            border: "1px solid black",
            left: format!("{}px", data.x()),
            top: format!("{}px", data.y()),
            width: format!("{}px", WIDTH),
            height: format!("{}px", HEIGHT),
            div { "Placed item {id}" }
        }
    )
}

#[derive(Store, Clone, PartialEq)]
struct PositionedElement {
    x: f32,
    y: f32,
}

#[derive(Store, Default, PartialEq)]
struct Data {
    elements: HashMap<usize, PositionedElement>,
}

impl Data {
    fn add_element(&mut self, x: f32, y: f32) {
        let id = self.elements.len();
        self.elements.insert(id, PositionedElement { x, y });
    }
}

const CSS: &str = r#"
* { box-sizing: border-box; }
html, body, main { width: 100vw; height: 100vh; margin: 0; }
"#;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions