On this page:
3.1 Color
3.1.1 Hue
3.1.2 Saturation
3.1.3 Brightness
3.1.4 Color Variables
3.1.5 Relativity
3.1.6 Linear Gradient
3.1.7 Radial Gradient
3.1.8 Wave Gradient
3.2 Classes and Objects
3.2.1 Objects
3.2.2 Multiple Constructors
3.2.3 Composite Objects
3.2.4 Inheritance
3.3 Input
3.3.1 Mouse 1D
3.3.2 Mouse 2D
3.3.3 Mouse Press
3.3.4 Mouse Signals
3.3.5 Easing
3.3.6 Constrain
3.3.7 Storing Input
3.3.8 Mouse Functions
3.3.9 Keyboard
3.3.10 Keyboard Functions
3.3.11 Milliseconds
3.3.12 Clock
3.4 Transform
3.4.1 Translate
3.4.2 Scale
3.4.3 Rotate
3.4.4 Arm
3.5 Typography
3.5.1 Letters
3.5.2 Words
3.5.3 Text Rotation
3.6 Vectors
3.6.1 Vectors
3.6.2 Vector 2d
3.6.3 Vector of objects
3.7 Form
3.7.1 Points and Lines
3.7.2 Pie Chart
3.7.3 Regular Polygons
3.7.4 Star
3.7.5 Triangle Strip
3.7.6 Bezier
3.8 Image
3.8.1 Pointilism

3 Examples

This section contains more elaborate examples of how to use Sketching.

All examples are available at https://github.com/soegaard/sketching/tree/main/sketching-doc/sketching-doc/manual-examples/.

If you find any mistakes in the examples, please make an Github issue at https://github.com/soegaard/sketching/.

I encourage you to submit your own examples.

If you lack inspiration, I’d love some help porting the examples on Processing Examples. The source for these examples can be found at Processing examples at Github.

The examples are divided into topics:

    3.1 Color

    3.2 Classes and Objects

    3.3 Input

    3.4 Transform

    3.5 Typography

    3.6 Vectors

    3.7 Form

    3.8 Image

3.1 Color

The color examples are:

    3.1.1 Hue

    3.1.2 Saturation

    3.1.3 Brightness

    3.1.4 Color Variables

    3.1.5 Relativity

    3.1.6 Linear Gradient

    3.1.7 Radial Gradient

    3.1.8 Wave Gradient

3.1.1 Hue

In color theory the concepts hue, saturation and brightness are used characterize the color. A hue such as red, yellow, etc. is what we in everyday language think of, when we hear the word "color".

Move the cursor vertically over each bar to alter its hue.

basics/color/hue.js
#lang sketching
; Original example by Rusty Robinson
 
; Hue is the color reflected from or transmitted through an object 
; and is typically referred to as the name of the color (red, blue, yellow, etc.) 
; Move the cursor vertically over each bar to alter its hue. 
 
(define bar-width 20)
(define last-bar  -1)
 
(define (setup)
  (size 640 360)  
  (color-mode 'hsb height height height)
  (background 0)
  (no-stroke))
 
(define (draw)
  (define which-bar (quotient mouse-x bar-width))
  (unless (= which-bar last-bar)
    (define bar-x (* which-bar bar-width))
    (fill mouse-y height height)
    (rect bar-x 0 bar-width height)
    (set! last-bar which-bar)))

3.1.2 Saturation

Saturation is the strength or purity of the color. One can think of saturation as the amount of gray in proportion to the hue. A "saturated" color is pure and an "unsaturated" color has a large component of gray.

Move the cursor vertically over each bar to alter its saturation.

basics/color/saturation.js
#lang sketching
 
; Saturation is the strength or purity of the color and represents the 
; amount of gray in proportion to the hue. A "saturated" color is pure 
; and an "unsaturated" color has a large percentage of gray. 
; Move the cursor vertically over each bar to alter its saturation.
 
(define bar-width 20)
(define last-bar  -1)
 
(define (setup)
  (size 640 360)
  (no-stroke)
  (background 0)
  (color-mode 'hsb width height 100))
 
(define (draw)
  (define which-bar (quotient mouse-x bar-width))
  (unless (= which-bar last-bar)
    (define bar-x (* which-bar bar-width))
    (fill bar-x mouse-y 66)
    (rect bar-x 0 bar-width height)
    (set! last-bar which-bar)))

3.1.3 Brightness

Move the cursor vertically over each bar to alter its brightness. basics/color/brightness.js
#lang sketching
; Original example by Rusty Robinson
 
(define bar-width 20)
(define last-bar  -1)
 
(define (setup)
  (size 640 360)
  (color-mode 'hsb width 100 height)
  (background 0)
  (no-stroke))
 
(define (draw)
  (define which-bar (quotient mouse-x bar-width))
  (unless (= which-bar last-bar)
    (define bar-x (* which-bar bar-width))
    (fill bar-x 100 mouse-y)
    (rect bar-x 0 bar-width height)
    (set! last-bar which-bar)))
 

3.1.4 Color Variables

basics/color/color-variables.js
#lang sketching
 
;; Color Variables (Homage to Albers).
;;
;; This example creates variables for colors that may be referred to 
;; in the program by a name, rather than a number. 
 
(define (setup)
  (size 640 360))
 
(define inside  (color 204 102 0))
(define middle  (color 204 153 0))
(define outside (color 153  51 0))
 
(define (draw)
  ; setup
  (no-stroke)
  (background 51 0 0)
  ; draw
  (push-matrix)
  (translate 80 80)
  (fill outside)
  (rect 0 0 200 200)
  (fill middle)
  (rect 40 60 120 120)
  (fill inside)
  (rect 60  90 80 80)
  (pop-matrix)
 
  (push-matrix)
  (translate 360 80)
  (fill inside)
  (rect 0 0 200 200)
  (fill outside)
  (rect 40 60 120 120)
  (fill middle)
  (rect 60 90 80 80)
  (pop-matrix))

3.1.5 Relativity

basics/color/relativity.js
#lang sketching
; Relativity.
 
; Each color is perceived in relation to other colors. The top and bottom 
; bars each contain the same component colors, but a different display order 
; causes individual colors to appear differently.
 
(define a (color 165 167  20))
(define b (color  77  86  59))
(define c (color  42 106 105))
(define d (color 165  89  20))
(define e (color 146 150 127))
 
(define (setup)
  (size 640 360)
  (no-loop) ; only call draw once
  (color-mode 'hsb height height height))
 
(define (draw)
  (draw-band a b c d e 0 (/ width 128))
  (draw-band c a d b e (/ height 2) (/ width 128)))
 
(define (draw-band v w x y z y-pos bar-width)
  (define colors (list v w x y z))
  (define num 5) ; number of colors
  (for ([i (in-range 0 width (* bar-width num))])
    (for ([j (length colors)] [c colors])
      (fill c)
      (rect (+ i (* j bar-width)) y-pos bar-width (/ height 2)))))

3.1.6 Linear Gradient

basics/color/linear-gradient.js
#lang sketching
 
; Simple Linear Gradient 
; 
; The lerp-color() function is useful for interpolating between two colors.
 
; The default color mode is rgb:
(define b1 (color 255))           ; white
(define b2 (color   0))           ; black
(define c1 (color 204 102   0))   ; orange
(define c2 (color   0 102 153))   ; blueish
 
(define (setup)
  (size 640 360)
  ; hsb = hue, saturation, brightness
  (color-mode 'hsb width height 100)
  (no-loop))
 
(define (draw)
  ; background
  (set-gradient 0 0            (/ width 2) height  b1 b2 'x-axis) ; white->black
  (set-gradient (/ width 2) 0  (/ width 2) height  b2 b1 'x-axis) ; black->white
  ; foreground
  (set-gradient 50  90  540 80  c1 c2 'y-axis)  ; orange -> blue
  (set-gradient 50 190  540 80  c2 c1 'x-axis)) ; blue   -> orange
 
(define (set-gradient x y  w h  c1 c2  axis)
  (no-fill)
  (case axis
    [(y-axis) ; top to bottom gradient
     (for ([i (in-range y (+ y h 1))])
       (define inter (remap i y (+ y h) 0 1))
       (define c (lerp-color c1 c2 inter))
       (stroke c)
       (line x i (+ x w) i))]
    [(x-axis) ; left to right gradient
     (for ([i (in-range x (+ x w 1))])
       (define inter (remap i x (+ x w) 0 1))
       (define c (lerp-color c1 c2 inter))
       (stroke c)
       (line i y i (+ y h)))]))

3.1.7 Radial Gradient

basics/color/radial-gradient.js
#lang sketching
(require racket/math)
 
; Radial Gradient.
 
; Draws a series of concentric circles to create a gradient from one color to another.
 
(define dim 1)
 
(define (setup)
  (size 640 360)
  (:= dim (/ width 2))
  (background 0)
  (color-mode 'hsb 360 100 100)
  (no-stroke)
  (ellipse-mode 'radius)
  (background 0)
  (frame-rate 1))
 
(define (draw)
  (for ([x (in-range 0 (+ width 1) dim)])
    (draw-gradient x (/ height 2))))
 
(define (draw-gradient x y)
  (define radius (quotient dim 2))
  (define h (exact-floor (random 0 360)))
  (for ([r (in-range radius 0 -1)])
    (fill h 90 90)
    (ellipse x y r r)
    (:= h (modulo (+ h 1) 360))))

3.1.8 Wave Gradient

basics/color/wave-gradient.js
#lang sketching
 
;; Wave Gradient
;
;; orignal Processing example by Ira Greenberg.  
;; Generate a gradient along a sin() wave.
 
(define amplitude 30)
(define fill-gap 2.5)
 
(define (setup)
  (size 640 360)
  (background 200)
  (no-loop))
 
(define (draw)
  (define w/2 width)
  (define h/2 height)
  ;; To efficiently set all the pixels on screen, make the set() 
  ;; calls on a PImage, then write the result to the screen.
  (define gradient (create-image width height 'rgb))
  (define frequency 0)
  
  (for ([i (in-range -75 (+ height 75))])
    ;; Reset angle to 0, so waves stack properly
    (define angle 0)
    ;; Increasing frequency causes more gaps
    (+= frequency 0.002)
    (for ([j (+ width 75)])
      (define py (+ i (* (sin (radians angle)) amplitude)))
      (+= angle frequency)
      (define c (color (abs   (/ (* (- py i) 255) amplitude))
                       (- 255 (/ (* (abs (- py i)) 255) amplitude))
                       (min 255 (* j (/ 255 (+ width 50))))))
      ;; Hack to fill gaps. Raise value of fillGap if you increase frequency
      (for ([filler (in-range fill-gap)])
        (image-set gradient (+ w/2 (int (- j filler))) (+ h/2 (- (int py) filler)) c)
        (image-set gradient (+ w/2 (int    j))         (+ h/2    (int py))         c)
        (image-set gradient (+ w/2 (int (+ j filler))) (+ h/2 (+ (int py) filler)) c))))
  ;; Draw the image to the screen
  (image gradient 0 0))

3.2 Classes and Objects

The examples are:

    3.2.1 Objects

    3.2.2 Multiple Constructors

    3.2.3 Composite Objects

    3.2.4 Inheritance

3.2.1 Objects

basics/objects/objects.js
#lang sketching
; Original Processing example by hbarragan.
 
;;;
;;; Objects
;;;
 
;; Move the cursor across the image to change the speed and positions
;; of the geometry. The class MRect defines a group of lines.
 
(class MRect Object
  (init-field w xpos h ypos d t)
       ; w     single bar width
       ; xpos  rect xposition
       ; h     rect height
       ; ypos  rect yposition
       ; d     single bar distance
       ; t      number of bars
 
  ;; Constructor
  ; Nothing to do - values are used as is
  (super-new)
  
  ;; Methods
  (define/public (move pos-x pos-y damping)
    (define dif (- ypos pos-y))
    (when (> (abs dif) 1)
      (-= ypos (/ dif damping)))
    (:= dif (- xpos pos-x))
    (when (> (abs dif) 1)
      (-= xpos (/ dif damping))))
 
  (define/public (display)
    (for ([i t])
      (rect (+ xpos (* i (+ d w))) ypos w (* height w)))))
 
;;;
;;; Example 
;;;
 
(define r1 (make-object MRect 1 134.0 0.532  (* 0.1 height) 10.0 60))
(define r2 (make-object MRect 2  44.0 0.166  (* 0.3 height)  5.0 50))
(define r3 (make-object MRect 2  58.0 0.332  (* 0.4 height) 10.0 35))
(define r4 (make-object MRect 1 120.0 0.0498 (* 0.9 height) 15.0 60))
 
(define (setup)
  (size 640 360)
  (fill 255 204)
  (frame-rate 60)
  (no-stroke))
 
(define (draw)
  (background 0)
  (r1.display)
  (r2.display)
  (r3.display)
  (r4.display)
 
  (r1.move (- mouse-x (/ width 2))                           (+ mouse-y (* height 0.1))   30)
  (r2.move (modulo (int (+ mouse-x (* width 0.05))) width)   (+ mouse-y (* height 0.025)) 20)
  (r3.move (/ mouse-x 4)                                     (- mouse-y (* height 0.025)) 40)
  (r4.move (- mouse-x (/ width 2))                           (- height mouse-y)           50))
 
 

3.2.2 Multiple Constructors

basics/objects/multiple-constructors.js
#lang sketching
;; Multiple constructors
 
;; Original text:
;;   A class can have multiple constructors that assign the fields in different ways.
;;   Sometimes it's beneficial to specify every aspect of an object's data by
;;   assigning values to the fields, but other times it might be appropriate to define only one or a few.
 
;; Sketching:
;;    We use init fields with default values instead of explicit constructors.
 
;;;
;;; Spot
;;; 
 
(class Spot Object
  (init-field
   [x      (* width 0.25)]
   [y      (* height 0.5)]
   [radius 40])  
  ; "Constructor"  
  (super-new)
  ; Methods
  (define/public (display)    
    (ellipse x y (* radius 2) (* radius 2))))
 
;;;
;;; Application
;;;
 
(define sp1 #f)
(define sp2 #f)
 
(define (setup)
  (size 640 360)
  (background 204)
  (no-loop)
  ;; Run the constructor without parameters
  (:= sp1 (make-object Spot))
  ;; Run the constructor with three parameters
  (:= sp2 (make-object Spot (* width 0.5) (* height 0.5) 120)))
 
(define (draw)
  (sp1.display)
  (sp2.display))
 
 
 

3.2.3 Composite Objects

basics/objects/composite-objects.js
#lang sketching
; Original Processing example by hbarragan.
 
;; /**
;;  * Composite Objects
;;  * 
;;  * An object can include several other objects. Creating such composite objects 
;;  * is a good way to use the principles of modularity and build higher levels of 
;;  * abstraction within a program.
;;  */
 
(class Ring Object
  (field [x #f] [y #f] [diameter #f] [on #f])
  ; x,y       x- and y-coordinate
  ; diameter  diameter of the ring
  ; on        turns the display on and off
 
  ;; Constructor
  ; values are used as is
  (super-new)
  
  ;; Methods
  (define/public (start xpos ypos)
    (:= x xpos)
    (:= y ypos)
    (:= on #t)
    (:= diameter (or diameter 1)))
 
  (define/public (grow)
    (when on
      (+= diameter 0.5)
      (when (> diameter (* 2 width))
        (:= diameter 0.0))))
 
  (define/public (display)
    (when on
      (no-fill)
      (stroke-weight 4)
      (stroke 155 153)
      (ellipse x y diameter diameter))))
 
(class Egg Object
  ; x, y     X-coordinate, y-coordinate
  ; tilt     Left and right angle offset
  ; angle    Used to define the tilt
  ; scalar   Height of the egg
  (init-field x y tilt scalar) ; passed to "constructor"
 
  ;; Constructor
  (super-new)
  (define angle 0.)    ; default value for floats in P are 0.0
  (/= scalar 100.)
 
  (define/public (wobble)
    (:= tilt (/ (cos angle) 8.))
    (+= angle 0.1))
 
  (define/public (display)
    (stroke "red")
    (fill 255)
    (push-matrix)
    (translate x y)
    (rotate tilt)
    (scale scalar)
    ;; beginShape();
    ;;   vertex(0, -100);
    ;;   bezierVertex(25, -100, 40, -65, 40, -40);
    ;;   bezierVertex(40, -15, 25, 0, 0, 0);
    ;;   bezierVertex(-25, 0, -40, -15, -40, -40);
    ;;   bezierVertex(-40, -65, -25, -100, 0, -100);
    ;; endShape();
    ;; TODO: Shapes aren't implemented yet, so let's
    ;;       approximate with an ellipse instead
    (ellipse-mode 'center)
    (ellipse 0 0 80 120)
    (pop-matrix)))
 
(class EggRing Object
  (init-field x y t sp)            ; arguments for the constructor
  (field [ovoid #f] [circle #f])   ; fields
  ;; Constructor
  (super-new)
  (:= circle (new Ring))
  (:= ovoid  (new Egg [x x] [y y] [tilt t] [scalar sp]))
  (circle.start x (- y (/ sp 2)))
  
  (define/public (transmit)
    (ovoid.wobble)
    (ovoid.display)
    (circle.grow)
    (circle.display)
    (unless circle.on
      (:= circle.on #t))))
 
;;;
;;;
;;;
 
(define er1 #f)
(define er2 #f)
 
(define (setup)
  ; (no-loop)
  (size 640 360)
  (frame-rate 60)
  (:= er1 (make-object EggRing (* width 0.45) (* height 0.5) 0.1  120))
  (:= er2 (make-object EggRing (* width 0.65) (* height 0.8) 0.05 180)))
  
(define (draw)
  (background 0)
  (er1.transmit)
  (er2.transmit))

3.2.4 Inheritance

basics/objects/inheritance.js
#lang sketching
;;;
;;; Inheritance
;;;
 
;; A class can be defined using another class as a foundation.
;; In object-oriented programming terminology, one class can inherit fields and methods from another.
;; An object that inherits from another is called a subclass,
;; and the object it inherits from is called a superclass. A subclass extends the superclass.
 
(class Spin Object
  (init-field x y speed)
  (field [angle #f])
  ; Constructor
  (super-new)
  (:= angle 0.0)
  ; Methods  
  (define/public (update)
    (+= angle speed)))
 
(class SpinArm Spin 
  (inherit-field x y speed angle) ; bring variables into scope
  ; Constructor
  (super-new)
  ; (super-make-object x y speed) ; invoke super class initialization
  ; Methods
  (define/public (display)
    (stroke-weight 1)
    (stroke 0)
    (push-matrix)
    (translate x y)
    (+= angle speed)
    (rotate angle)
    (line 0 0 165 0)
    (pop-matrix)))
 
(class SpinSpots Spin
  (init-field dim)
  (inherit-field x y speed angle)
  ; Constructor
  (super-new)
  ; (super-make-object x y speed)
  ; Methods
  (define/public (display)
    (no-stroke)
    (push-matrix)
    (translate x y)
    (+= angle speed)
    (rotate angle)
    (ellipse (- (/ dim 2)) 0 dim dim)
    (ellipse (+ (/ dim 2)) 0 dim dim)
    (pop-matrix)))
 
(define spots #f)
(define arm   #f)
 
(define (setup)
  (size 640 360)
  (frame-rate 60)
  (:= arm   (make-object SpinArm  (/ width 2) (/ height 2)  0.01 ))
  (:= spots (make-object SpinSpots
                         90.0                               ; new field
                         (/ width 2) (/ height 2) -0.02)))  ; super fields
 
(define (draw)
  (background 204)
  (arm.update)
  (arm.display)
  (spots.update)
  (spots.display))

3.3 Input

The input examples are:

    3.3.1 Mouse 1D

    3.3.2 Mouse 2D

    3.3.3 Mouse Press

    3.3.4 Mouse Signals

    3.3.5 Easing

    3.3.6 Constrain

    3.3.7 Storing Input

    3.3.8 Mouse Functions

    3.3.9 Keyboard

    3.3.10 Keyboard Functions

    3.3.11 Milliseconds

    3.3.12 Clock

3.3.1 Mouse 1D

basics/input/mouse-1d.js
#lang sketching
 
; Move the mouse left and right to shift the balance.
; The mouse-x variable is used to control both the size and color of the rectangles.
 
(define (setup)
  (size 640 360)
  (no-stroke)
  (color-mode 'rgb height height height)
  (rect-mode 'center))
 
(define (draw)
  (background 0)
 
  (define r1 (remap mouse-x 0 width 0 height))
  (define r2 (- height r1))
 
  (fill (int r1))
  (rect (/ (+ width r1) 2) (/ height 2) r1 r1)
 
  (fill (int r2))
  (rect (/ (- width r1) 2) (/ height 2) r2 r2))

3.3.2 Mouse 2D

basics/input/mouse-2d.js
#lang sketching
; Moving the mouse changes the position and size of each box.
 
(define (setup)
  (size 640 360)
  (no-stroke)
  (rect-mode 'center))
 
(define (draw)
  (background 51)
  (fill 255 204)
  (rect mouse-x (/ height 2)  (+ (/ mouse-y 2) 10) (+ (/ mouse-y 2) 10))
  (fill 255 204)
  (define inverse-x (- width  mouse-x))
  (define inverse-y (- height mouse-y))
  (rect inverse-x (/ height 2)  (+ (/ inverse-y 2) 10) (+ (/ inverse-y 2) 10)))

3.3.3 Mouse Press

basics/input/mouse-press.js
#lang sketching
; Move the mouse to position the shape. 
; Press the mouse button to invert the color.
 
(define (setup)
  (size 640 360)
  (no-smooth)
  (fill 126)
  (background 102))
 
(define (draw-cross x y)
  (line (- x 66)    y       (+ x 66)    y)
  (line    x     (- y 66)      x     (+ y 66)))
 
(define (draw)
  (if mouse-pressed (stroke 255) (stroke 0))
  (draw-cross mouse-x mouse-y))

3.3.4 Mouse Signals

basics/input/mouse-signals.js
#lang sketching
; Mouse Signals.
 
; Move and click the mouse to generate signals. 
; The top row is the signal from "mouseX", 
; the middle row is the signal from "mouseY",
; and the bottom row is the signal from "mousePressed". 
 
(define w 640) ; width
(define h 360) ; height
 
(define xs (make-vector w))
(define ys (make-vector w))
(define bs (make-vector w))
 
(define (setup)  
  (size 640 360)
  (frame-rate 30)
  (stroke-weight 16))
 
(define (draw)
  (background 102)
  (stroke-weight 2)
 
  ; shift all values left
  (for ([i (in-range 1 w)])
    (:= xs (- i 1) (xs.ref i))
    (:= ys (- i 1) (ys.ref i))
    (:= bs (- i 1) (bs.ref i)))
 
  ; enter new values at the right
  (:= xs (- w 1) mouse-x)
  (:= ys (- w 1) mouse-y)
 
  (if mouse-pressed
      (:= bs (- w 1) 0)
      (:= bs (- w 1) (/ height 3)))
  
  (fill 255)
  (no-stroke)
  (rect 0 (/ height 3) width (+ (/ height 3) 1))
 
  (for ([i (in-range 1 width)])
    ; draw x-values
    (stroke 255)
    (point i (remap (xs.ref i) 0 width 0 (- (/ height 3) 1)))
    ; draw y-values
    (stroke 0)
    (point i (+ (/ height 3) (/ (ys.ref i) 3)))
    ; draw mouse presses
    (stroke 255)
    (line i (+ (* 2/3 height) (bs.ref i))
          i (+ (* 2/3 height) (bs.ref (- i 1))))))

3.3.5 Easing

basics/input/easing.js
#lang sketching
; Easing. 
 
; Move the mouse across the screen and the symbol will follow.  
; Between drawing each frame of the animation, the program
; calculates the difference between the position of the 
; symbol and the cursor. If the distance is larger than
; 1 pixel, the symbol moves part of the distance (0.05) from its
; current position toward the cursor. 
 
(define x 0.)
(define y 0.)
(define easing 0.05)
 
(define (setup)
  (size 640 360)
  (frame-rate 60)
  (no-stroke))
 
(define (draw)
  (background 51)
  
  (define target-x mouse-x)
  (define dx (- target-x x))
  (+= x (* dx easing))
 
  (define target-y mouse-y)
  (define dy (- target-y y))
  (+= y (* dy easing))
  
  (ellipse x y 66 66))
 

3.3.6 Constrain

basics/input/constrain.js
#lang sketching
; Constrain.
 
; Move the mouse across the screen to move the circle. 
; The program constrains the circle to its box. 
 
(define easing   0.05)
(define radius  24)
(define edge   100)
(define inner  (+ edge radius))
 
(define mx 0.)
(define my 0.)
 
(define (setup)
  (size 640 360)
  (frame-rate 60)
  (no-stroke)
  (ellipse-mode 'radius)
  (rect-mode 'corners))
 
(define (draw)
  (background 51)
 
  (when (> (abs (- mouse-x mx)) 0.1)
    (:= mx (+ mx (* (- mouse-x mx) easing))))
 
  (when (> (abs (- mouse-y my)) 0.1)
    (:= my (+ my (* (- mouse-y my) easing))))
 
  (set! mx (constrain mx inner (- width  inner)))
  (set! my (constrain my inner (- height inner)))
 
  (fill 76)
  (rect edge edge (- width edge) (- height edge))
  (fill 255)
  (ellipse mx my radius radius))
 

3.3.7 Storing Input

basics/input/storing-input.js
#lang sketching
; Storing Input.
 
; Move the mouse across the screen to change the position
; of the circles. The positions of the mouse are recorded
; into an array and played back every frame. Between each
; frame, the newest value are added to the end of each array
; and the oldest value is deleted. 
 
(define n 60)
(define mx (make-vector n 0.0))
(define my (make-vector n 0.0))
 
 
(define (setup)
  (size 640 360)
  (frame-rate 60))
 
(define (draw)
  (background 51)
  (no-stroke)
  (fill 255 153)
 
  ; The arrays are used as circular buffers.
  ; This way we don't need to move anything.
  (define which (modulo frame-count n))
  (:= mx which mouse-x)
  (:= my which mouse-y)
 
  (for ([i n])
    ; which+1 is the index of the oldest entry
    (define index (modulo (+ which 1 i) n))
    (ellipse (mx.ref index) (my.ref index) i i)))

3.3.8 Mouse Functions

basics/input/mouse-functions.js
#lang sketching
; Mouse Functions.
 
; Click on the box and drag it across the screen. 
 
(define bx         0) ; center of box
(define by         0)
(define box-size  75) ; box radius
 
(define locked?   #f) 
(define x-offset   0) ; mouse position relative to center of box
(define y-offset   0)
 
(define (setup)
  (size 640 360)
  (:= bx (/ width 2.))
  (:= by (/ width 2.))
  (rect-mode 'radius))
 
(define (in-the-box? x y)
  (and (< (- bx box-size) x (+ bx box-size))
       (< (- by box-size) y (+ by box-size))))
       
(define (draw)
  (background 0)
  (cond
    [(and (in-the-box? mouse-x mouse-y) locked?)
     (stroke 255)
     (fill   255)]    
    [(and (in-the-box? mouse-x mouse-y) (not locked?))
     (stroke 255)
     (fill   153)]
    [else
     (stroke 153)
     (fill   153)])
  
  (rect bx by box-size box-size))
 
(define (on-mouse-pressed)
  (:= locked?  (in-the-box? mouse-x mouse-y))
  (:= x-offset (- mouse-x bx))
  (:= y-offset (- mouse-y by)))
 
(define (on-mouse-dragged)
  (when locked?
    (:= bx (- mouse-x x-offset))
    (:= by (- mouse-y y-offset))))
 
(define (on-mouse-released)
  (:= locked? #f))

3.3.9 Keyboard

basics/input/keyboard.js
#lang sketching
; Keyboard.
 
; Click on the image to give it focus and press the letter keys 
; to create forms in time and space. Each key has a unique identifying 
; number. These numbers can be used to position shapes in space. 
 
(define rect-width 0)
 
(define (setup)
  (size 640 360)
  (no-stroke)
  (background 0)
  (:= rect-width (/ width 4)))
 
(define (draw)
  (void))
 
(define (on-key-pressed)
  (define c key)
  (cond
    [(and (char? c) (char-alphabetic? c))
     (define key-index (- (int (char-downcase c)) (int #\a)))
     (fill (modulo (millis) 255)) ; color depends on time
     (define x (remap key-index 0 25 0 (- width rect-width)))
     (rect x 0 rect-width height)]
    [else
     ; blank the scren on non-letters
     (background 0)]))

3.3.10 Keyboard Functions

basics/input/keyboard-functions.js
#lang sketching
; Keyboard Functions.
 
; "Color Typewriter" is an art installation by John Maeda.
;   https://www.ntticc.or.jp/en/archive/works/color-typewriter/
; Martin Gomez were inspired and wrote a Processing version,
; which in modified form became an example in the Processing manual.
; That example was then ported to Sketching.
 
; Click on the window to give it focus and press the letter keys to type colors. 
; The keyboard function on-key-pressed is called whenever a key is pressed.
; The functions on-key-released is called when a key is released.
 
(define max-height 40)
(define min-height 20)
(define letter-height max-height)
(define letter-width  20)
 
(define x (- letter-width)) ; position of the next letter
(define y 0)
 
(define new-letter? #t)
 
(define n      26)                ; There are 26 letters in the alphabet
(define colors (make-vector n 0)) ; each key has a color 
 
(define (setup)
  (size 640 360)
  (no-stroke)
  (color-mode 'hsb n)
  (background (/ n 2))
  ; set hue for each key
  (for ([i (in-range n)])
    (:= colors i (color i n n))))
 
(define (draw)
  (when (= frame-count 0)
    (no-stroke)
    (background "cyan"))
  (when new-letter?
    (cond
      [(= letter-height max-height)
       (rect x y letter-width letter-height)]
      [else
       (define y1 (+ y min-height))
       (rect x y1 letter-width letter-height)
       (fill "cyan")
       (rect x (- y1 min-height) letter-width letter-height)])
    (:= new-letter? #f)))
 
(define (on-key-pressed)
  ; tell draw we have a new letter
  (:= new-letter? #t)
  ; 
  (cond
    [(and (char? key)
          (<= (int #\a) (int (char-downcase key)) (int #\z)))
     (define key-index (- (int (char-downcase key)) (int #\a)))
     (fill (colors.ref key-index))
     (:= letter-height
         (if (char-upper-case? key) max-height min-height))]
    [else
     (fill 0)
     (:= letter-height 10)])
 
  ; update letter position
  (:= x (+ x letter-width))
 
  ; wrap horizontally
  (when (> x (- width letter-width))
    (:= x 0)
    (+= y max-height))
 
  ; wrap vertically
  (when (> y (- height letter-height))
    (:= y 0)))

3.3.11 Milliseconds

basics/input/milliseconds.js
#lang sketching
; Milliseconds. 
 
; A millisecond is 1/1000 of a second. 
; Processing keeps track of the number of milliseconds a program has run.
; By modifying this number with the modulo, different patterns in time are created.
 
(define scale 1)
 
(define (setup)
  (size 640 360)
  (frame-rate 30)
  (:= scale (/ width 20)))
 
(define (draw)
  (no-stroke)
  (for ([i (in-range scale)])
    (define n (* (+ i 1) scale 10))
    (color-mode 'rgb n)
    (fill (modulo (millis) n))
    (rect (* i scale) 0 scale height)))

3.3.12 Clock

basics/input/clock.js
#lang sketching
; Clock. 
;  
;  The current time can be read with the second(), minute(), 
;  and hour() functions. In this example, sin() and cos() values
;  are used to set the position of the hands.
 
(define w 640)
(define h 360)
 
(define cx (/ w 2))
(define cy (/ h 2))
 
(define radius         (/ (min w h) 2))
(define seconds-radius (* 0.72 radius))
(define minutes-radius (* 0.60 radius))
(define hours-radius   (* 0.50 radius))
(define clock-diameter (* 1.80 radius))
 
(define (setup)
  (size 640 360)
  (frame-rate 1)
  (stroke 255))
 
(define (draw)
  (background 0)
 
  ; draw clock background
  (fill 80)
  (no-stroke)
  (ellipse cx cy clock-diameter clock-diameter)
 
  ; Angles for sin() and cos() start at 3 o'clock;
  ; subtract pi/2 to make them start at the top
  (define s (- (remap (second)                        0 60 0 2pi) pi/2))
  (define m (- (remap (minute)                        0 60 0 2pi) pi/2))
  (define h (- (remap (+ (hour) (norm (minute) 0 60)) 0 24 0 2pi) pi/2))
 
  ; Draw the hands of the clock  
  (stroke 255)
  (stroke-weight 1)
  (line cx cy (+ cx (* (cos s) seconds-radius)) (+ cy (* (sin s) seconds-radius)))
  (stroke-weight 2)
  (line cx cy (+ cx (* (cos m) minutes-radius)) (+ cy (* (sin m) minutes-radius)))
  (stroke-weight 4)
  (line cx cy (+ cx (* (cos h) hours-radius))   (+ cy (* (sin h) hours-radius)))
    
  ; Draw the minute ticks
  (stroke-weight 2)
  (for ([a (in-range 0 360 6)])
    (define angle (radians a))
    (define x (+ cx (* (cos angle) seconds-radius)))
    (define y (+ cy (* (sin angle) seconds-radius)))
    (point x y)))

3.4 Transform

The examples using transformations are:

    3.4.1 Translate

    3.4.2 Scale

    3.4.3 Rotate

    3.4.4 Arm

3.4.1 Translate

basics/transform/translate.js
#lang sketching
; Translate.
 
;  The translate function moves the position of (0,0).
;  If you draw an object (in this example a rectangle) relative
;  to (0,0), you can use translate to move the position of the object.
 
(define x    0.0)
(define y    0.0)
 
(define dim 80.0)
 
(define (setup)
  (size 640 360)
  (frame-rate 60)
  (rect-mode 'center))
 
(define (draw)
  (background 102)
  (no-stroke)
  
  (:= x (+ x 0.8))
  (when (> x (+ width dim))
    (:= x (- dim)))
  
  (translate x (- (/ height 2) (/ dim 2)))
  (fill 255)
  (rect 0 0 dim dim)
  
  ; Transforms accumulate. Notice how this rect moves 
  ; twice as fast as the other, but it has the same 
  ; argument for the x-axis value
  (translate x dim)
  (fill 0)
  (rect 0 0 dim dim))

3.4.2 Scale

basics/transform/scale.js
#lang sketching
; Scale 
;  Original Processing example by Denis Grutze.
 
(define a 0.0)
(define s 0.0)
 
(define (setup)
  (size 640 360)
  (rect-mode 'center)
  (no-stroke)
  (frame-rate 30))
 
(define (draw)
  (background 102)
 
  (:= a (+ a 0.04))
  (:= s (* 2 (cos a)))
  
  (translate (* 1/2 width) (* 1/2 height))
  (scale s)
  (fill 51)
  (rect 0 0 50 50)
  
  (translate 75 0)
  (fill 255)
  (scale s)
  (rect 0 0 50 50))

3.4.3 Rotate

basics/transform/rotate.js
#lang sketching
; Rotate. 
 
;  Rotating a square around the Z axis. To get the results
;  you expect, send the rotate function angle parameters that are
;  values between 0 and PI*2 (TWO_PI which is roughly 6.28). If you prefer to 
;  think about angles as degrees (0-360), you can use the radians() 
;  method to convert your values. For example: scale(radians(90))
;  is identical to the statement scale(PI/2). 
 
(define angle  0.0)
(define jitter 0.0)
 
(define (setup)
  (size 640 360)
  (frame-rate 60)
  (no-stroke)
  (fill 255)
  (rect-mode 'center))
 
(define (draw)
  (background 51)
 
  ; during even-numbered seconds (0, 2, 4, 6...)
  (when (even? (second))
    (:= jitter (random -0.1 0.1)))
  (:= angle (+ angle jitter))
  
  (define c (cos angle))
  (translate (* 1/2 width) (* 1/2 height))
  (rotate c)
  (rect 0 0 180 180))

3.4.4 Arm

basics/transform/arm.js
#lang sketching
; Arm.
 
;  The angle of each segment is controlled with the mouseX and
;  mouseY position. The transformations applied to the first segment
;  are also applied to the second segment because they are inside
;  the same pushMatrix() and popMatrix() group.
 
(define x      0.0)
(define y      0.0)
(define angle1 0.0)
(define angle2 0.0)
 
(define seg-length 100)
 
(define (setup)
  (size 640 360)
  (stroke-weight 30)
  (stroke 255 160)
 
  (:= x (* 0.3 width))
  (:= y (* 0.5 height)))
 
(define (draw)
  (background 0)
 
  (define angle1 (* -1 π (- (/ mouse-x width)  0.5)))
  (define angle2 (* -1 π (- (/ mouse-y height) 0.5)))
 
  (push-matrix)
  (segment x y angle1)
  (segment seg-length 0 angle2)
  (pop-matrix))
 
(define (segment x y a)
  (translate x y)
  (rotate a)
  (line 0 0 seg-length 0))

3.5 Typography

The typography examples are:

    3.5.1 Letters

    3.5.2 Words

    3.5.3 Text Rotation

3.5.1 Letters

basics/typography/letters.js
#lang sketching
; Letters.
 
;  Draws letters to the screen. 
 
(define (setup)
  (size 640 360)
  (background 0)
 
  (text-face "Tahoma")
  (text-size 24)
  (text-align 'center 'center))
 
(define (draw)
  ; set the left and top marings
  (define margin 10)
  (translate (* 4 margin) (* 4 margin))
 
  (define gap     46)
  (define counter 35)
 
  (for ([y (in-range 0 (- height gap) gap)])
    (for ([x (in-range 0 (- width gap) gap)])
      ; Current letter
      (define letter (char counter))
      ; Color wovel and consonants differently
      (case (char-downcase letter)
        [(#\a #\e #\i #\o #\u) (fill 255 204 0)]
        [else                  (fill 255)])
      ; Draw the letter
      (text letter x y)
      ; Increment the counter
      (++ counter))))

3.5.2 Words

basics/typography/words.js
#lang sketching
; Words. 
 
;  The text() function is used for writing words to the screen.
;  The letters can be aligned left, center, or right with the 
;  textAlign() function. 
 
(define (setup)
  (size 640 360)
  (text-face "Arial")
  (text-size 24))
 
(define (draw)
  (background 102)
  (text-align 'right)
  (draw-type (* 0.25 width))
  (text-align 'center)
  (draw-type (* 0.50 width))
  (text-align 'left)
  (draw-type (* 0.75 width)))
  
(define (draw-type x)
  (line x   0  x 65)
  (line x 220  x height)
  (fill 0)
  (text "ichi" x 95)
  (fill 51)
  (text "ni" x 140)
  (fill 204)
  (text "san" x 165)
  (fill 255)
  (text "shi" x 210))

3.5.3 Text Rotation

basics/typography/text-rotation.js
#lang sketching
; Text Rotation. 
 
; Draws letters to the screen and rotates them at different angles.
 
(define angle 0.0) ; the rotation angle
 
(define (setup)
  (size 640 360)
  (frame-rate 10)
  (text-size 18)
  (background 0))
 
(define (draw)
  (background 0)
  ; (smoothing 'unsmoothed)
  ; (text-smoothing 'unsmoothed)
 
  (stroke-weight 1)
  (stroke 153)
 
  (push-matrix)
  (define angle1 (radians 45))
  (translate 100 180)
  (rotate angle1)
  (text "45 DEGREES" 0 0)
  (line 0 0 150 0)
  (pop-matrix)
 
  (push-matrix)
  (define angle2 (radians 270))
  (translate 200 180)
  (rotate angle2)
  (text "270 DEGREES" 0 0)
  (line 0 0 150 0)
  (pop-matrix)
 
  (push-matrix)
  (translate 440 180)
  (rotate (radians angle))
  (text (~a (modulo (int angle) 360) " DEGREES") 0 0)
  (line 0 0 150 0)
  (pop-matrix)
  
  (+= angle 0.25)
      
  (stroke 255 0 0)
  (stroke-weight 4)
  (point 100 180)
  (point 200 180)
  (point 440 180))

3.6 Vectors

The examples using vectors are:

    3.6.1 Vectors

    3.6.2 Vector 2d

    3.6.3 Vector of objects

3.6.1 Vectors

basics/vectors/vector.js
#lang sketching
;  Vector. 
 
;  Vectors are zero based, which means that the first 
;  element in the array has index 1, the second element 1, and so on. 
;  In this example, a vector named "coswave" is created and filled
;  with cosine values. This data is displayed three  separate ways on the screen.  
 
(define w 640)
(define h 360)
 
(define y1 #f)
(define y2 #f)
 
(define coswave (for/vector ([i w]) (abs (cos (remap i 0 w 0 pi)))))
 
(define (setup)
  (size 640 360)
  (background 255)
  (no-loop))
 
(define (draw)
  (:= y1 0)
  (:= y2 (* 1/3 height))
  (for ([i w] [c coswave])
    (stroke (* c 255))
    (line i y1 i y2))
 
  (:= y1 y2)
  (:= y2 (+ y1 y1))
  (for ([i w] [c coswave])
    (stroke (* 1/2 (* c 255)))
    (line i y1 i y2))
 
  (:= y1 y2)
  (:= y2 height)
  (for ([i w] [c coswave])
    (stroke (- 255 (* c 255)))
    (line i y1 i y2)))

3.6.2 Vector 2d

basics/vectors/vector-2d.js
#lang sketching
; Two-dimensional vector
 
;  Demonstrates the syntax for creating a two-dimensional (2D) array.
;  Values in a 2D array are accessed through two index values.  
;  2D arrays are useful for storing images. In this example, each dot 
;  is colored in relation to its distance from the center of the image. 
 
(define w   640)
(define h   360)
(define w/2 (* 1/2 w))
(define h/2 (* 1/2 h))
 
(define spacer 10)
 
(define max-distance (dist w/2 h/2 w h))
(define distances
  (for/vector ([x w])
    (for/vector ([y h])
      ; distance from screen center to (x,y)
      (remap (dist x y w/2 h/2)
             0 max-distance 0 255))))
 
(define (setup)
  (size w h)
  (stroke-weight 6)
  (no-loop)) ; run draw only once
 
(define (draw)
  (background 0)
  ; This embedded loop skips over values in the arrays based on
  ; the spacer variable, so there are more values in the array
  ; than are drawn here. Change the value of the spacer variable
  ; to change the density of the points
  (for ([y (in-range 0 height spacer)])
    (for ([x (in-range 0 width spacer)])
      (define ys (distances.ref x))
      (