Building a simple card layout using Babylon GUI.
Something that I settled on in chapter 1.2 was the idea of having two versions of the card. A compact card that I can show in a grid or list, and a full-size card with all the details for an item. This post covers the full-size card.
I had a bit of a head start on this one. Last winter I worked on a series called A Month of Babylon JS where I set out to build a small project each week. The third week of that series was all about creating some simple 3D data cards. I adapted the code from that project to create the full-size item card layout. I’ll describe the process below.
The item card is made up of a handful of objects in a hierarchy. At the top level is a Box. For this series, the box only serves to add some 3D depth to the cards, but in some future projects this will also be an interactive object (grab, move, resize). Hovering just off the surface of the box is a plane. This is where we draw the UI.
Babylon JS has some powerful GUI features–my favorite of which is the
AdvancedDynamicTexture. With it, we can draw interactive 2D UI objects onto the surface of a mesh (the plane). Everything we draw from here will be added to this texture.
The UI objects needed for the card are: image, title, description, and a button to toggle favorites. I placed all of these in a
StackPanel to group them together in a vertical stack. Each UI object has a defined height that impacts the placement of the objects below. This may not be ideal, but it was good enough for this prototype.
Item Card Hierarchy
- Image (1024px)
- Title (120px)
- Description (440px)
- Button (120px)
I ran into an issue where the text on the card was getting stretched. I posted the issue on the Babylon JS Forum and quickly received an answer that I need to pass in a size value that matches the aspect ratio of the plane when creating the
// The plane is 3 units high and 2 units wide const advancedTexture = AdvancedDynamicTexture.CreateForMesh(plane, 2 * 512, 3.4 * 512);
I’ll expand the function that creates these cards in the days to come. I’ll add some input to the function so I can pass in an item to be rendered and I’ll keep playing with the layout a bit.
Next up: building the compact card and working with collections of items from the API.