5 Home
Öppenlab edited this page 2 weeks ago

Skiss Manual

Skiss Screenshot (Perlin noise + Lensing screenshot)

About

Skiss (Swedish: Sketch): an extremely basic 2D animation system for Android, it's very fast, smooth, and lightweight, and has a structure and syntax influenced by Processing.

Getting Started

  • .aar coming soon, for now clone the project and include the skisslib module in your own app.

  • Add a SkissView to your xml layout:

    <oppen.skiss.lib.SkissView
        android:id="@+id/skiss_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
  • Create a subclass of Skiss (see example below), pass in the view and start from your Activity/Fragment: DemoSkiss(skiss_view).start()

Example

The usual drawing primitives are built into Skiss but the standard Android View Canvas is also available:

import android.graphics.Canvas
import oppen.skiss.lib.Skiss
import oppen.skiss.lib.SkissView
import oppen.skiss.lib.color
import oppen.skiss.lib.random

class DemoSkiss(view: SkissView): Skiss(view) {

    private val background = color("#1d1d1d")
    private val red = color("#ff0000")
    private val pale = color("#55ffffff")
    private var y = 0f

    override fun setup(width: Int, height: Int) {}

    override fun update(canvas: Canvas) {
        background(background)

        y += 2
        if (y > height) y = 0f

        stroke(red)
        line(0f, y, width.toFloat(), y)

        noStroke()
        fill(pale)
        repeat(100) {
            circle(random(width), random(height), random(5, 40))
        }
    }
}

Documentation

Sketch Syntax

smooth() noSmooth()

Anti-aliasing is off by default, screens on modern devices are so high resolution it may not be needed at all. Skiss uses the same friendly syntax as Processing, turn anti-aliasing on in setup:

override fun setup(width: Int, height: Int) {
    smooth()
}

stroke(color) noStroke()

Stroke is used for lines, points, and shape borders. Supply a colour int for Skiss to draw with: stroke(aColour). Be sure to pre calculate the colour value as a class member, avoid any allocations in the update block (see performance below). Turn off stroke drawing with noStroke()

fill(color) noFill()

Same as stroke above but for shape fills, eg:

fill(red)
circle(100, 100, 20)

Vector

The Vector object includes Kotlin operator overloads, so you can have nice expressive syntax not available in Processing/Java, otherwise the implementation is very similar to PVector in Processing:

//Vector operator overload examples:
velocity *= speed
position += velocity

Shape Primitives

Skiss has draw operations for common shapes, most shapes have multiple implementations with different type arguments, be aware if you pass a Number the implementation will unbox (usually calling .toFloat):

point(x, y)

Draws a point using current stroke colour, args:

point(int, int)
point(float, float)
point(vector)

points(array)

Draws an array of points, args:

points(vectorList)
points(vectorArray)

line(x, y, x2, y2)

Draws a line using current stroke colour, args:

line(Vector, Vector)
line(float, float, float, float)
line(number, number, number, number)

lines(array)

Draws an array of lines described by a Pair<Vector, Vector>, args:

lines(vectorPairList)
lines(vectorPairArray)

circle(x, y, r)

Draws a circle at x, y of radius r:

circle(float, float, float)

//Using circle(Number, Number, Number)
circle(int, float, double)

square(x, y, d)

Draws a circle at x, y of diameter d:

circle(float, float, float)

//Using square(Number, Number, Number)
square(int, float, double)

Performance

Skiss uses Android's Choreographer to ensure frames are sync'd to the screen refresh, this keeps animations running smoothly but there are a few other things you can do to ensure there's no frame drops:

  • No allocations in the update loop, intialise as much as possible in the class constructor or setup.
  • Pause Skiss when user interacts with other elements on-screen (eg. when displaying a menu, see the demo MainActivity for an example):
    val skiss = DemoSkiss(skiss_view)
    skiss.start()
    
    ...
      
    //on some view click:
    skiss.pause()
    
  • Use an off-screen buffer when appropriate. Modern phone screens have a lot of pixels, if you're doing anything pixel based it'd be best to use a small offscreen buffer canvas. See the Metaballs demo for an example.

Development References

Various docs and articles used while developing Skiss: