Liking cljdoc? Tell your friends :D


Lemon Lime makes for delicious sprite(s) in ClojureScript.

cljdoc badge Clojars Project

Table of contents


Lemon Lime supports creating sprites backed by tiny state machines. Sprites are backed by renderers that respond to changes in state.

(require '[lemon.lime :as ll])
(require '[lemon.lime.css :as css])

(def shepherd
 (ll/sprite {:uri           "shepherd-swing.png"
             :height        52
             :width         47
             ::css/renderer {:id "shepherd"}}))

(ll/frames shepherd) ;=> [[0 0] [1 0] [2 0] [3 0] [4 0] [5 0] [6 0] [7 0]]

(ll/reel [0 0] [0 0] shepherd) ;=> [[0 0] [1 0] [2 0] [3 0] [4 0] [5 0] [6 0] [7 0] [0 0]]

(ll/move shepherd [1 0]) ;; transition the sprite to a new frame


The core config for sprites is minimal.

(def config {:uri    "shepherd-swing.png"
             :height 52
             :width  47})

This core config is the pixel dimensions of your sprite and a uri used to uniquely identify the sprite. This uri could be a url to an image, or some other way of pointing to the resources necessary for loading the sprite. It uniquely identifies the sprite and is leveraged by the load phase of renderers.

The core config is extended by renderers in order to support rendering needs:

(def config {:uri           "shepherd-swing.png"
             :height        52
             :width         47
             ::css/renderer {:id "shepherd"}})

It is recommended, but not required, that renderer keys are namespaced in the style of ::ns/renderer. A sprite config could contain multiple renderer configs so they are ready to be used where they are needed.


When a sprite is created via lemon.lime/sprite it is bound to a renderer. A render is any type that implements the lemon.lime.protocols/Renderer protocol.

Renderers handle initial load of sprite resources and setting initial state.

See src/lemon/lime/css.cljs for the default renderer implementation backed by css' background-position.

A render can be given as the second argument to the lemon.lime/sprite function.

(def my-sprite (sprite config (create-css-renderer)))


At it's core, Lemon Lime is a library for managing sprite state. It is used to load spritesheets and transition an individual sprite instance through the frames thereof. To that end, no animation code is actually provided as part of the core library.

The lemon.lime/frames and lemon.lime/reel functions are intended for use within animation loops. The typical workflow would be creating a reel via lemon.lime/reels and then transitioning the sprite's state, relying on the renderer to draw the meaningful changes:

(let [reel (ll/reel [0 0] [0 0] shepherd)
  (doseq [frame reel]
    (ll/move shepherd frame))])

The above doseq is meant to illustrate. A useful animation loop would respect frame duration and not transition through the reel so quickly.

See dev/cljs/user.cljs for a full-fledged animation example backed by core.async.


Frames are articulated as a vector of [x y] coordinates within a spritesheet.

The collection of frames [[0 0] [1 0] [3 0] [4 0]] would reflect a row based spritesheet:


The collection of frames [[0 0] [1 0] [0 1] [1 1]] would reflect a grid based spritesheet:


The frameset is created by considering the sprites dimensions against the spritesheet dimensions. See lemon.lime/create-frames for the implementation used to generate a sprites frame set.


Lemon Lime is developed using a vanilla ClojureScript repl. This plays well with development environments like Calva, or a plain repl.

See the ClojureScript quick start for info on running a repl.

See dev/cljs/user.cljs. This is where development takes place.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close