Displaying Gendl graphics

<-Previous | ^UP^ | Next->

The viewport-html-div

The canonical way to display Gendl geometry on a web page is the viewport-html-div. It is a subclass of base-html-div, so you include it on a page exactly as you would any other page section: define it as a child object and emit (str (the my-viewport div)) somewhere in the page body. No special graphics page mixin is required -- a plain base-html-page hosts graphics just fine, and this supersedes the older graphics-sheet mixins.

The recipe has four ingredients:

  • Mix base-html-page into your page object
  • Add a child object of type viewport-html-div, giving it :display-list-objects (a list of leaf-level geometric objects to draw) and/or :display-list-object-roots (a list of objects whose leaves will all be drawn)
  • Emit the viewport's div in the page body, inside a sized container element
  • Include the viewport-renderers-js-baseline script in additional-header-content, which loads the client-side rendering support

Here is a complete example, displaying the brick wall developed in earlier tutorials:

(in-package :gwl-user)(define-object wall-viewport-page (base-html-page):computed-slots((additional-header-content(string-append(with-lhtml-string () (:script (str (the viewport-renderers-js-baseline))))(call-next-method)))(body (with-lhtml-string ()(:h2 "A Brick Wall")(:div :style "width: 600px; height: 400px; position: relative;"(str (the viewport div)))))):objects((wall :type 'gdl-user::wall)(viewport :type 'viewport-html-div:image-format :svg:display-list-object-roots (list (the wall)))))(publish-gwl-app "/wall-viewport" 'wall-viewport-page)

Image formats

The :image-format input selects the renderer: :svg gives a wireframe vector rendering and :x3dom gives a shaded, mouse-navigable 3D rendering. The slot is settable, so it can also be wired to a form control with :ajax-submit-on-change? to let the user switch formats on a live page.

Multiple viewports on one page

Because each viewport-html-div is just a page section, you may lay out any number of them as children of the same base-html-page. For example, wireframe and shaded views of the same wall, side by side:

(body (with-lhtml-string ()(:h2 "Wireframe and Shaded views")(:div :style "display: flex; gap: 10px;"(:div :style "width: 45vw; height: 60vh; position: relative;"(str (the wireframe-view div)))(:div :style "width: 45vw; height: 60vh; position: relative;"(str (the shaded-view div)))))):objects((wall :type 'gdl-user::wall)(wireframe-view :type 'viewport-html-div:image-format :svg:display-list-object-roots (list (the wall)))(shaded-view :type 'viewport-html-div:image-format :x3dom:display-list-object-roots (list (the wall)))))

A note about Geysr

The Geysr web-based development environment still runs its own, older internal viewport machinery. You are welcome to use Geysr as an application for inspecting and debugging your models, but for graphics on your own web pages, build on viewport-html-div rather than attempting to reuse Geysr internals.