clojure2d.core

Main Clojure2d entry point for Canvas, Window and drawing generatively.

Basic concepts:

  • Image - BufferedImage java object used to store ARGB color information.
  • Canvas - Image which contains graphical context. You draw on it. Similar to processing Graphics object.
  • Window - Window which can display canvas, process events, keeps app/script concept. Similar to Processing sketch with display.
  • Events - Mouse and keyboard events

Protocols:

  • ImageProto - basic Image operations (Image, Canvas, Window and Pixels (see clojure2d.pixels) implement this protocol.
  • Various events protocols. Events and Window implement these:
  • Additionally Window implements PressedProto in case you want to check in draw loop if your mouse or key is pressed.

Image

Image is BufferedImage java object. Image can be read from file using load-image function or saved to file with save. ImageProto provides get-image function to access to Image object directly (if you need) There is no function which creates Image directly (use Canvas instead).

SVG

To load SVG use load-svg which creates internal Batik object. Object can be rendered to Image with transcode-svg.

Canvas

Canvas is an object which is used to draw on it. To create new one call canvas function. Provide width and height and optionally quality hint.

Quality hints are as follows:

  • :low - no antialiasing, speed optimized rendering
  • :mid - antialiasing, speed optimized rendering
  • :high - antialiasing, quality optimized rendering (default)
  • :highest - as :high plus PURE_STROKE hint, which can give strange results in some cases.
  • :retina - retina display with :high quality

Hints can be provided as a set in case if you want to combine :retina with different quality than :high

To draw on Canvas you have to create graphical context. Wrap your code into one of two functions:

  • with-canvas - binding macro (with-canvas [local-canvas canvas-object] ...)
  • with-canvas-> - threading macro (with-canvas-> canvas ...).

Each function in this macro has to accept Canvas as first parameter and return Canvas.

Canvas bound to Window and accessed via callback drawing function (a’ka Processing draw()) has graphical context created automatically.

Retina / High density displays

When quality hint for canvas is set to :retina (to allow proper window / canvas scaling) internal ImageBuffer is doubled in size and drawing is done with scale set to 2.0 by default. When image is retrieved (via get-image, save or during window display), resulting image is an internal ImageBuffer scaled down.

Events

Java2d keyboard and mouse event handlers can be defined as custom multimethods separately for each window. There are following options:

  • Handlers for particular key with dispatch as a vector of window name and key character (eg. ["name" \c])
  • Handler for given key event with dispatch as a vector of window name and key event (eg. ["name" :key-pressed])
  • Handler for mouse event with dispatch as a vector of window name and mouse event (eg. ["name" :mouse-dragged])

Every event handler accepts as parameters:

  • Event object (java KeyEvent or MouseEvent) - access to the fields through defined protocols
  • Global state - state attached to window

Event handler should return new global state.

Window

Window object is responsible for displaying canvas content and processing events. You can also initialize states here.

To create window and display it call show-window. Function accepts several parameters which are described below.

Window itself simulates workflow which is available in Processing/Quil frameworks.

Internals

When window is created following things are done:

  1. Check parameters and create missing values for missed ones.
  2. If :setup function is provided, call it and use returned value as :draw-state
  3. Create JFrame, java.awt.Canvas, pack them, attach event handlers and display
  4. Set global state
  5. Run separated thread which refreshes display with given :fps, if :draw-fn is available it’s called before refreshment.

Additional informations:

  • Display refreshment is done by displaying canvas on JFrame. You can set separate quality hints (same as for canvas) for this process with :hint parameter.
  • When you privide drawing function, it’s called every refreshment. By default graphical context is created every call - which costs time but is safe in case you want to directly access pixels. The second variant which can be used is to create graphical context once at the moment of window creation. This variant can be forced by setting :refresher parameter to :fast
  • In case you don’t want to refresh window content automatically, set :refresher to :onrepaint. This will lower CPU consumption.
  • You can replace canvas attached to window with replace-canvas function.
  • Window itself acts as event object (implements all event protocols)
  • Canvas and window can have different sizes. Display refreshing functions will scale up/down in such case.
  • Events and refreshment are not synchronized. Synchonization can be done explicitely by wrapping functions with locking macro.
  • You can create as many windows as you want.
  • You can check if window is visible or not with window-active? function.
  • If you provide both :draw-state and :setup. Value returned by :setup has a precedence unless is nil or false.

Parameters

Following parameters are used:

  • :canvas - canvas which is displayed on window. Default is 200x200px
  • :window-name - name of the window as a string. Used for event multimathods dispatch.
  • :w - width of the window. Default width of the canvas
  • :h - height of the window. Default height of the canvas
  • :fps - frames per second, defaults to 60
  • :draw-fn - drawing function, called before every display refreshment. Function should accept following four parameters:
    • canvas within graphical context (you don’t need to use with-canvas or with-canvas-> wrappers.
    • window object
    • current frame number as a long value
    • current state
  • :setup - setup function which should accept two parameters and return initial draw state.
    • canvas withing graphical context
    • window object
  • :state - initial global state
  • :draw-state - initial local (drawing) state. If setup is provided, value returned by it will be used instead.
  • :hint - display quality hint. Use it when window and canvas have different sizes
  • :refresher - when create graphical context for draw: :fast for once or :safe for each call (default).

States

There are two states managed by library: global state connected to window and draw state connected to callback drawing function.

Global state

Each window has its own state kept in atom. The main idea is to have data which flow between event calls. Every event function accepts state and should return state data. Initial state can be set with show-window :state parameter To access current state from outside the flow call get-state. You can also mutate the state with set-state!.

Local state for drawing function

When drawing callback is used you can keep state between calls. What is returned by callback is passed as a parameter in next call. Drawing function is not synchronized with events that’s why local state is introduced. You can still access and change global state.

You can init state from show-window with :draw-state or :setup parameters.

How to draw

There are plenty of functions which you can use to draw on canvas. They can be grouped to:

All operate on canvas and return canvas as a result. Obviously canvas is mutated.

Session

Session is a datetime with its hash kept globally in vector. To access current session names call session-name.

Following functions rely on session:

  • next-filename - generate unique filename based on session
  • log - save any information to the file under name based on session. See log-name.

Session is created automatically when needed. Session management functions are:

Utilities

Additional utility functions

  • date and time functions
  • to-hex formatter

Categories

Other vars: ->Canvas ->SessionType ->Window ->WithExceptionT arc-shape bezier-shape bounding-box contains-point? contains-rectangle? crect-shape curve-shape double-array-2d ellipse-shape flat-hex-shape flush-graphics grid-cell-shape int-array-2d intersects-rectangle? load-bytes load-url-image long-array-2d make-counter make-graphics map->Canvas map->SessionType map->Window path-bezier-shape path-def->shape path-shape pointy-hex-shape prect-shape quad-shape rarc-shape rect-shape shape->path-def to-hex triangle-shape

Constants

Code snippets

Process image with function f and save.

(defn process-image-snippet
  [f params & opts]
  (let [img (load-image "docs/cockatoo.jpg")
        unique-name (str "images/core/" (first opts) ".jpg")]
    (binding [*jpeg-image-quality* 0.7]
      (save (f img) (str "docs/" unique-name)))
    (str "../" unique-name)))

Draw axes on reoriented canvas

(defn draw-on-oriented-canvas
  [f params & opts]
  (let [canvas (canvas 400 200)
        unique-name (str "images/core/" (first opts) ".jpg")]
    (with-oriented-canvas-> f
                            canvas
                            (set-background 3162730)
                            (set-color :white)
                            (line 5 5 150 5)
                            (line 5 5 5 100)
                            (line 150 5 145 10)
                            (line 5 100 10 95)
                            (line 150 5 145 0)
                            (line 5 100 0 95)
                            (text "X" 150 20)
                            (text "Y" 15 100)
                            (text "warning: text is reoriented" 20 40))
    (binding [*jpeg-image-quality* 0.85]
      (save canvas (str "docs/" unique-name)))
    (str "../" unique-name)))

Draw something on canvas and save.

(defn drawing-snippet
  [f params & opts]
  (let [canvas (canvas 200 200)
        unique-name (str "images/core/" (first opts) ".jpg")]
    (with-canvas-> canvas
                   (set-background 3162730)
                   (set-color :white)
                   (f))
    (binding [*jpeg-image-quality* 0.85]
      (save canvas (str "docs/" unique-name)))
    (str "../" unique-name)))

*jpeg-image-quality*

dynamic

Default quality of saved jpg (values: 0.0 (lowest) - 1.0 (highest)

Examples

Value

*jpeg-image-quality*
;;=> 0.97

*log-to-file*

dynamic

Should log save to file under log-name. Print to terminal if false (default).

alt-down?

(alt-down? e)

ALT key state as boolean.

alt-gr-down?

(alt-gr-down? e)

ALT-GR key state as boolean.

arc

(arc canvas x y w h start extent type stroke?)(arc canvas x y w h start extent type)(arc canvas x y w h start extent)(arc canvas [x y] w h start extent)

Draw arc with middle at (x,y) position with width w and height h.

Starting angle start and extent are in radians. Direction is clockwise.

Type is one of the:

  • :open - default
  • :pie
  • :chord

Examples

Arcs

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-color :white)
                       (arc 60 60 90 90 m/PI m/HALF_PI)
                       (arc 70 70 90 90 m/PI m/HALF_PI :chord)
                       (arc 90 90 90 90 m/PI m/HALF_PI :pie)
                       (set-color :gray)
                       (arc 130 130 90 90 m/PI m/HALF_PI :open false)
                       (arc 150 150 90 90 m/PI m/HALF_PI :chord false)
                       (arc 170 170 90 90 m/PI m/HALF_PI :pie false)))
                 ...)

arc-shape

(arc-shape a x y w h start extent type)(arc-shape x y w h start extent type)(arc-shape x y w h start extent)(arc-shape [x y] w h start extent)

available-cores

const

;;=> 16

How much processor cores are in system. Constant is machine dependant.

available-tasks

const

;;=> 24

How much intensive tasks can we run. Which is 150% of available cores. Constant is machine dependant.

awt-xor-mode

(awt-xor-mode canvas c)

Set XOR graphics mode with java.awt.Color.

To revert call paint-mode.

Examples

Set Xor Mode with java.awt.Color.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (awt-xor-mode java.awt.Color/BLACK)
                       (rect 50 50 100 100)
                       (rect 70 70 60 60)))
                 ...)

bezier

(bezier canvas x1 y1 x2 y2 x3 y3 x4 y4 stroke?)(bezier canvas x1 y1 x2 y2 x3 y3 x4 y4)(bezier canvas [x1 y1] [x2 y2] [x3 y3] [x4 y4])

Draw bezier curve with 4 sets of coordinates.

Examples

Bezier curve

(drawing-snippet (fn [canvas]
                   (bezier canvas 20 20 180 20 180 180 20 180 false)
                   (set-color canvas :black)
                   (bezier canvas 20 180 20 20 180 20 180 180))
                 ...)

bezier-shape

(bezier-shape x1 y1 x2 y2 x3 y3 x4 y4)(bezier-shape [x1 y1] [x2 y2] [x3 y3] [x4 y4])

black-canvas

(black-canvas & r)

Create canvas with black, opaque background.

bounding-box

(bounding-box shape)

Returns [x,y,width,height] of shape’s bounding box.

canvas

(canvas width height hints font)(canvas width height)(canvas width height hints)

Create and return Canvas with width, height and optionally quality hints and font (name or Font object).

Default hint is :high. Possible options are: :low, :mid, :high, :highest and :retina. When :retina is selected, rendering hint is set to :high. To select other rendering hint you can provide a set, eg. #{:low :retina}.

When :retina is set, created canvas is doubled and transform matrix is set for scaling 2.0

Default font is system one.

Canvas is an object which keeps everything needed to draw Java2d primitives on it. As a drawing buffer BufferedImage is used. To draw on Canvas directly wrap your functions with with-canvas or with-canvas-> macros to create graphical context.

Canvas is transparent by default. See also black-canvas.

Be aware that drawing on Canvas is single threaded.

Font you set while creating canvas will be default font. You can set another font in the code with set-font and set-font-attributes functions. However these set font temporary.

Examples

Canvas is the record.

(canvas 20 30 :low)
;;=> #clojure2d.core.Canvas
;;=>  {:arc-obj
;;=>   #object[java.awt.geom.Arc2D$Double 0xfaba0e3 "java.awt.geom.Arc2D$Double@0"],
;;=>   :buffer
;;=>   #object[java.awt.image.BufferedImage 0x74355b19 "BufferedImage@74355b19: type = 2 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000 IntegerInterleavedRaster: width = 20 height = 30 #Bands = 4 xOff = 0 yOff = 0 dataOffset[0] 0"],
;;=>   :ellipse-obj
;;=>   #object[java.awt.geom.Ellipse2D$Double 0xad86bb5 "java.awt.geom.Ellipse2D$Double@0"],
;;=>   :font nil,
;;=>   :graphics nil,
;;=>   :h 30,
;;=>   :hints
;;=>   [[#object[sun.awt.SunHints$Key 0x685f49f2 "Global antialiasing enable key"]
;;=>     #object[sun.awt.SunHints$Value 0x450b1fbb "Nonantialiased rendering mode"]]
;;=>    [#object[sun.awt.SunHints$Key 0xcf5e973 "Image interpolation method key"]
;;=>     #object[sun.awt.SunHints$Value 0x78f8a5d0 "Nearest Neighbor image interpolation mode"]]
;;=>    [#object[sun.awt.SunHints$Key 0x780862bc "Alpha blending interpolation method key"]
;;=>     #object[sun.awt.SunHints$Value 0x3134fcb9 "Fastest alpha blending methods"]]
;;=>    [#object[sun.awt.SunHints$Key 0x5fc405a8 "Color rendering quality key"]
;;=>     #object[sun.awt.SunHints$Value 0x4d79098a "Fastest color rendering mode"]]
;;=>    [#object[sun.awt.SunHints$Key 0x46a88033 "Global rendering quality key"]
;;=>     #object[sun.awt.SunHints$Value 0x50123159 "Fastest rendering methods"]]
;;=>    [#object[sun.awt.SunHints$Key 0x1cdc9126 "Fractional metrics enable key"]
;;=>     #object[sun.awt.SunHints$Value 0x6df9d8ae "Integer text metrics mode"]]
;;=>    [#object[sun.awt.SunHints$Key 0x75cf2270 "Text-specific antialiasing enable key"]
;;=>     #object[sun.awt.SunHints$Value 0x67e36a47 "Nonantialiased text mode"]]],
;;=>   :line-obj
;;=>   #object[java.awt.geom.Line2D$Double 0x7b3e209c "java.awt.geom.Line2D$Double@7b3e209c"],
;;=>   :rect-obj
;;=>   #object[java.awt.geom.Rectangle2D$Double 0x33283784 "java.awt.geom.Rectangle2D$Double[x=0.0,y=0.0,w=0.0,h=0.0]"],
;;=>   :retina? false,
;;=>   :transform-stack nil,
;;=>   :w 20}

Check ImageProto on canvas.

(width (canvas 10 20))
;;=> 10
(height (canvas 10 20))
;;=> 20
(get-image (canvas 5 6))
;;=> BufferedImage@5a132dfa: type = 2 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000 IntegerInterleavedRaster: width = 5 height = 6 #Bands = 4 xOff = 0 yOff = 0 dataOffset[0] 0
(width (resize (canvas 1 2) 15 15))
;;=> 15
(height (subimage (canvas 10 10) 5 5 2 2))
;;=> 2

char-width

(char-width canvas chr)

Returns font width from metrics. Should be called within graphical context.

Examples

Width of some chars.

(with-canvas [c (canvas 10 10)] [(char-width c \W) (char-width c \a)])
;;=> [12 7]

clip

(clip canvas x y w h)(clip canvas shape)

Clip drawing to specified rectangle or shape.

See also reset-clip.

Examples

Set clip region.

(process-image-snippet (fn [img]
                         (with-canvas-> (canvas 150 150)
                                        (clip 20 20 100 100)
                                        (image img 0 0)))
                       ...)

close-session

(close-session)

Close session via agent

Examples

Usage

(session-name)
;;=> ["20221021141728" "FA7A1788"]
(close-session)
;;=> nil
(session-name)
;;=> ["20221021141756" "FA7A85B4"]

close-window

(close-window window)

Close window programmatically

contains-point?

(contains-point? shape x y)(contains-point? shape point)

Returns true if given point is inside a shape.

contains-rectangle?

(contains-rectangle? shape x y w h)(contains-rectangle? shape [x y w h])

Returns true if given rectangle is inside a shape.

control-down?

(control-down? e)

CONTROL key state as boolean.

convolution-matrices

Java ConvolveOp kernels. See convolve.

Examples

List of kernels

(keys convolution-matrices)
;;=> (:sobel-y :gradient-x :gaussian-blur-3
;;=>           :sharpen :gaussian-blur-5
;;=>           :edges-2 :gradient-y
;;=>           :edges-3 :unsharp
;;=>           :edges-4 :emboss
;;=>           :box-blur :shadow
;;=>           :sobel-x :edges-1)

convolve

(convolve i kernel)

Convolve with Java ConvolveOp.

Kernel can be predefined as keywords or sequence of numbers (row-wise).

See convolution-matrices for kernel names.

Examples

Convolve image with sobel-y kernel.

(process-image-snippet (fn [img] (convolve img :sobel-y)) ...)

Convolve image with gradient-x kernel.

(process-image-snippet (fn [img] (convolve img :gradient-x)) ...)

Convolve image with gaussian-blur-3 kernel.

(process-image-snippet (fn [img] (convolve img :gaussian-blur-3)) ...)

Convolve image with sharpen kernel.

(process-image-snippet (fn [img] (convolve img :sharpen)) ...)

Convolve image with gaussian-blur-5 kernel.

(process-image-snippet (fn [img] (convolve img :gaussian-blur-5)) ...)

Convolve image with edges-2 kernel.

(process-image-snippet (fn [img] (convolve img :edges-2)) ...)

Convolve image with gradient-y kernel.

(process-image-snippet (fn [img] (convolve img :gradient-y)) ...)

Convolve image with edges-3 kernel.

(process-image-snippet (fn [img] (convolve img :edges-3)) ...)

Convolve image with unsharp kernel.

(process-image-snippet (fn [img] (convolve img :unsharp)) ...)

Convolve image with edges-4 kernel.

(process-image-snippet (fn [img] (convolve img :edges-4)) ...)

Convolve image with emboss kernel.

(process-image-snippet (fn [img] (convolve img :emboss)) ...)

Convolve image with box-blur kernel.

(process-image-snippet (fn [img] (convolve img :box-blur)) ...)

Convolve image with shadow kernel.

(process-image-snippet (fn [img] (convolve img :shadow)) ...)

Convolve image with sobel-x kernel.

(process-image-snippet (fn [img] (convolve img :sobel-x)) ...)

Convolve image with edges-1 kernel.

(process-image-snippet (fn [img] (convolve img :edges-1)) ...)

crect

(crect canvas x y w h stroke?)(crect canvas x y w h)(crect canvas [x y] w h)

Centered version of rect.

Examples

Two squares, regular and centered.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-color :white 160)
                       (rect 50 50 100 100)
                       (crect 50 50 60 60)))
                 ...)

crect-shape

(crect-shape r x y w h)(crect-shape x y w h)(crect-shape [x y] w h)

curve

(curve canvas x1 y1 x2 y2 x3 y3 stroke?)(curve canvas x1 y1 x2 y2 x3 y3)(curve canvas [x1 y1] [x2 y2] [x3 y3])

Draw quadratic curve with 3 sets of coordinates.

Examples

Quadratic curve

(drawing-snippet (fn [canvas]
                   (curve canvas 20 20 180 20 180 180 false)
                   (set-color canvas :black)
                   (curve canvas 20 180 20 20 180 20))
                 ...)

curve-shape

(curve-shape x1 y1 x2 y2 x3 y3)(curve-shape [x1 y1] [x2 y2] [x3 y3])

datetime

(datetime type-of-array)(datetime)

Date time values in the array. Optional parameter :vector or :hashmap (default) to indicate what to return.

Examples

Current value

(datetime)
;;=> {:day 21,
;;=>  :hour 14,
;;=>  :millis 1666354676803,
;;=>  :minute 17,
;;=>  :month 10,
;;=>  :nanos 414308451396778,
;;=>  :sec 56,
;;=>  :second 56,
;;=>  :year 2022}
(datetime :vector)
;;=> [2022 10 21 14 17 56 1666354676803 414308451493305]

day

(day)

Current day

Examples

Current value

(day)
;;=> 21

double-array-2d

(double-array-2d sizex sizey)

Create 2d int array getter and setter methods. Array is mutable!

ellipse

(ellipse canvas x y w h stroke?)(ellipse canvas x y w h)(ellipse canvas [x y] w h)

Draw ellipse with middle at (x,y) position with width w and height h.

Examples

A couple of ellipses.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-color :white 200)
                       (ellipse 100 100 50 150)
                       (ellipse 100 100 150 50 true)
                       (ellipse 100 100 20 20)
                       (set-color :black 200)
                       (ellipse 100 100 20 20 true)))
                 ...)

ellipse-shape

(ellipse-shape e x y w h)(ellipse-shape x y w h)(ellipse-shape [x y] w h)

ensure-session

(ensure-session)

Ensure that session is active (create one if not)

file-extension

(file-extension filename)

Extract extension from filename.

  • Input: image filename
  • Returns extension (without dot)

Examples

Usage

(file-extension "image.png")
;;=> png
(file-extension "no_extension")
;;=> nil
(file-extension "with.path/file.doc")
;;=> doc

filled-with-stroke

macro

(filled-with-stroke canvas color-filled color-stroke primitive-fn & attrs)

Draw primitive filled and with stroke.

Provide two colors, one for fill (color-filled), second for stroke (color-stroke). primitive-fn is a primitive function and attrs are function parameters. Do not provide.

One note: current color is replaced with color-stroke.

Examples

Draw two primitives

(drawing-snippet
 (fn [canvas]
   (-> canvas
       (filled-with-stroke :maroon :black crect 100 100 180 180)
       (filled-with-stroke 3359999 :white ellipse 100 100 20 100)))
 ...)

flat-hex

(flat-hex canvas x y size stroke?)(flat-hex canvas x y size)(flat-hex canvas [x y] size)

Draw flat topped hex.

Examples

Flat topped hexagon

(drawing-snippet (fn [canvas]
                   (flat-hex canvas 100 100 20)
                   (flat-hex canvas 100 100 90 true))
                 ...)

flat-hex-shape

(flat-hex-shape x y size)(flat-hex-shape [x y] size)

flip-x

(flip-x canvas)

Flip canvas over x axis

Examples

Flip around vertical axis

(process-image-snippet
 (fn [img] (with-canvas-> (canvas 150 150) (flip-x) (image img -150 0)))
 ...)

flip-y

(flip-y canvas)

Flip canvas over y axis

Examples

Flip around horizontal axis

(process-image-snippet
 (fn [img] (with-canvas-> (canvas 150 150) (flip-y) (image img 0 -150)))
 ...)

flush-graphics

(flush-graphics canvas)

Dispose current Graphics2D

Do not use directly. Call with-canvas-> or with-canvas macros.

font-ascent

(font-ascent canvas)

Returns font width from metrics. Should be called within context.

Examples

Ascent of current font.

(with-canvas-> (canvas 10 10) (font-ascent))
;;=> 12

font-height

(font-height canvas)

Returns font width from metrics. Should be called within context.

Examples

Height of current font.

(with-canvas-> (canvas 10 10) (font-height))
;;=> 15

fonts-list

List of all available font names.

Examples

First five availabe fonts

(take 5 fonts-list)
;;=> ("3270Medium Nerd Font"
;;=>  "3270Medium Nerd Font Mono"
;;=>  "3270Medium NF"
;;=>  "3270Narrow Nerd Font"
;;=>  "3270Narrow Nerd Font Mono")

get-canvas

(get-canvas window)

Returns canvas bound to window.

get-image

(get-image i)

Return BufferedImage

get-state

(get-state window)

Get state from window

gradient-mode

(gradient-mode canvas x1 y1 color1 x2 y2 color2)

Set paint mode to gradient.

To revert call paint-mode

Examples

Set some gradient and fill

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (gradient-mode 20 20 :maroon 180 180 :black)
                       (ellipse 100 100 190 190)))
                 ...)

grid-cell

(grid-cell canvas grid x y stroke?)(grid-cell canvas grid x y)(grid-cell canvas grid x y scale stroke?)

Draw grid cell for given grid.

Examples

Draw on square grid

(drawing-snippet (fn [canvas]
                   (let [g (grid/grid :square 15)]
                     (dotimes [_ 100]
                       (let [x (r/drand 200)
                             y (r/drand 200)]
                         (filled-with-stroke canvas
                                             (c/color :white 100)
                                             :maroon
                                             grid-cell
                                             g
                                             x
                                             y)))))
                 ...)

Draw on shifted-square grid

(drawing-snippet (fn [canvas]
                   (let [g (grid/grid :shifted-square 15)]
                     (dotimes [_ 100]
                       (let [x (r/drand 200)
                             y (r/drand 200)]
                         (filled-with-stroke canvas
                                             (c/color :white 100)
                                             :maroon
                                             grid-cell
                                             g
                                             x
                                             y)))))
                 ...)

Draw on rhomboidal grid

(drawing-snippet (fn [canvas]
                   (let [g (grid/grid :rhombus 15)]
                     (dotimes [_ 100]
                       (let [x (r/drand 200)
                             y (r/drand 200)]
                         (filled-with-stroke canvas
                                             (c/color :white 100)
                                             :maroon
                                             grid-cell
                                             g
                                             x
                                             y)))))
                 ...)

Draw on triangular grid

(drawing-snippet (fn [canvas]
                   (let [g (grid/grid :triangle 15)]
                     (dotimes [_ 100]
                       (let [x (r/drand 200)
                             y (r/drand 200)]
                         (filled-with-stroke canvas
                                             (c/color :white 100)
                                             :maroon
                                             grid-cell
                                             g
                                             x
                                             y)))))
                 ...)

Draw on flat topped hexagonal grid

(drawing-snippet (fn [canvas]
                   (let [g (grid/grid :flat-hex 15)]
                     (dotimes [_ 100]
                       (let [x (r/drand 200)
                             y (r/drand 200)]
                         (filled-with-stroke canvas
                                             (c/color :white 100)
                                             :maroon
                                             grid-cell
                                             g
                                             x
                                             y)))))
                 ...)

Draw on pointy topped hexagonal grid

(drawing-snippet (fn [canvas]
                   (let [g (grid/grid :pointy-hex 15)]
                     (dotimes [_ 100]
                       (let [x (r/drand 200)
                             y (r/drand 200)]
                         (filled-with-stroke canvas
                                             (c/color :white 100)
                                             :maroon
                                             grid-cell
                                             g
                                             x
                                             y)))))
                 ...)

Draw on hexagonal grid with random size

(drawing-snippet (fn [canvas]
                   (let [g (grid/grid :flat-hex 15)]
                     (dotimes [_ 100]
                       (let [x (r/drand 200)
                             y (r/drand 200)
                             s (r/drand 0.1 1.0)]
                         (filled-with-stroke canvas
                                             (c/color :white 100)
                                             :maroon
                                             grid-cell
                                             g
                                             x
                                             y
                                             s)))))
                 ...)

grid-cell-shape

(grid-cell-shape grid x y)(grid-cell-shape grid x y scale)

height

(height i)

height of the image.

Examples

Height of the image

(height (load-image "docs/cockatoo.jpg"))
;;=> 150

hour

(hour)

Current hour

Examples

Current value

(hour)
;;=> 14

image

(image canvas img x y w h)(image canvas img)(image canvas img x y)

Draw an image.

You can specify position and size of the image. Default it’s placed on whole canvas.

Examples

Draw image at given position.

(drawing-snippet (fn [canvas]
                   (let [img (load-image "docs/cockatoo.jpg")]
                     (doseq [x (range 0 80 10)]
                       (image canvas img x x (- 200 x x) (- 200 x x)))))
                 ...)

img-reader-formats

Supported readable image formats. Machine/configuration dependant.

Examples

Set of readable image formats

img-reader-formats
;;=> #{"bmp" "gif" "jpeg" "jpg" "png" "tif" "tiff" "wbmp"}

img-writer-formats

Supported writable image formats. Machine/configuration dependant.

Examples

Set of writable image formats

img-writer-formats
;;=> #{"bmp" "gif" "jpeg" "jpg" "png" "tif" "tiff" "wbmp"}

int-array-2d

(int-array-2d sizex sizey)

Create 2d int array getter and setter methods. Array is mutable!

intersects-rectangle?

(intersects-rectangle? shape x y w h)(intersects-rectangle? shape [x y w h])

Returns true if given rectangle is inside a shape.

inv-transform

(inv-transform canvas x y)(inv-transform canvas [x y])

Inverse transform of given point or coordinates with current transformation. See transform.

Examples

Inverse transform of point using current transformation.

(with-canvas [c (canvas 100 100)]
             (translate c 50 50)
             (rotate c m/HALF_PI)
             (inv-transform c 40 60))
;;=> [10.0 10.0]

key-char

(key-char e)

Key as char.

key-code

(key-code e)

Keycode mapped to keyword. See java.awt.event.KeyEvent documentation. Eg. VK_LEFT is mapped to :left.

key-event

multimethod

Called on key event

  • Dispatch: vector of window name and key event. See key-event-map.
  • Params: key event and current state.

Should return state.

(defmethod key-event ["My window name" :key-pressed] [event state]
  ;; do something when 'up' is typed
  (when (= :up (key-code event)) (do-something))
  state)

key-event-map

Map of supported key events

Examples

List of key events

(vals key-event-map)
;;=> (:key-pressed :key-released :key-typed)

key-pressed

multimethod

Called when key is pressed.

  • Dispatch: vector of window name and key char
  • Params: key event and current state.

Should return state.

(defmethod key-pressed ["My window name" \c] [event state]
  ;; do something when 'c' is pressed
  (assoc state :some (calculate-something state)))

key-pressed?

(key-pressed? w)

Any key pressed? (boolean)

key-raw

(key-raw e)

Raw value for pressed key (as integer).

key-released

multimethod

Called when key is released.

  • Dispatch: vector of window name and key char
  • Params: key event and current state.

Should return state.

(defmethod key-released ["My window name" \c] [event state]
  ;; do something after 'c' is released
  (assoc state :some (calculate-something state)))

key-typed

multimethod

Called when key is typed (pressed and released).

  • Dispatch: vector of window name and key char
  • Params: key event and current state.

Should return state.

(defmethod key-typed ["My window name" \c] [event state]
  ;; do something when 'c' is typed
  (assoc state :some (calculate-something state)))

line

(line canvas x1 y1 x2 y2)(line canvas vect1 vect2)

Draw line from point (x1,y1) to (x2,y2)

Examples

Draw some lines

(drawing-snippet (fn [canvas]
                   (doseq [x (range 10 190 10)]
                     (line canvas x 10 (- 190 x) 190)))
                 ...)

load-bytes

(load-bytes file-or-url)

Load file or http and return byte array.

Examples

Load image file to byte array

(load-bytes "docs/cockatoo.jpg")
;;=> [B@991c667
(second (load-bytes "docs/cockatoo.jpg"))
;;=> -40

load-font

(load-font font-file-or-url)

Load font from file or url. Only TrueType and OpenTrueType fonts are supported.

load-image

(load-image filename-or-url)

Load Image from file.

  • Input: Image filename with absolute or relative path (relative to your project folder) or url.
  • Returns BufferedImage object or nil when Image can’t be loaded.

For supported formats check img-reader-formats.

load-svg

(load-svg filename-or-url)

Load image into Batik Document. See transcode-svg.

Examples

Load SVG into Batik object

(load-svg "docs/takkun.svg")
;;=> org.apache.batik.transcoder.TranscoderInput@5a51b1b3

load-url-image

(load-url-image url)

Load image from given URL, see load-image.

log

(log message)

Log message to file or console

Examples

Example usage

(session-name)
;;=> ["20221021141756" "FA7A85B4"]
(binding [*log-to-file* true]
  (log "Log information to file under session"))
;;=> #clojure2d.core.SessionType
;;=>  {:counter #,
;;=>   :logger
;;=>   #object[java.io.BufferedWriter 0x2a63b41 "java.io.BufferedWriter@2a63b41"],
;;=>   :name ["20221021141756" "FA7A85B4"]}
(Thread/sleep 1000)
;;=> nil
(slurp (log-name))
;;=> Session id: FA7A85B4
;;=> 
;;=> 2022-10-21 14:17:56: Log information to file under session

log-name

(log-name)

Returns log file name with path.

Examples

Usage

(log-name)
;;=> log/20221021141728.log

long-array-2d

(long-array-2d sizex sizey)

Create 2d int array getter and setter methods. Array is mutable!

make-counter

(make-counter v)(make-counter)

Create counter function, each call returns next number.

Examples

Usage

(let [cnt (make-counter)] (repeatedly 5 cnt))
;;=> (0 1 2 3 4)
(let [cnt (make-counter 100)] (repeatedly 5 cnt))
;;=> (100 101 102 103 104)

make-graphics

(make-graphics canvas)

Create new Graphics2D object and set rendering hints.

Do not use directly. Call with-canvas-> or with-canvas macros.

make-session

(make-session)

Create session via agent

Examples

Usage

(make-session)
;;=> ["20221021141757" "FA7A89E1"]
(Thread/sleep 2000)
;;=> nil
(make-session)
;;=> ["20221021141759" "FA7A91B1"]

meta-down?

(meta-down? e)

META key state as boolean.

millis

(millis)

Milliseconds from epoch

Examples

Current value

(millis)
;;=> 1666354648375

minute

(minute)

Current minute

Examples

Current value

(minute)
;;=> 17

month

(month)

Current month

Examples

Current value

(month)
;;=> 10

mouse-button

(mouse-button m)

Get mouse pressed button status: :left :right :center or :none

mouse-event

multimethod

Called on mouse event

  • Dispatch: vector of window name and mouse event. See mouse-event-map.
  • Params: key event and current state.

Should return state.

(defmethod mouse-event ["My window name" :mouse-pressed] [event state]
  ;; do something when button is pressed
  (do-something)
  state)

mouse-event-map

Map of supported mouse events

Examples

List of mouse events

(vals mouse-event-map)
;;=> (:mouse-clicked :mouse-dragged :mouse-pressed
;;=>                 :mouse-released :mouse-moved)

mouse-in-window?

(mouse-in-window? window)

Check if mouse is inside window.

mouse-pos

(mouse-pos m)

Mouse position as Vec2 type. 0,0 - top left, -1,-1 outside window.

mouse-pressed?

(mouse-pressed? w)

Any mouse button pressed? (boolean)

mouse-x

(mouse-x m)

Mouse horizontal position within window. 0 - left side. -1 outside window.

mouse-y

(mouse-y m)

Mouse vertical position within window. 0 - left side. -1 outside window.

nanos

(nanos)

JVM running time in nanoseconds

Examples

Current value

(nanos)
;;=> 414280088334082

next-filename

(next-filename prefix)(next-filename prefix suffix)

Create next unique filename based on session

Examples

Usage

(next-filename "folder/name/")
;;=> folder/name/FA7A91B1_000000
(next-filename "folder/name/")
;;=> folder/name/FA7A91B1_000001
(next-filename "folder/name/" ".jpg")
;;=> folder/name/FA7A91B1_000002.jpg
(close-session)
;;=> nil
(next-filename "folder/name/")
;;=> folder/name/FA7A91BD_000000
(next-filename "folder/name/")
;;=> folder/name/FA7A91BD_000001
(next-filename "folder/name/" ".jpg")
;;=> folder/name/FA7A91BD_000002.jpg

orient-canvas

multimethod

Place origin into one of four window corners and reorient axes.

  • - as suffix - means default orientation (y-axis reversed)
  • + as suffix - means usual (mathematical) orientation (y-axis not reversed).

Examples

top-left-, default

(draw-on-oriented-canvas :top-left- ...)

top-left+

(draw-on-oriented-canvas :top-left+ ...)

top-right-

(draw-on-oriented-canvas :top-right- ...)

top-right+

(draw-on-oriented-canvas :top-right+ ...)

bottom-left-

(draw-on-oriented-canvas :bottom-left- ...)

bottom-left+

(draw-on-oriented-canvas :bottom-left+ ...)

bottom-right-

(draw-on-oriented-canvas :bottom-right- ...)

bottom-right+

(draw-on-oriented-canvas :bottom-right+ ...)

orientations-list

List of orientations

Examples

List of orientations

orientations-list
;;=> (:bottom-left+ :bottom-left-
;;=>                :bottom-right+ :bottom-right-
;;=>                :top-left+ :top-left-
;;=>                :top-right+ :top-right-)

paint-mode

(paint-mode canvas)

Set normal paint mode.

This is default mode.

See gradient-mode or xor-mode for other types.

path

(path canvas vs close? stroke?)(path canvas vs close?)(path canvas vs)

Draw path from lines.

Input: list of points as vectors, close? - close path or not (default: false), stroke? - draw lines or filled shape (default true - lines).

See also path-bezier.

Examples

Path

(drawing-snippet
 (fn [canvas]
   (set-color canvas :white 190)
   (translate canvas 100 100)
   (let [s (for [a (range 0 65 1.3)]
             (v/vec2 (* (+ a 25) (m/cos a)) (* (+ a 25) (m/sin a))))]
     (path canvas s)))
 ...)

path-bezier

(path-bezier canvas vs close? stroke?)(path-bezier canvas vs close?)(path-bezier canvas vs)

Draw path from quad curves.

Input: list of points as vectors, close? - close path or not (default: false), stroke? - draw lines or filled shape (default true - lines).

See also path.

Examples

Bezier path

(drawing-snippet
 (fn [canvas]
   (set-color canvas :white 190)
   (translate canvas 100 100)
   (let [s (for [a (range 0 65 1.3)]
             [(* (+ a 25) (m/cos a)) (* (+ a 25) (m/sin a))])]
     (path-bezier canvas s)))
 ...)

path-bezier-shape

(path-bezier-shape vs)(path-bezier-shape vs close?)

path-def->shape

(path-def->shape path-def)

Create a shape from path definition, see shape->path-def.

Path entry is a tripplet [command arguments winding-rule]

  • [:move [x y]] - move to a position
  • [:line [x y]] - line to a position
  • [:quad [x1 y1 x2 y2] - curved line to a position
  • [:cubic [x1 y1 x2 y2 x3 y3]] - bezier line to a position
  • [:close] - close path
  • [:shape [shape-object connect?]] - append given shape

Winding rule can be one of :even-odd and :non-zero (default) and is optional.

path-shape

(path-shape vs)(path-shape vs close?)

Create shape object out of path.

pattern-mode

(pattern-mode canvas image)(pattern-mode canvas image w h)(pattern-mode canvas image anchor-x anchor-y w h)

Set paint mode to pattern.

Default anchor is set to (0,0). Default width and height are the same as texture dimensions.

To revert call paint-mode

Examples

Set some pattern and fill

(drawing-snippet
 (fn [canvas]
   (let
     [i
      (load-url-image
       "http://static.colourlovers.com/images/patterns/465/465753.png")]
     (-> canvas
         (pattern-mode i)
         (ellipse 100 100 190 190))))
 ...)

point

(point canvas x y)(point canvas [x y])

Draw point at x,y or at vector position.

It’s implemented as a very short line. Consider using (rect x y 1 1) for speed when x and y are integers.

Examples

Sequence of points.

(drawing-snippet (fn [canvas]
                   (doseq [x (range 10 190 10)]
                     (set-stroke canvas (/ x 20))
                     (point canvas x x)))
                 ...)

Magnified point can look differently when different stroke settings are used.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (scale 80.0)
                       (set-stroke 0.5)
                       (point 0.5 0.5)
                       (set-stroke 0.5 :square)
                       (point 1.5 1.5)))
                 ...)

pointy-hex

(pointy-hex canvas x y size stroke?)(pointy-hex canvas x y size)(pointy-hex canvas [x y] size)

Draw pointy topped hex.

Examples

Pointy topped hexagon

(drawing-snippet (fn [canvas]
                   (pointy-hex canvas 100 100 20)
                   (pointy-hex canvas 100 100 90 true))
                 ...)

pointy-hex-shape

(pointy-hex-shape x y size)(pointy-hex-shape [x y] size)

pop-matrix

(pop-matrix canvas)

Restore saved transformation state.

See also push-matrix, reset-matrix.

Examples

Push/pop matrix canvas

(process-image-snippet (fn [img]
                         (with-canvas [c (canvas 250 250)]
                                      (translate c 125 125)
                                      (doseq [a (range 0 m/TWO_PI 0.3)]
                                        (let [x (* 80.0 (m/cos a))
                                              y (* 80.0 (m/sin a))]
                                          (-> c
                                              (push-matrix)
                                              (translate x y)
                                              (rotate a)
                                              (image img 0 0 20 20)
                                              (pop-matrix))))
                                      c))
                       ...)

prect

(prect canvas x1 y1 x2 y2 stroke?)(prect canvas x1 y1 x2 y2)(prect canvas [x1 y1] [x2 y2])

Draw rectangle with top-left corner at (x1,y1) and bottom-right corner at (x2,y2). Optionally you can set stroke? (default: false) to true if you don’t want to fill rectangle and draw outline only.

See also: rect.

prect-shape

(prect-shape r x1 y1 x2 y2)(prect-shape x y w h)(prect-shape [x y] w h)

push-matrix

(push-matrix canvas)

Remember current transformation state.

See also pop-matrix, reset-matrix.

Examples

Push/pop matrix canvas

(process-image-snippet (fn [img]
                         (with-canvas [c (canvas 250 250)]
                                      (translate c 125 125)
                                      (doseq [a (range 0 m/TWO_PI 0.3)]
                                        (let [x (* 80.0 (m/cos a))
                                              y (* 80.0 (m/sin a))]
                                          (-> c
                                              (push-matrix)
                                              (translate x y)
                                              (rotate a)
                                              (image img 0 0 20 20)
                                              (pop-matrix))))
                                      c))
                       ...)

quad

(quad canvas x1 y1 x2 y2 x3 y3 x4 y4 stroke?)(quad canvas x1 y1 x2 y2 x3 y3 x4 y4)(quad canvas [x1 y1] [x2 y2] [x3 y3] [x4 y4])

Draw quad with corners at 4 positions.

Examples

Quad

(drawing-snippet (fn [canvas] (quad canvas 20 20 180 50 50 180 70 70))
                 ...)

quad-shape

(quad-shape x1 y1 x2 y2 x3 y3 x4 y4)(quad-shape [x1 y1] [x2 y2] [x3 y3] [x4 y4])

rarc

(rarc canvas x y r start extent type stroke?)(rarc canvas x y r start extent type)(rarc canvas x y r start extent)(rarc canvas [x y] r start extent)

Draw arc with middle at (x,y) with radius r.

Starting angle start and extent are in radians. Direction is clockwise.

Type is one of the:

  • :open
  • :pie
  • :chord

Examples

Arcs by radius

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-color :white)
                       (rarc 60 60 45 3.5 m/HALF_PI)
                       (rarc 70 70 45 3.5 m/HALF_PI :chord)
                       (rarc 90 90 45 3.5 m/HALF_PI :pie)
                       (set-color :gray)
                       (rarc 130 130 45 m/PI 2 :open false)
                       (rarc 150 150 45 m/PI 2 :chord false)
                       (rarc 170 170 45 m/PI 2 :pie false)))
                 ...)

rarc-shape

(rarc-shape a x y r start extent type)(rarc-shape x y r start extent type)(rarc-shape x y r start extent)(rarc-shape [x y] r start extent)

rect

(rect canvas x y w h stroke?)(rect canvas x y w h)(rect canvas [x y] w h)

Draw rectangle with top-left corner at (x,y) position with width w and height h. Optionally you can set stroke? (default: false) to true if you don’t want to fill rectangle and draw outline only.

See also: crect and prect.

Examples

Two squares, one filled and second as outline.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (rect 30 30 50 50)
                       (rect 80 80 90 90 true)))
                 ...)

rect-shape

(rect-shape r x y w h)(rect-shape x y w h)(rect-shape [x y] w h)

rendering-hints

Rendering hints define quality of drawing or window rendering.

The differences are in interpolation, antialiasing, speed vs quality rendering etc. See the source code for the list of each value.

The :highest is :high with VALUE_STROKE_PURE added. Be aware that this option can give very soft lines.

Default hint for Canvas is :high. You can set also hint for Window which means that when display is refreshed this hint is applied (java defaults are used otherwise).

Examples

List of possible hints.

(keys rendering-hints)
;;=> (:low :mid :high :highest)

replace-canvas

(replace-canvas window canvas)

Replace canvas in window.

  • Input: window and new canvas
  • Returns canvas

reset-clip

(reset-clip canvas)

Resets current clipping.

See also clip.

reset-matrix

(reset-matrix canvas)

Reset transformations.

resize

(resize i w h)

Resize image.

Examples

Resize image to 300x40

(process-image-snippet (fn [img] (resize img 300 40)) ...)

rotate

(rotate canvas angle)

Rotate canvas

Examples

Rotate canvas

(process-image-snippet (fn [img]
                         (with-canvas-> (canvas 150 150)
                                        (translate 75 75)
                                        (rotate m/QUARTER_PI)
                                        (image img -75 -75)))
                       ...)

save

(save i n)

Save image i to a file n.

save-file-type

multimethod

Save Image to the file.

Preprocess if necessary (depends on file type). For supported formats check img-writer-formats.

Dispatch is based on extension as keyword, ie. “.jpg” -> :jpg.

save-image

(save-image b filename)

Save image to the file.

  • Input: image (BufferedImage object) and filename
  • Side effect: saved image

Image is saved using save-file-type multimethod.

scale

(scale canvas scalex scaley)(scale canvas s)

Scale canvas

Examples

Scale canvas

(process-image-snippet
 (fn [img] (with-canvas-> (canvas 150 150) (scale 0.5) (image img 0 0)))
 ...)

screen-height

(screen-height)

Returns height of the screen.

Examples

Example value

(screen-height)
;;=> 1080

screen-width

(screen-width)

Returns width of the screen.

Examples

Example value

(screen-width)
;;=> 1920

sec

(sec)

Current second

Examples

Current value

(sec)
;;=> 28

session-name

(session-name)

Get session name

Examples

Currenct session value

(session-name)
;;=> ["20221021141759" "FA7A91BD"]

set-awt-background

(set-awt-background canvas c)

Set background color. Expects valid java.awt.Color object.

Examples

Set background with java.awt.Color.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-awt-background java.awt.Color/BLUE)))
                 ...)

set-awt-color

(set-awt-color canvas c)

Set color with valid java Color object. Use it when you’re sure you pass java.awt.Color object.

Examples

Set color with java.awt.Color.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-awt-color java.awt.Color/RED)
                       (rect 50 50 100 100)))
                 ...)

set-background

(set-background canvas c)(set-background canvas c a)(set-background canvas r g b a)(set-background canvas r g b)

Sets background with given color.

Background can be set with alpha.

See set-color.

Examples

Set background with alpha set.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-background :maroon 200)))
                 ...)

set-color

(set-color canvas c)(set-color canvas c a)(set-color canvas r g b a)(set-color canvas r g b)

Sets current color. Color can be:

  • vec3, vec4 with rgb values.
  • java.awt.Color object
  • keyword with name from 140 HTML color names
  • Integer
  • r, g, b and optional alpha

See clojure2d.color namespace for more color functions.

Examples

Set color various ways.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-color 11189196)
                       (rect 10 10 40 40)
                       (set-color :maroon)
                       (rect 60 60 40 40)
                       (set-color java.awt.Color/GREEN)
                       (rect 110 110 40 40)
                       (set-color 0 111 200 100)
                       (rect 20 20 160 160)
                       (set-color (v/vec3 0 100 255))
                       (rect 160 160 25 25)))
                 ...)

set-composite

(set-composite canvas composite)(set-composite canvas)

Set composite method for blending during draw.

See composite to create one defined by clojure2d.color blending modes.

You can also use ones defined in java.awt.AlphaComposite class.

Call witout parameters to revert to default: java.awt.AlphaComposite/SrcOver.

set-font

(set-font canvas font-or-fontname)

Set font by name or actual font.

Examples

Various fonts

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-font "Courier New")
                       (text "Trying to set Courier New" 100 50 :center)
                       (set-font "Arial")
                       (text "Trying to set Arial" 100 100 :center)
                       (set-font "Verdana")
                       (text "Trying to set Verdana" 100 150 :center)))
                 ...)

set-font-attributes

(set-font-attributes canvas size style)(set-font-attributes canvas size)

Set current font size and attributes.

Attributes are: :bold, :italic, :bold-italic.

Examples

Font attributes

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-font-attributes 30)
                       (text "Size 30" 100 50 :center)
                       (set-font-attributes 15 :italic)
                       (text "Size 15, italic" 100 100 :center)
                       (set-font-attributes 20 :bold-italic)
                       (text "Size 20, bold, italic" 100 150 :center)))
                 ...)

set-state!

(set-state! w state)

Changle global state for Window.

set-stroke

(set-stroke canvas size cap join miter-limit)(set-stroke canvas size cap join)(set-stroke canvas size cap)(set-stroke canvas size)(set-stroke canvas)

Set stroke (line) attributes like cap, join, size and miter-limit.

Default :round and :bevel are used. Default size and miter-limit are 1.0.

See stroke-joins and stroke-caps for names.

See set-stroke-custom.

Examples

Various stroke settings.

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-stroke 10 :round)
                       (line 25 20 25 180)
                       (set-stroke 10 :butt)
                       (line 55 20 55 180)
                       (set-stroke 10 :square)
                       (line 85 20 85 180)
                       (set-stroke 10 :round :bevel)
                       (rect 120 20 60 40 true)
                       (set-stroke 10 :round :miter)
                       (rect 120 80 60 40 true)
                       (set-stroke 10 :round :round)
                       (rect 120 140 60 40 true)))
                 ...)

Miter limit

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (set-stroke 10 :square :miter)
                       (triangle 70 50 170 50 170 70 true)
                       (set-stroke 10 :square :miter 5.0)
                       (triangle 70 100 170 100 170 120 true)
                       (set-stroke 10 :square :miter 25.0)
                       (triangle 70 150 170 150 170 170 true)))
                 ...)

set-stroke-custom

(set-stroke-custom canvas {:keys [size cap join miter-limit dash dash-phase], :or {size 1.0, cap :butt, join :round, miter-limit 1.0, dash nil, dash-phase 0.0}})

Create custom stroke.

Provide map with following entries, see more in JavaDoc:

  • :size - size of the stroke (default: 1.0)
  • :cap - stroke-caps (default: :butt)
  • :join - stroke-joins (default: :round)
  • :miter-limit - line joins trim factor (default: 1.0)
  • :dash - array with dash pattern, (default: nil)
  • :dash-phase - offset to start pattern (default: 0.0)

See also set-stroke.

Examples

Custom strokes

(drawing-snippet
 (fn [canvas]
   (-> canvas
       (set-stroke-custom {:size 2.0, :dash [4.0], :dash-phase 2.0})
       (line 20 20 180 20)
       (set-stroke-custom {:size 2.0, :dash [20.0], :dash-phase 10})
       (line 20 50 180 50)
       (set-stroke-custom {:size 2.0, :dash [10.0 2.0 2.0 2.0]})
       (line 20 80 180 80)
       (set-stroke-custom {:size 1.0, :dash [4.0], :dash-phase 2.0})
       (rect 20 110 160 10 true)
       (set-stroke-custom {:size 1.0, :dash [10.0 5.0], :join :miter})
       (rect 20 140 160 10 :true)
       (set-stroke-custom {:size 1.0, :dash [10.0 2.0 2.0 2.0]})
       (rect 20 170 160 10 :true)))
 ...)

shape

(shape canvas sh stroke?)(shape canvas sh)

Draw Java2D shape object

shape->path-def

(shape->path-def shape)

Create path definition from a shape

Returns sequence of triplets of command coords winding-rule:

  • [:move [x y]] - move to a position
  • [:line [x y]] - line to a position
  • [:quad [x1 y1 x2 y2] - curved line to a position
  • [:cubic [x1 y1 x2 y2 x3 y3]] - bezier line to a position
  • [:close] - close path

Winding rule is one of :even-odd and :non-zero (default)

See path-def->shape

shear

(shear canvas sx sy)(shear canvas s)

Shear canvas

Examples

Shear canvas

(process-image-snippet
 (fn [img]
   (with-canvas-> (canvas 150 150) (shear 0.2 0.4) (image img 0 0)))
 ...)

shift-down?

(shift-down? e)

SHIFT key state as boolean.

show-window

(show-window canvas window-name)(show-window canvas window-name draw-fn)(show-window canvas window-name fps draw-fn)(show-window canvas window-name w h fps)(show-window canvas window-name w h fps draw-fn)(show-window {:keys [canvas window-name w h fps draw-fn state draw-state setup hint refresher always-on-top? background position], :or {canvas (canvas 200 200), window-name (str "Clojure2D - " (to-hex (rand-int (Integer/MAX_VALUE)) 8)), fps 60, background :white, refresher :safe}})(show-window)

Show window for given canvas

  • Returns Window type value

As parameters you can provide a map with folowing keys:

  • :canvas - canvas attached to window (default is canvas 200x200 px)
  • :window-name - window name, used also for events dispatch and global state
  • :w - width of the window (default as canvas width)
  • :h - height of the window (default as canvas heiht)
  • :fps - refresh rate
  • :draw-fn - drawing callback (fn canvas window frame loop-state … new-loop-state)
  • :state - initial global state data
  • :draw-state - initial drawing state
  • :setup - inital callback function, returns drawing state (fn canvas window … initial-loop-state)
  • :hint - rendering hint for display: :low, :mid, :high or :highest
  • :refresher - :safe (default), :fast, :onrepaint
  • :background - background color for window panel, default white.
  • :position - window position as a pair of x y, nil (default) for center.

:refresher controls what to do with repainting a window. :safe and :fast repaint a window autmatically, calling draw-fn (if provided) and repaint is done :fps times per second. :onrepaint leaves repainting to the AWT, draw-fn is ignored.

stroke-caps

Stroke cap types

Examples

List of stroke cap types

(keys stroke-caps)
;;=> (:round :butt :square)

stroke-joins

Stroke join types

Examples

List of stroke join types

(keys stroke-joins)
;;=> (:bevel :miter :round)

subimage

(subimage i x y w h)

Return rectangular subimage

Examples

Get subimage and resize.

(process-image-snippet (fn [img]
                         (-> img
                             (subimage 100 100 12 12)
                             (resize 150 150)))
                       ...)

text

(text canvas s x y align)(text canvas s x y)

Draw text for given position and alignment.

Possible alignments are: :right, :center, :left.

Examples

Font attributes

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (text "Align left" 100 50 :left)
                       (text "Align center" 100 100 :center)
                       (text "Align right" 100 150 :right)))
                 ...)

text-bounding-box

(text-bounding-box canvas txt)

Returns bounding box x,y,w,h for given text. [x,y] position is relative to base line.

Examples

Size of some string.

(with-canvas-> (canvas 10 10)
               (text-bounding-box "Size of some string."))
;;=> [0.0 -11.138671875 118.5703125 13.96875]

text-shape

(text-shape canvas txt)(text-shape canvas txt x y)

Returns shape for given text. Should be called withing context.

text-width

(text-width canvas txt)

Returns width of the provided string. Should be called within context.

Examples

Size of some string.

(with-canvas-> (canvas 10 10) (text-width "Size of some string."))
;;=> 119

to-hex

(to-hex n)(to-hex n pad)

Return hex value of given number, padded with leading zeroes if given length

Examples

Usage

(to-hex 123)
;;=> 7B
(to-hex 123 8)
;;=> 0000007B

to-image

(to-image i)

Return BufferedImage, alias for get-image

transcode-svg

(transcode-svg input w h)

Convert transcoder input into BufferedImage. See load-svg.

Examples

Draw SVG onto canvas.

(drawing-snippet (fn [canvas]
                   (let [svg (load-svg "docs/takkun.svg")]
                     (-> canvas
                         (image (transcode-svg svg 200 200))
                         (image (transcode-svg svg 30 30) 170 170))))
                 ...)

transform

(transform canvas x y)(transform canvas [x y])

Transform given point or coordinates with current transformation. See inv-transform.

Examples

Transform point using current transformation.

(with-canvas [c (canvas 100 100)]
             (translate c 50 50)
             (rotate c m/HALF_PI)
             (transform c 10 10))
;;=> [40.0 60.0]

translate

(translate canvas tx ty)(translate canvas [x y])

Translate origin

Examples

Translate canvas

(process-image-snippet
 (fn [img]
   (with-canvas-> (canvas 150 150) (translate 20 20) (image img 0 0)))
 ...)

triangle

(triangle canvas x1 y1 x2 y2 x3 y3 stroke?)(triangle canvas x1 y1 x2 y2 x3 y3)(triangle canvas [x1 y1] [x2 y2] [x3 y3])

Draw triangle with corners at 3 positions.

Examples

Two triangles

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (triangle 30 30 170 100 30 170)
                       (set-color :black)
                       (triangle 170 30 170 170 30 100 true)))
                 ...)

triangle-fan

(triangle-fan canvas vs stroke?)(triangle-fan canvas vs)

Draw triangle fan. Implementation of Processing FAN shape.

First point is common vertex of all triangles.

Input: list of vertices as vectors.

See also: triangle-strip.

Examples

Triangle fan

(drawing-snippet (fn [canvas]
                   (set-color canvas :white 190)
                   (translate canvas 100 100)
                   (let [s (for [a (range 0 65 3.0)]
                             [(* 90.0 (m/cos a)) (* 90.0 (m/sin a))])]
                     (triangle-fan canvas s true)))
                 ...)

triangle-shape

(triangle-shape x1 y1 x2 y2 x3 y3)(triangle-shape [x1 y1] [x2 y2] [x3 y3])

triangle-strip

(triangle-strip canvas vs stroke?)(triangle-strip canvas vs)

Draw triangle strip. Implementation of Processing STRIP shape.

Input: list of vertices as vectors.

See also: triangle-fan.

Examples

Triangle strip

(drawing-snippet
 (fn [canvas]
   (set-color canvas :white 190)
   (translate canvas 100 100)
   (let [s (for [a (range 0 65 3.0)]
             (v/vec2 (* 90.0 (m/cos a)) (* 90.0 (m/sin a))))]
     (triangle-strip canvas s true)))
 ...)

virtual-key

const

;;=> \0xffff

Use as a dispatch in key events for keys like up/down/etc.

width

(width i)

Width of the image.

Examples

Width of the image

(width (load-image "docs/cockatoo.jpg"))
;;=> 150

window-active?

(window-active? window)

Helper function, check if window is active.

Examples

Check if window is visible.

(let [w (show-window)
      before-closing (window-active? w)]
  (close-window w)
  {:before-closing before-closing, :after-closing (window-active? w)})
;;=> {:after-closing false, :before-closing true}

with-canvas

macro

(with-canvas [c canvas] & body)

Macro which takes care to create and destroy Graphics2D object for drawings on canvas. Macro returns result of last call.

See also with-canvas->.

Examples

Draw on canvas

(process-image-snippet (fn [img]
                         (with-canvas [c (canvas 200 200)]
                                      (dotimes [i 50]
                                        (let [x (r/irand -50 100)
                                              y (r/irand -50 100)
                                              w (r/irand (- 200 x))
                                              h (r/irand (- 200 y))]
                                          (image c img x y w h)))
                                      c))
                       ...)

with-canvas->

macro

(with-canvas-> canvas & body)

Threading macro which takes care to create and destroy Graphics2D object for drawings on canvas. Macro returns result of last call.

Each function have to accept canvas as second parameter and have to return canvas.

See also with-canvas.

Examples

Draw on canvas

(process-image-snippet
 (fn [img] (with-canvas-> (canvas 100 100) (image img 50 50 50 50)))
 ...)

with-oriented-canvas

macro

(with-oriented-canvas orientation [c canv] & body)

Same as with-canvas but with initial orientation.

Examples

Orient and draw.

(drawing-snippet (fn [canvas]
                   (with-oriented-canvas :bottom-left+
                                         [c canvas]
                                         (doseq [p (range 0 100 4)]
                                           (set-color c (* p 2) 200 200)
                                           (line c p 0 (+ p 100) 50))))
                 ...)

with-oriented-canvas->

macro

(with-oriented-canvas-> orientation canv & body)

Same as with-canvas-> but with initial orientation.

Examples

Orient and draw.

(drawing-snippet (fn [canvas]
                   (with-oriented-canvas-> :bottom-left+
                                           canvas
                                           (line 0 0 100 50)
                                           (line 100 0 200 50)))
                 ...)

xor-mode

(xor-mode canvas c)(xor-mode canvas c a)(xor-mode canvas r g b a)(xor-mode canvas r g b)

Set XOR painting mode with given color.

Examples

Set XOR Painting mode

(drawing-snippet (fn [canvas]
                   (-> canvas
                       (xor-mode :gray)
                       (rect 50 50 100 100)
                       (rect 70 70 60 60)))
                 ...)

year

(year)

Current year

Examples

Current value

(year)
;;=> 2022