-
Notifications
You must be signed in to change notification settings - Fork 166
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:p2d
and:p3d
modes,:p2d
is default) -
:key-pressed
,:key-released
,:key-typed
-
:mouse-clicked
,:mouse-dragged
,:mouse-moved
,:mouse-pressed
,:mouse-released
,:mouse-exited
,:mouse-entered
-
:middleware
with middlewaresfun-mode
andnavigation_3d
-
:features
with one option:no-start
. By default sketch started when html page is loaded. But if you set sketch option:no-start
then 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 :all
or(:use some-ns-name)
inns
form. 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]])
inns
from; - 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
div
element with specifiedid
field. - Create a copy of sketch
clj
file withcljs
extension. - Add
:include-macros true
to(:require [quil.core :as q])
:(:require [quil.core :as q :include-macros true])
. - Add
:host
parameter toq/defsketch
. - Add ClojureScript to
:dependencies
inproject.clj
. - Add CljsBuild plugin to
:plugins
inproject.clj
. - Add
leiningen.cljsbuild
to:hooks
inproject.clj
. - Set
:cljsbuild
parameter inproject.clj
. - Include
processing-1.4.8.js
and ClojureScript outputjs
scripts in the html page. - Run
lein compile
and 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.