Animation

Animating with {nara} is simply a matter of generating and displaying multiple images - hopefully quickly enough to look smooth.

There are two approaches:

  1. Render all the images into a list, and then save as a video file e.g. .gif, .mp4
  2. Display the images to a fast graphics device

Render to a video file

To render to a video file, {nara} use nrs_to_gif() and nrs_to_mp4(). These functions are simple wrappers around the {magick} package.

The code below:

library(nara)
w <- 320
h <- 200

set.seed(1)
N <- 20
xs   <- runif(N, 0, w)
ys   <- runif(N, 0, h)
rs   <- runif(N, 2, 6)  
vx   <- rnorm(N, sd = 3)
cols <- sample(heat.colors(N))

# Storage for animation frames
anim <- list()

for (i in seq(30)) {
  # create image
  nr <- nr_new(w, h, fill = 'grey90')
  
  # update the x position and wraparound
  xs <- xs + vx
  xs <- ifelse(xs < 0, xs + w, xs)
  xs <- ifelse(xs > w, xs - w, xs)
  
  # draw circles
  nr_circle(nr, xs, ys, rs, cols)
  
  # store animatino frame
  anim[[i]] <- nr  
}

nrs_to_gif(anim, "working/demo.gif")
# nrs_to_mp4(anim, "working/demo.mp4")

Render to a fast graphics device

If your graphics device updates fast enough, then you can show images on this device quickly and have the appearance on smooth animation.

A major problem for most platforms: Rstudio and Positron graphics devices are not fast enough to do this

Instead, if you are wanting to use a built-in graphics device, the x11() device is the preferred graphics output for animation.

x11() device is supported on macos, linux and windows (where it a lightweight wrapper around the standard windows() device).

A good way to setup this device for fast animation is to:

  1. Call x11()
  2. Set the type to double buffered Cairo rendering type = 'dbcairo'
  3. Disable the display list as there’s no need to record graphics operations
  4. Use dev.hold() and dev.flush() calls to synchronise the drawing command with the graphics display update (this can prevent tearing).
  5. A small pause may be needed in the loop, otherwise things might go too fast!

See code below for an example:

x11(..., type = 'dbcairo', antialias = 'none')
dev.control(displaylist = 'inhibit')

for (i in seq(nframes)) {
  nr <- generate_image_somehow()
  dev.hold()
  plot(nr)
  dev.flush()
  Sys.sleep(0.03) # Sleep maybe?
}

Note: Particular platforms may have differing parameters to give good results for realtime animation - you might need to experiment to get the best out of your platform.