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:
- MouseXYProto - mouse position related to Window.
- MouseButtonProto - status of mouse buttons.
- KeyEventProto - keyboard status
- ModifiersProto - status of special keys (Ctrl, Meta, Alt, etc.)
- 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
plusPURE_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]
)- key-pressed - when key is pressed
- key-released - when key is released
- key-typed - when key is typed
- 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:
- Check parameters and create missing values for missed ones.
- If
:setup
function is provided, call it and use returned value as:draw-state
- Create JFrame, java.awt.Canvas, pack them, attach event handlers and display
- Set global state
- 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 isnil
orfalse
.
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. Ifsetup
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:
- Primitives like point, rect, etc.
- Tranformations like translate, rotate, etc.
- Text rendering like text, set-font-attributes, etc.
- Image manipulations like convolve
- Color and style like set-color, gradient-mode, set-background, set-stroke, etc.
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:
- make-session - create new session
- ensure-session - create new session when there is no one
- close-session - close current session
- session-name - returns current session.
Utilities
Additional utility functions
- date and time functions
- to-hex formatter
Categories
- Canvas functions: black-canvas canvas clip convolve flip-x flip-y get-canvas get-image height inv-transform orient-canvas orientations-list pop-matrix push-matrix rendering-hints replace-canvas reset-clip reset-matrix resize rotate save scale shear subimage to-image transform translate width with-canvas with-canvas-> with-oriented-canvas with-oriented-canvas->
- Screen: screen-height screen-width
- Drawing functions: arc awt-xor-mode bezier crect curve ellipse filled-with-stroke flat-hex gradient-mode grid-cell grid-qr-cell image line paint-mode path path-bezier pattern-mode point pointy-hex prect quad rarc rect set-awt-background set-awt-color set-background set-color set-composite set-stroke set-stroke-custom shape stroke-caps stroke-joins transcode-svg triangle triangle-fan triangle-strip xor-mode
- Date / time: datetime day hour millis minute month nanos sec year
- Events: alt-down? alt-gr-down? control-down? key-char key-code key-event key-event-map key-pressed key-pressed? key-raw key-released key-typed meta-down? mouse-button mouse-event mouse-event-map mouse-pos mouse-pressed? mouse-x mouse-y shift-down?
- Image functions: *jpeg-image-quality* convolution-matrices convolve file-extension get-image height img-reader-formats img-writer-formats load-image load-svg resize save save-file-type save-image subimage to-image width
- Session: *log-to-file* close-session ensure-session log log-name make-session next-filename session-name
- Transform canvas: flip-x flip-y inv-transform orient-canvas orientations-list pop-matrix push-matrix reset-matrix rotate scale shear transform translate with-oriented-canvas with-oriented-canvas->
- Window: alt-down? alt-gr-down? close-window control-down? convolve get-canvas get-image get-state height key-char key-code key-pressed? key-raw meta-down? mouse-button mouse-in-window? mouse-pos mouse-pressed? mouse-x mouse-y rendering-hints replace-canvas save set-state! shift-down? show-window subimage to-image width window-active?
- Text / font: char-width font-ascent font-height fonts-list load-font set-font set-font-attributes text text-bounding-box text-shape text-width
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 repaint shape->path-def to-hex triangle-shape
Constants
- available-cores =
16
- available-tasks =
24
- virtual-key =
\0xffff
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
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])
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 0x6d0055d4 "java.awt.geom.Arc2D$Double@0"],
;;=> :buffer
;;=> #object[java.awt.image.BufferedImage 0x2599cec3 "BufferedImage@2599cec3: 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 0x3f42ed38 "java.awt.geom.Ellipse2D$Double@0"],
;;=> :font nil,
;;=> :graphics nil,
;;=> :h 30,
;;=> :hints
;;=> [[#object[sun.awt.SunHints$Key 0x36ddbb42 "Global antialiasing enable key"]
;;=> #object[sun.awt.SunHints$Value 0x4399e4b0 "Nonantialiased rendering mode"]]
;;=> [#object[sun.awt.SunHints$Key 0x63759fe "Image interpolation method key"]
;;=> #object[sun.awt.SunHints$Value 0x7f4e4a70 "Nearest Neighbor image interpolation mode"]]
;;=> [#object[sun.awt.SunHints$Key 0x5e1d9ab0 "Alpha blending interpolation method key"]
;;=> #object[sun.awt.SunHints$Value 0x57cd438c "Fastest alpha blending methods"]]
;;=> [#object[sun.awt.SunHints$Key 0x5c012177 "Color rendering quality key"]
;;=> #object[sun.awt.SunHints$Value 0x343f40e1 "Fastest color rendering mode"]]
;;=> [#object[sun.awt.SunHints$Key 0x6aa5b643 "Global rendering quality key"]
;;=> #object[sun.awt.SunHints$Value 0x380f9eb2 "Fastest rendering methods"]]
;;=> [#object[sun.awt.SunHints$Key 0x1abb4410 "Fractional metrics enable key"]
;;=> #object[sun.awt.SunHints$Value 0x351f5e09 "Integer text metrics mode"]]
;;=> [#object[sun.awt.SunHints$Key 0x4f5ae662 "Text-specific antialiasing enable key"]
;;=> #object[sun.awt.SunHints$Value 0x4c55e89c "Nonantialiased text mode"]]],
;;=> :line-obj
;;=> #object[java.awt.geom.Line2D$Double 0x873ba05 "java.awt.geom.Line2D$Double@873ba05"],
;;=> :rect-obj
;;=> #object[java.awt.geom.Rectangle2D$Double 0x301dfece "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@79ce5176: 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)
;;=> ["20230425090623" "B73C1E51"]
(close-session)
;;=> nil
(session-name)
;;=> ["20230425090652" "B73C8F7C"]
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.
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)))
...)
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))
...)
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 25,
;;=> :hour 9,
;;=> :millis 1682406412038,
;;=> :minute 6,
;;=> :month 4,
;;=> :nanos 89535799073555,
;;=> :sec 52,
;;=> :second 52,
;;=> :year 2023}
(datetime :vector)
;;=> [2023 4 25 9 6 52 1682406412038 89535799191962]
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)))
...)
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))
...)
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")
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 in screen (x,y) coordinates. For cell coordinates, see grid-qr-cell.
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-qr-cell
(grid-qr-cell canvas grid q r stroke?)
(grid-qr-cell canvas grid q r)
(grid-qr-cell canvas grid q r scale stroke?)
Draw grid cell for given grid in cell (q,r) coordinates. For screen coordinates, see grid-cell.
height
(height i)
height of the image.
Examples
Height of the image
(height (load-image "docs/cockatoo.jpg"))
;;=> 150
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-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-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@29e5f741
(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@7b488210
log
(log message)
Log message to file or console
Examples
Example usage
(session-name)
;;=> ["20230425090652" "B73C8F7C"]
(binding [*log-to-file* true]
(log "Log information to file under session"))
;;=> #clojure2d.core.SessionType
;;=> {:counter #,
;;=> :logger
;;=> #object[java.io.BufferedWriter 0x548f198b "java.io.BufferedWriter@548f198b"],
;;=> :name ["20230425090652" "B73C8F7C"]}
(Thread/sleep 1000)
;;=> nil
(slurp (log-name))
;;=> Session id: B73C8F7C
;;=>
;;=> 2023-04-25 09:06:52: Log information to file under session
log-name
(log-name)
Returns log file name with path.
Examples
Usage
(log-name)
;;=> log/20230425090623.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)
;;=> ["20230425090653" "B73C92A2"]
(Thread/sleep 2000)
;;=> nil
(make-session)
;;=> ["20230425090655" "B73C9B71"]
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-pos
(mouse-pos m)
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)
;;=> 89507182784556
next-filename
(next-filename prefix)
(next-filename prefix suffix)
Create next unique filename based on session
Examples
Usage
(next-filename "folder/name/")
;;=> folder/name/B73C9B71_000000
(next-filename "folder/name/")
;;=> folder/name/B73C9B71_000001
(next-filename "folder/name/" ".jpg")
;;=> folder/name/B73C9B71_000002.jpg
(close-session)
;;=> nil
(next-filename "folder/name/")
;;=> folder/name/B73C9A85_000000
(next-filename "folder/name/")
;;=> folder/name/B73C9A85_000001
(next-filename "folder/name/" ".jpg")
;;=> folder/name/B73C9A85_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)
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-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.
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))
...)
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.
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)
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)))
...)
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
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-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
session-name
(session-name)
Get session name
Examples
Currenct session value
(session-name)
;;=> ["20230425090655" "B73C9A85"]
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)
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-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->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)))
...)
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 or user by calling repaint
, 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
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-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)))
...)
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)))
...)