This can be done by leveraging Presentation Mode with Coroutines. Here’s a working example:
import kotlinx.coroutines.delay
import org.openrndr.PresentationMode
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.olive.oliveProgram
import org.openrndr.launch
import org.openrndr.shape.Circle
fun main() = application {
configure {
width = 800
height = 800
windowAlwaysOnTop = true
}
oliveProgram {
val w = width * 1.0
val h = height * 1.0
window.presentationMode = PresentationMode.MANUAL
val frameRate = 24L
var prevTime = seconds
var deltaTime: Double
var lastUpdate = seconds
extend {
launch {
delay(1000L / frameRate)
window.requestDraw()
}
drawer.clear(ColorRGBa.BLACK)
drawer.stroke = ColorRGBa.PINK
drawer.strokeWeight = 14.0
for (i in 1..10) {
val sub = Circle(385.0, h / 2.0, 100.0).contour
val time = seconds * 0.1
val phase = (1.0 / 10.0) * i
drawer.contour(sub.sub(time + phase, phase + time + 0.05))
}
// LOGGING FRAME RATE
deltaTime = seconds - prevTime
prevTime = seconds
if (prevTime - lastUpdate > 1.0) {
println("FPS: ${(1.0 / deltaTime)}")
lastUpdate = prevTime
}
}
}
}
PS: I haven’t done extensive testing, so if there are any issues please share them.