Skip to content

Instantly share code, notes, and snippets.

@yutannihilation
Created September 20, 2024 09:50
Show Gist options
  • Save yutannihilation/089a957f0b67b0cceb0b0ef0198079dc to your computer and use it in GitHub Desktop.
Save yutannihilation/089a957f0b67b0cceb0b0ef0198079dc to your computer and use it in GitHub Desktop.
library(string2path)
library(ggplot2)
library(dplyr)
# Note: it seems Noto Color Emoji has many variants. Only that of COLRv1 format
# is supported, so this might not work on installed font of Noto Color Emoji.
ttf <- "~/../Downloads/Noto_Color_Emoji/NotoColorEmoji-Regular.ttf"
d <- string2fill("🐯", ttf)
d2 <- string2path("🐯", ttf)
colours_orig <- unique(d2$color)
n_colours <- length(colours_orig)
colours <- purrr::flatten_chr(lapply(LETTERS[1:8], \(x) scales::pal_viridis(option = x)(n_colours)))
colours <- c(colours_orig, colours)
xlim <- range(d$x)
xlim <- xlim + diff(xlim) * c(-0.2, 0.2)
ylim <- range(d$y)
ylim <- ylim + diff(ylim) * c(-0.2, 0.2)
rotate_and_enlarge <- function(d, rot, scale) {
d |>
# 平行移動
mutate(
x = x - 0.5,
y = y - 0.3
) |>
# 回転と拡大
mutate(
x_new = scale * (x * cos(rot) - y * sin(rot)),
y_new = scale * (x * sin(rot) + y * cos(rot)),
) |>
mutate(
x = x_new + 0.5,
y = y_new + 0.3
)
}
steps <- 180
cycle <- 2
t <- \(x) pmax(x - steps * cycle * 0.2, 0)^1.2 / steps^1.2
png_path <- file.path(tempdir(), "frame%03d.png")
png(png_path, width = 800, height = 600)
for (i in 0:(steps * cycle)) {
phase <- t(i)
offset <- as.integer(n_colours * 8 * phase * 0.6) %% (n_colours * 9)
rot <- 2.0 * pi * phase
scale <- 1.0 + (1.0 * phase)^2
d_tmp <- rotate_and_enlarge(d, rot, scale)
d2_tmp <- rotate_and_enlarge(d2, rot, scale)
p <- ggplot() +
geom_polygon(data = d_tmp, aes(x, y, group = triangle_id, fill = color)) +
geom_path(data = d2_tmp, aes(x, y, group = path_id), colour = alpha("white", 0.7)) +
coord_equal(xlim = xlim, ylim = ylim) +
theme_minimal() +
scale_fill_manual(values = setNames(colours[offset:(offset+6)], nm = colours_orig))
plot(p)
}
dev.off()
png_files <- sprintf(png_path, (0:(steps * cycle) + 1))
gifski::gifski(png_files, delay = 1/60)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment