-
Notifications
You must be signed in to change notification settings - Fork 170
ClojureScript
Use quil-cljs Leiningen template to create a project from scratch:
lein new quil-cljs hello-quil
In src directory you have ClojureScript with an example of a sketch.
Processing.js library is used as rendering backend for Quil on ClojureScript. To run sketch run lein compile and then open ./index.html.
If you haven't used ClojureScript before check following links:
- ClojureScript: https://github.com/clojure/clojurescript
- cljsbuild Leiningen plugin: https://github.com/emezeske/lein-cljsbuild
And keep in the mind that ClojureScript code is translated to JavaScript outside of the browser.
We try to keep maximal compatibility between Clojure and ClojureScript versions of Quil, but it's not complete. You can see a list of supported (in ClojureScript version) functions on this page: https://github.com/quil/quil/wiki/List-of-available-functions-in-ClojureScript
The main thing in Quil is defsketch macro. Therefore consider the main differences in this macro between Clojure and ClojureScript versions.
The key point is that we have to assign sketch to a div element on a html page. This div element is specified using id field. This means that ClojureScript sketch has to "know" about the id. Use :host property for that:
(q/defsketch my-sketch-definition
:host "canvas-id"
:draw draw
:size [300 300])somewhere on page:
<div id="canvas-id"></div>If the :host property is not defined then Quil uses sketch name as id. In previous example sketch name was my-sketch-definition, so if we omitted :host property Quil would look for a div with id my-sketch-definition.
Currently you can use the following properties for defsketch macro in ClojureScript:
:host:setup:draw:size-
:renderer(supported:p2dand:p3dmodes,:p2dis default) -
:key-pressed,:key-released,:key-typed -
:mouse-clicked,:mouse-dragged,:mouse-moved,:mouse-pressed,:mouse-released,:mouse-exited,:mouse-entered -
:middlewarewith middlewaresfun-modeandnavigation_3d -
:featureswith one option:no-start. By default sketch started when html page is loaded. But if you set sketch option:no-startthen sketch not initialized when html page loaded.
To execute arbitrary code in sketch environment you can use with-sketch macro.
Code, wrapped in with-sketch, can call any Quil functions. For example:
(defn ^:export clean-sketch []
(q/with-sketch (q/get-sketch-by-id host)
(q/background 255)))with-sketch macro is defined only for ClojureScript Quil code, and might be ported to regular Quil later. It's useful for controlling sketch outside sketch code.
ClojureScript has a few important limitations:
- You can't use
:refer :allor(:use some-ns-name)innsform. Only(:require [some-ns :only [refers-list]])or(:require [some-ns :as ns-alias])are available; - You must use
(:require-macros [some-ns :only [imported-macros-list]])innsfrom; - You can't define macros in cljs files. Macros can be defined only in clj files.
If you have not worked with ClojureScript before carefully read the links at the beginning of the page.
- Create an html page with
divelement with specifiedidfield. - Create a copy of sketch
cljfile withcljsextension. - Add
:include-macros trueto(:require [quil.core :as q]):(:require [quil.core :as q :include-macros true]). - Add
:hostparameter toq/defsketch. - Add ClojureScript to
:dependenciesinproject.clj. - Add CljsBuild plugin to
:pluginsinproject.clj. - Add
leiningen.cljsbuildto:hooksinproject.clj. - Set
:cljsbuildparameter inproject.clj. - Include
processing-1.4.8.jsand ClojureScript outputjsscripts in the html page. - Run
lein compileand open the html page in browser to see your sketch.
ClojureScript 0.0-2261 depends on Clojure 1.6.0, so you can't use older Clojure version, like 1.5.1.
This means that you must use ClojureScript 0.0-2261+ and Clojure 1.6.0+ or ClojureScript 0.0-2234 or less and Clojure 1.5.1 (we don't test Quil for previous versions of Clojure, so it might work or might not).
Note: this is no longer applies for Quil 2.2.5 as all externs and preamble are automatically applied without you need to do anything, just change optimization mode to :advanced.
For quil 2.2.4 and below. Advanced compilation mode drastically reduces size of compiled js by renaming all functions and stripping out unused code. To compile Quil in advanced mode do following:
- use
:optimizations :advanced; - disable pretty printing by specifying:
:pretty-print false; - specify processing.js externs file:
:externs ["externs/processing.js"]; - use minified version of processing.js:
:preamble ["processing.min.js"];
Example:
:cljsbuild
{:builds [{:source-paths ["src"]
:compiler
{:output-to "web/js/main.js"
:externs ["externs/processing.js"]
:preamble ["processing.min.js"]
:optimizations :advanced
:pretty-print false}}]})More info about ClojureScript and advanced mode: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html.
You can create project with Leiningen template and use autostart feature. Look at the example:
HTML page:
<html>
<head>
<title>hello</title>
<script type="text/javascript" src="js/processing-1.4.8.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
<div id="hello"></div>
</body>
</html>Sketch code:
(ns hello.core
(:require [quil.core :as q :include-macros true]))
(defn draw []
(q/background 255)
(q/fill 0)
(q/ellipse 56 46 55 55))
(q/defsketch hello
:draw draw
:host "hello"
:size [300 300])Now run lein compile and open you html page in browser. And sketch automatically starts when html page loaded.
You can use it in the development process or in you fully developed sites.
This method based on :features [:no-start] defsketch option.
Suppose you have the following code:
(ns hello.core
(:require [quil.core :as q :include-macros true]))
(defn draw []
(q/background 255)
(q/fill 0)
(q/ellipse 56 46 55 55))
(q/defsketch hello
:draw draw
:host "hello"
:features [:no-start]
:size [300 300])To run this sketch call (hello.core/hello) from ClojureScript or hello.core.hello() from JavaScript. Look at the following code:
<html>
<head>
<title>hello</title>
<script type="text/javascript" src="js/processing-1.4.8.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
<div id="hello"></div>
<button onclick="hello.core.hello()">Run sketch!</button>
</body>
</html>Sketch starts on button click.
You can use this approach (for example) for embedding sketches to some blog platforms (which allow you to edit raw html of a post).
If you want to have all control over you sketches you should use quil.core/sketch function to create a sketch. Look at the simple example:
(ns hello.core
(:require [quil.core :as q]))
(defn draw []
(q/background 255)
(q/fill 0)
(q/ellipse 56 46 55 55))
(defn hello []
(q/sketch
:draw draw
:host "hello"
:size [300 300]))You can call hello.core.hello from ClojureScript or JavaScript to run the sketch.
quil.core/sketch support all parameters of defsketch. But you must specify :host parameter for quil.core/sketch unlike defsketch macro.
This approach should be used if you want to change the initialization order.