|
5 | 5 | #' @export |
6 | 6 | toRGB <- function(x, alpha = 1) { |
7 | 7 | if (is.null(x)) return(x) |
8 | | - # as of ggplot2 version 1.1, an NA alpha is treated as though it's 1 |
9 | | - alpha[is.na(alpha)] <- 1 |
10 | | - # if we've already made the proper conversion, return the input |
11 | | - if (inherits(x, "plotly_rgba")) return(x) |
12 | | - if (inherits(x, "plotly_rgb")) { |
13 | | - if (all(alpha == 1)) return(x) |
14 | | - # all alpha channel |
15 | | - x <- sub("^rgb", "rgba", sub("\\)", paste0(",", alpha, ")"), x)) |
16 | | - return(prefix_class(x, "plotly_rgba")) |
| 8 | + if (any(x %in% "transparent")) return(x) |
| 9 | + # add alpha to already converted "rgb(x,y,z)" codes |
| 10 | + idx <- grepl("^rgba\\(", x) & alpha <= 1 & 0 <= alpha |
| 11 | + if (any(idx)) { |
| 12 | + x[idx] <- rgb2hex(x[idx]) |
17 | 13 | } |
18 | 14 | # for some reason ggplot2 has "NA" in some place (instead of NA) |
19 | 15 | if (is.character(x)) { |
20 | 16 | x[x == "NA"] <- NA |
21 | 17 | } |
22 | | - has_alpha <- all(0 <= alpha & alpha < 1) |
23 | | - rgb_matrix <- col2rgb(x, alpha = has_alpha) |
24 | | - # rescale alpha |
25 | | - # TODO: what if x already has an alpha channel??? |
26 | | - if (has_alpha) rgb_matrix["alpha", ] <- alpha |
27 | | - container <- if (has_alpha) "rgba(%s)" else "rgb(%s)" |
28 | | - rgb_a <- sprintf(container, apply(rgb_matrix, 2, paste, collapse = ",")) |
29 | | - rgb_a[is.na(x)] <- "transparent" |
30 | | - structure(rgb_a, class = if (has_alpha) "plotly_rgba" else "plotly_rgb") |
| 18 | + # as of ggplot2 version 1.1, an NA alpha is treated as though it's 1 |
| 19 | + alpha[is.na(alpha)] <- 1 |
| 20 | + rgb_matrix <- grDevices::col2rgb(x, alpha = TRUE) |
| 21 | + # multiply the existing alpha with specified alpha (both on 0-1 scale) |
| 22 | + rgb_matrix["alpha", ] <- alpha * scales::rescale( |
| 23 | + rgb_matrix["alpha", ], from = c(0, 255) |
| 24 | + ) |
| 25 | + rgb_matrix["alpha", ] <- round(rgb_matrix["alpha", ], 4) |
| 26 | + rgba <- sprintf("rgba(%s)", apply(rgb_matrix, 2, paste, collapse = ",")) |
| 27 | + rgba[is.na(x)] <- "transparent" |
| 28 | + rgba |
| 29 | +} |
| 30 | + |
| 31 | +# take a 'plotly color' and produce a hex code |
| 32 | +rgb2hex <- function(string = "rgba(255,255,255,1)") { |
| 33 | + vals <- sub("rgba\\(", "", sub("\\)", "", string)) |
| 34 | + valz <- strsplit(vals, ",") |
| 35 | + sapply(valz, function(x) { |
| 36 | + x <- setNames(as.numeric(x), c("red", "green", "blue", "alpha")) |
| 37 | + x[["alpha"]] <- x[["alpha"]] * 255 |
| 38 | + do.call(grDevices::rgb, c(x, list(maxColorValue = 255))) |
| 39 | + }) |
31 | 40 | } |
0 commit comments