Nothing
#' Generator for tweening components separately from each other
#'
#' This is a generator versions of [tween_components()]. It returns a generator
#' that can be used with [get_frame()] and [get_raw_frames()] to extract frames
#' for a specific time point scaled between 0 and 1.
#'
#' @inheritParams tween_components
#'
#' @return A `component_generator` object
#'
#' @family Other generators
#'
#' @export
#' @importFrom rlang eval_tidy enquo quo_is_null
#'
#' @examples
#' from_zero <- function(x) {x$x <- 0; x}
#'
#' data <- data.frame(
#' x = c(1, 2, 2, 1, 2, 2),
#' y = c(1, 2, 2, 2, 1, 1),
#' time = c(1, 4, 8, 4, 8, 10),
#' id = c(1, 1, 1, 2, 2, 2)
#' )
#'
#' gen <- gen_components(data, 'cubic-in-out', time = time, id = id,
#' enter = from_zero, enter_length = 4)
#'
#' get_frame(gen, 0.3)
gen_components <- function(.data, ease, nframes, time, id = NULL, range = NULL,
enter = NULL, exit = NULL, enter_length = 0,
exit_length = 0) {
time <- enquo(time)
time <- eval_tidy(time, .data)
id <- enquo(id)
id <- if (quo_is_null(id)) rep(1, nrow(.data)) else eval_tidy(id, .data)
if (is.null(enter_length)) enter_length <- 0
if (is.null(exit_length)) exit_length <- 0
.data$.phase <- NULL
if (length(ease) == 1) ease <- rep(ease, ncol(.data))
if (length(ease) == ncol(.data)) {
ease <- c(ease, 'linear') # To account for .phase column
} else {
stop('Ease must be either a single string or one for each column', call. = FALSE)
}
.data$.phase <- rep_len(factor("raw", levels = PHASE_LEVELS), nrow(.data))
class(.data) <- c(c("component_generator", "frame_generator"), class(.data))
gen_data <- .complete_components(.data, time, id, enter, exit, enter_length, exit_length)
time <- gen_data$.time
id <- gen_data$.id
gen_data$.time <- NULL
gen_data$.id <- NULL
d_order <- order(id, time)
if (is.null(range)) range <- range(time)
if (diff(range) == 0) stop('range cannot be 0', call. = FALSE)
generator_settings(.data) <- list(
data = gen_data[d_order, ],
id = id[d_order],
time = time[d_order],
range = range,
ease_type = ease,
col_types = col_classes(.data)
)
.data
}
#' @export
get_frame.component_generator <- function(generator, at, ...) {
d <- generator_settings(generator)
# clamp between 0 and 1
at <- min(max(at, 0), 1)
range <- d$range
# normalise to range
at <- (range[2] - range[1]) * at + range[1]
data <- gen_data(generator)
ease <- ease_type(generator)
type <- col_types(generator)
frame <- lapply(seq_along(data), function(i) {
col <- data[[i]]
e <- rep_len(ease[[i]], length(col))
switch(
type[i],
numeric = interpolate_numeric_element_at(col, d$id, d$time, at, e),
logical = interpolate_logical_element_at(col, d$id, d$time, at, e),
factor = interpolate_factor_element_at(col, d$id, d$time, at, e),
character = interpolate_character_element_at(col, d$id, d$time, at, e),
colour = interpolate_colour_element_at(col, d$id, d$time, at, e),
date = interpolate_date_element_at(col, d$id, d$time, at, e),
datetime = interpolate_datetime_element_at(col, d$id, d$time, at, e),
constant = interpolate_constant_element_at(col, d$id, d$time, at, e),
numlist = interpolate_numlist_element_at(col, d$id, d$time, at, e),
list = interpolate_list_element_at(col, d$id, d$time, at, e),
phase = get_phase_element_at(col, d$id, d$time, at, e)
)
})
structure(frame, names = names(data), row.names = .set_row_names(length(frame[[1]])), class = 'data.frame')
}
#' @export
get_raw_frames.component_generator <- function(generator, at, before = 0, after = 0, ...) {
d <- generator_settings(generator)
# clamp between 0 and 1
before <- min(max(at - before, 0), 1)
after <- min(max(at + after, 0), 1)
at <- min(max(at, 0), 1)
range <- d$range
# normalise to generator time
at <- (range[2] - range[1]) * at + range[1]
before <- (range[2] - range[1]) * before + range[1]
after <- (range[2] - range[1]) * after + range[1]
# Find before and after
before <- d$time >= before & d$time < at
after <- d$time > at & d$time <= after
raw <- d$data$.phase == 'raw'
list(
before = d$data[before & raw, , drop = FALSE],
after = d$data[after & raw, , drop = FALSE]
)
}
#' @export
convert_generator.component_generator <- convert_generator.along_generator
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.