Setup
Begin by cloning the Blockly repo and checking out the rendering-hackathon branch of Blockly. This contains some sample code to get us started.
git clone https://github.com/google/blockly
git checkout rendering-hackathon
Most of the changes we’ll be making will be in the core/renderers/minimalist
directory. The minimalist renderer is the Blockly bare bones renderer with no specific changes added on to it.
- In your choice of browser, open
blockly/tests/playground.html
- In your choice of code editor, open the blockly repo you checked out.
Changing Constants
Let’s start by adjusting some constants, and seeing the results in the playground.
Notches
In core/renderers/minimalist/constants.js
, change the notch size. Here I’ve used a NOTCH_WIDTH of 20 and a NOTCH_HEIGHT of 10, but feel free to try out your own configuration.
Next, let’s try out a few different notch styles.
In the constants.js file, there are a number of makeNotch functions commented out. Each one of these describes how to draw a different style notch. These are just samples and you should feel free to try to create your own notch style. Play with each of these notch styles by uncommenting them one at a time. Use whichever one makes the most sense as a starting point.
Puzzle tab
Next, let’s adjust the puzzle tab style.
Adjust the size of the puzzle tab in constants.js by altering TAB_HEIGHT and TAB_WIDTH. There is also a commented out makePuzzleTab function which describes how to draw a square puzzle tab. Uncomment that to see it in action. This is just a sample and you should feel free to try to create your own puzzle tab.
Note: this is overriding the makePuzzleTab in the common renderer (base class).
Corners
Next, let’s adjust the corner radius.
In constants.js, play around with different configurations for the CORNER_RADIUS value. Here’s what it looks like with a value of 4.
The constants.js file is also a good play to adjust other constants such as:
- SMALL_PADDING: 3, small padding
- MEDIUM_PADDING: 5, medium padding
- LARGE_PADDING: 10, large padding
As an example, here’s a Minecraft style block that I made by using a CORNER_RADIUS of 0, the square notch and the square puzzle tab.
For further extensions, you can also play around with changing the start hat shape or the jagged teeth shape.
Theme
Themes are a way to adjust colors in Blockly. We have a number of built-in themes found under the core/themes directory. You can switch between these themes in the playground using the theme dropdown.
You can find more theming documentation here.
Theme configuration is split into multiple groups:
- Block colors: control the color of blocks by category
- Category colors: control the toolbox category color
- Component colors: controls Blockly UI component colors
Blockly UI component configuration is still a work in progress. For a list of currently supported configuration options, see: https://github.com/google/blockly/issues/3113
- The Material theme is a good starting point for playing around with theme colors.
- If you’re a Star Trek fan, you could use the LCARS UI as inspiration!
Render Info
The RenderInfo object houses all the information we need to complete our rendering. This is where we look at a block’s various properties and components (next, prev, fields, inputs, connections) and populate rows and elements that are then sent over to the drawer to draw.
As a fun way to get started with render info, let’s make a renderer that doesn’t show any label fields. To do that, we’ll override the createRows_ function in our renderer and won’t add any fields that are of type FieldLabel when populating our row.
Start by copying the createRows_ method from renderers/common/info.js and pasting it into our renderer’s RenderInfo object, ie: renderers/minimalist/info.js.
Change the method name from Blockly.blockRendering.RenderInfo.prototype.createRows_ to Blockly.minimalist.RenderInfo.prototype.createRows_. This overrides the createRows_ method in the base class.
In the for loop that iterates through an input’s fields and adds Field measurables to the active row, add an if statement that checks whether the current field is an instance of Blockly.FieldLabel. Only add the field to the row if it’s not.
// All of the fields in an input go on the same row.
for (var j = 0, field; (field = input.fieldRow[j]); j++) {
if (!(field instanceof Blockly.FieldLabel)) {
activeRow.elements.push(
new Blockly.blockRendering.Field(this.constants_, field, input));
}
}
You should end up with blocks that look like this:
You should now have a rough idea of where all the rendering APIs can be found.
Happy Hacking!