Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grid implementation #29

Open
samsamai opened this issue Oct 13, 2020 · 3 comments
Open

Grid implementation #29

samsamai opened this issue Oct 13, 2020 · 3 comments

Comments

@samsamai
Copy link

Thanks for your work on this library, I have been playing around with it and I would like to see it develop further. I was hoping to contribute to it but some guidance would be helpful.

I'm looking to implement a grid, was wondering what your thoughts were regarding how it should be done, should it be another primitive type or should it be described as a window style? Or some other way?

@Michael-F-Bryan
Copy link
Owner

Michael-F-Bryan commented Oct 14, 2020

How I've implemented grids in the past is to have some sort of Grid object which keeps track of things like the current grid spacing and maybe object snap settings.

Then whenever a mouse event comes in and you need to do something (e.g. drag a point around the canvas) you pass the raw mouse location to the Grid and ask what the "effective" mouse location is.

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Point {
    x: f64,
    y: f64,
}

#[derive(Debug, Clone, PartialEq)]
pub struct Snaps {
    grid_spacing: Option<f64>,
}

impl Snaps {
    pub fn effective_location(&self, raw_mouse_location: Point) -> Point {
        match self.grid_spacing {
            Some(spacing) => {
                Point {
                    x: raw_mouse_location.x % spacing,
                    y: raw_mouse_location.y % spacing,
                }
            }
            None => raw_mouse_location,
        }
    }
}

Actually rendering the grid should really be done by the CAD engine as part of its rendering process. I'd probably implement some sort of layering system where a drawing contains a Vec<Box<dyn Layer>> ordered by z-level and you ask each layer to render in turn. Normal layers would draw objects as normal (cull objects outside the viewport, convert from drawing space to canvas space, render to the canvas with normal line/arc/spline drawing algorithms, etc.), but then you have custom logic for things like the grid and background.

This ties in with how users normally organise their drawings (e.g. you might have a layer for dimension lines, a layer for the drawing itself, and a layer for page outline and title boxes), except things like the grid and background would be treated as "system" layers that are inaccessible to users.

@samsamai
Copy link
Author

Thanks for your detailed response @Michael-F-Bryan, I'll start working on this.

@samsamai
Copy link
Author

Hi @Michael-F-Bryan, I have the basic snapping and grid working in this experimental app based on your old demo: https://github.com/samsamai/arcs-wasm-experiment
I ended up making the grid another primitive type as I was just learning about ECS but looking back at it now, it could probably be a resource.
With the snapping, I created a new system which modifies the supplied cursor position to the ECS, this then affects other systems (such as the mover) down stream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants