Blockoid is a thin ClojureScript wrapping of the Blockly library, which provides tools for building Scratch-like visual language interfaces. Blockoid exposes only the most basic of Blockly functions; but you can easily access the rest of its rather large API through Javascript interop. Better yet, expose them yourself and make a pull request.
Blockoid allows you to combine the block UI paradigm with a powerful symbol manipulation language, so you can do complex things such as compile a block structure to a textual language, all within a web browser.
Add to dependencies:
[org.parkerici/blockoid "0.0.2"]
In your code, add the require
:
(ns ...
(:require [org.parkerici.blockoid.core :as blockoid]))
This is done by calling the define-workspace
fn which takes the following arguments:
div
: Name of the HTML div element in which to inject Blockly
toolbox-xml
: XML in EDN format. Usually generated by toolbox
.
options
: map of additional options to Blockly՚s inject
method, eg: {:zoom true}
. See https://developers.google.com/blockly/guides/get-started/web#configuration
change-handler
: a fn of one argument (event) that gets called on any changes to the workspace. "
Blockly toolboxes are defined in XML. You can supply the XML directly (in EDN form) or use the toolbox
fn to compile XML from a more compact toolbox representation. See the (example toolbox)[example/src/cljs/org/parkerici/blockoid_example/core.cljs#L30].
[:toolbox <contents>]
: This is the outer element.
[:category <name> <props> <contents>]
: Defines a category. is a map of attributes as defined by Blockly (eg {:colour “blue”}
) .
[:block <name> <props> <subs>]
: Defines a block. is a map of attributes as defined by Blockly. is zero or more :field
or :value
specifications
[:field <name> <value>]
: Defines a value for a named field of a block
[:value <name> <subs>]
: Define an inner block for a named field of the outer block.
[:next <block>]
: Define a block to fit into the next field of the outer block.
[:sep]
: Insert a graphic separator element.
(def demo-toolbox
[:toolbox
[:category "Logic" {:colour "red"}
[:category "if" {}
[:block "controls_if"]
[:category "Boolean" {:colour "%{BKY_LOGIC_HUE}"}
[:block "logic_compare"]
[:block "logic_operation"]
[:block "logic_negate"]
[:block "logic_boolean"]
Blockly allows you to define custom blocks using JSON. The Blockly API for this is define-blocks
, a very thin layer that just translated EDN definitions to JSON and passed them in. See (the Blockly documentation)[https://developers.google.com/blockly/guides/configure/web/custom-blocks] for details on block specifications.
workspace-xml
returns the workspace contents as parsed XML (EDN). An alternative workspace-selected-xml
returns just the structure containing the selected block, if any.
[ sigh, just realized this and toolbox format should be the same...do I want to do that before release? Probably. ]
To respond to user changes to the Blockly workspace, you supply a handler when you call define-workspace
. This gets called with a js event object, and if you are using (re-frame)[https://github.com/Day8/re-frame] (recommended!) it can just dispatch
a re-frame event.
Blocky has an elaborate mechanism for code generation, which Blockoid completely ignores, preferring that you deal with it by having the change event handler call get-workspace-xml
and compact
. The theory is that Blockoid provides a Clojure-native representation of the block structure, allowing the developer to do code generation in Clojure, generally a good choice for complex language transformations. It may be possible to make use of the Blockly generation framework, but I haven՚t tried.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close