Coder Social home page Coder Social logo

Comments (2)

ndreynolds avatar ndreynolds commented on May 18, 2024

Thanks for bringing this up again. I agree that this is an important one to solve. I've had to add a lot of little hacks in my app to work around this.

When I was adding the viewport element, I started to think that the element renderers should be overhauled to return not only a merged canvas with the rendered cells, but also detailed information about what was rendered where. I think gathering and returning that rendering metadata would be the first step in being able to obtain element dimensions within an app.

This might be a tree of rendered elements collected from all the renderers, where each rendered element has:

  • (unique) id
    • Some way of telling any two rendered elements apart.
    • Maybe interesting as a hash of the element's attributes and the window dimensions. We could then use the id for caching purposes.
  • element attributes (defaults merged with given)
    • These could later be the basis for a Query API, where CSS-style attribute selectors could be used to filter the tree.
  • rendered dimensions
    • Coordinates, height and width, margin, padding, etc.
    • Probably worth studying the CSS box model.

I'm not sure about how to model the input and output of the renderers—currently a "canvas". Maybe it makes sense to have the rendering metadata on the canvas. Alternatively, it may be better to introduce a new layer there—e.g., a "scene"—which wraps the canvas and rendering information.

I also wonder how we would get this information within an app. It almost seems paradoxical, because you can't know the height of what's rendered in a render function until it's been already been rendered.

I think there are different ways of getting around that, though. We could render the content twice—once to get the dimensions, and a second time with adjustments based on those dimensions.

For example, in order to set a viewport based on the height of a table inside of it:

def render(model) do
  my_table = table id: "my-table" do
    # ...rows...
  end

  # Render just the table (not currently allowed), and get some sort of "DOM" back.
  canvas, dom = Ratatouille.Renderer.render(Canvas.from_dimensions(model.window), my_table)
  # Use a Query API to find the table in the DOM.
  rendered_table = Ratatouille.DOM.find(dom, "my-table")
  offset_y_max = rendered_table.height

  viewport(offset_y: min(model.offset_y, offset_y_max))  do
    my_table
  end
end

Still a lot to think about. I'm curious if there are more elegant ways of exposing this. Let me know if you have any ideas.

from ratatouille.

linduxed avatar linduxed commented on May 18, 2024

Still a lot to think about.

Indeed. My thoughts when I investigated this last year (and subsequently paused my experimentation with the library) were mostly concerned with the problems tied to losing the clear separation between the steps going from model to rendered views.

You've outlined more things to consider than I could have thought of back in September, and I have not dedicated a longer session to think about these problems since you posted your message (which is also why I haven't gotten around to responding before now).

While I don't have anything new to contribute to the issue, I suspect that these are problems that must have been explored at some point by other communities with similar architectures. I'm just guessing, but Elm seems like a candidate to ask, possibly Scenic as well.

I can't promise a timeline, but I hope to get in touch with someone during the coming months who has worked on similar problems. If I find something, I'll post here again.

from ratatouille.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.