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

Declarative custom elements for Cesium #10876

Open
angrycat9000 opened this issue Oct 28, 2022 · 6 comments
Open

Declarative custom elements for Cesium #10876

angrycat9000 opened this issue Oct 28, 2022 · 6 comments

Comments

@angrycat9000
Copy link
Contributor

angrycat9000 commented Oct 28, 2022

Overview

Use custom element web components to allow cesium to be used declaratively in HTML.

Currently Cesium is an imperative library that requires writing Javascript code with step by step instructions to set up the view. Many newer UI frameworks (like React, Vue, Svlete) are declarative. They allow the developer to declare what they want to display.

Example of current imperative Javascript code

const viewer = new Cesium.Viewer("cesiumContainer", {
  animation: true,
  homeButton: true,
  navigationHelpButton: false,
  shadows: true,
  shouldAnimate: true,
});

viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
  url:  "../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json"
}));

viewer.entities.add({
    position: position,
    orientation: orientation,
    model: {
      uri: "../SampleData/models/CesiumAir/Cesium_Air.glb",
      minimumPixelSize: 128,
      maximumScale: 20000,
    },
  });

Example of what a declarative custom element interface could look like

<cesium-view shadows animate>
  <cesium-animation-controls></cesium-animation-controls>
  <cesium-navigation-controls hide-help></cesium-navigation-controls>
  <cesium-tileset src= "../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json"></cesium-tileset>. 
  <cesium-model
    src="../SampleData/models/CesiumAir/Cesium_Air.glb"
    minium-pixel-size="128"
    maximum-scale="20000"
  ></cesium-model>
</cesium-view>

Other custom element functionality

Using custom elements would also allow functionality like:

  • automatically resizing the canvas to the containing element using ResizeObserver. This way it just works if the layout changes.
  • Exposing events as native DOM events eg. document.querySelector('cesium-view').addEventListener('selected-entity-changed', ...). Makes it easier to learn for developers already familiar with other HTML DOM events.
  • CSS style isolation

First steps

I think the first steps would be to create a proof of concept cesium-viewer element that mirrors the exposes Viewer interface today. It would not support any sub-elements like the example above (there would still need to be some imperative configuration).

This could be used as a building block to start adding more elements like cesium-tileset.

Long term vision

Longer term I would like to see the viewer element be more modular and extensible for widgets. It provides a generic set of hosting capability for widgets (such as accessing the scene, maybe some basic positioning for widgets). Instead of the current system where the viewer knows about all possible widgets and they all get configured via the viewer object. That puts cesium created widgets on the same level as user created widgets. The cesium created widgets can serve as examples for how to create your own custom widgets.

@kring
Copy link
Member

kring commented Oct 29, 2022

Probably worth taking a look at Resium if you haven't seen it already.

@angrycat9000
Copy link
Contributor Author

Probably worth taking a look at Resium if you haven't seen it already.

Thanks for pointing that out. Yes this would be similar to Resium, however it would use custom elements instead of React. The advantage of custom elements is that they are not tied to any particular framework. So they could be used in React, Angular, Vue, or with plain HTML+JS.

@ggetz
Copy link
Contributor

ggetz commented Nov 8, 2022

Maybe we look at <model-viewer>, a web component for simple display of glTFs, for inspiration.

@rudifa
Copy link
Contributor

rudifa commented Nov 20, 2022

Hi @angrycat9000

(1) Let me ask for some clarifications:

"Use custom element web components to allow cesium to be used declaratively in HTML."

I would interpret this to mean 'use Lit elements', since these appear to be the most advanced form of web components. Is this correct, or would you also consider alternative web component implementations?

Will the proposed declarative API be aimed at the current community of Cesium users, or should it also facilitate the access to Cesium to a yet wider public? How should this impact and inform the new API development?

IMO, the users of the new API should rely on the corresponding API documentation (to be developed), rather than having to dig into the existing Cesium documentation. Would you agree?

Your sketch of the declarative API suggest a progressively increasing degree of modularity. Are there plans to modularize Cesium (break up into smaller subsystems)? How would this impact the new API?

May I suggest that you should draft a guidance document that would define objectives aimed at and trace the directions to follow towards the new declarative API?

(2) Apropos the "First steps" and "proof of concept cesium-viewer element that mirrors the exposed Viewer interface":

How would you define the scope of the Viewer interface? I suppose that it goes beyond the formal list of properties and methods of the Cesium.Viewer object. Is this correct?

Lit elements expose a set of attributes whose values can

  • define the element configuration and appearance when an instance is created
  • trigger the rendering of the element when these values change

The first group could map directly to the properties of the underlying object (the Viewer), while the second group might map to some method calls on the object or on its child objects. Some attributes could serve both purposes.

I think that you could greatly advance the prototyping work if you could draft a list of <cesium-viewer> attributes that you want to see implemented in the early development rounds.

(3) My prototypes

I recently started experimenting with Cesium-in-Lit, and I hit and reported a problem (cesium/issues/10907). In her responses, @ggetz pointed me to this thread.

Meanwhile, helped by my js-mentor @olange I implemented a workaround, and I deployed my prototype on netlify. I just updated it, based on my thinking since I first saw this discussion.

My questions and suggestions above are a byproduct of my prototyping so far. I would greatly appreciate if you could respond with comments, guidance and possibly with a challenge to implement a more substantial prototype.

@rudifa

@angrycat9000
Copy link
Contributor Author

angrycat9000 commented Nov 21, 2022

Thanks for your feedback @rudifa

I would interpret this to mean 'use Lit elements', since these appear to be the most advanced form of web components. Is this correct, or would you also consider alternative web component implementations?

It could be Lit since there is experience using that framework at Cesium. However, it might also make sense to just write it as a vanilla custom element with no framework if most of API would be focused on changing properties of the Cesium viewer object and not writing HTML.

Will the proposed declarative API be aimed at the current community of Cesium users, or should it also facilitate the access to Cesium to a yet wider public? How should this impact and inform the new API development?

It would probably start with the existing names and structures and see if there are areas that could be simplified for declarative rendering. That would avoid having two disjointed APIs but also allowing some freedom to make it easier to write declaratively.

If there are areas you think could be improved on the existing API please let us know.

How would you define the scope of the Viewer interface? I suppose that it goes beyond the formal list of properties and methods of the Cesium.Viewer object. Is this correct?

The first pass would probably be focused on the commonly used properties and might leave out some of the less frequently used properties. I would not expect it to be adding anything that isn't already available.

It would also extend beyond just the Viewer object itself. A large part of this will be declaring the data that is shown in the viewer. That brings in things like tilesets and models. It will probably be a whole set of elements needed to represent this complexity, not just a cesium-viewer element.

I recently started experimenting with Cesium-in-Lit, and I hit and reported a problem

Thank you for reporting that issue. That is great to see others in the community interested in having a declaratively rendered cesium viewer.

@rudifa
Copy link
Contributor

rudifa commented Nov 23, 2022

Hi @angrycat9000

Thank you for the comments and clarifications.

it might also make sense to just write it as a vanilla custom element with no framework

I think that LitElement places an useful layer of abstractions over the HTMLElement, hiding the drudgery and boilerplate code needed to use the HTMLElement API directly, see for example the codelab From Web Component to Lit Element.

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

No branches or pull requests

4 participants