😎 Give your xaringan slides some style
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

111 lines
3.7KB

  1. #' @title Generate lighter or darker version of a color
  2. #' @description Produces a linear blend of the color with white or black.
  3. #' @param color_hex A character string representing a hex color
  4. #' @param strength The "strength" of the blend with white or black,
  5. #' 0 low to 1 high.
  6. #' @name lighten_darken_color
  7. NULL
  8. #' @rdname lighten_darken_color
  9. #' @export
  10. lighten_color <- function(color_hex, strength = 0.7) {
  11. stopifnot(strength >= 0 && strength <= 1)
  12. color_rgb <- col2rgb(color_hex)[, 1]
  13. color_rgb <- (1 - strength) * color_rgb + strength * 255
  14. rgb(color_rgb[1], color_rgb[2], color_rgb[3], maxColorValue = 255)
  15. }
  16. #' @rdname lighten_darken_color
  17. #' @export
  18. darken_color <- function(color_hex, strength = 0.8) {
  19. stopifnot(strength >= 0 && strength <= 1)
  20. color_rgb <- col2rgb(color_hex)[, 1]
  21. color_rgb <- (1 - strength) * color_rgb
  22. rgb(color_rgb[1], color_rgb[2], color_rgb[3], maxColorValue = 255)
  23. }
  24. #' @title Add alpha to hex color
  25. #' @description Applies alpha (or opacity) to a color in hexadecimal form by
  26. #' converting opacity in the `[0, 1]` range to hex in the `[0, 255]` range
  27. #' and appending to the hex color.
  28. #' @inheritParams lighten_darken_color
  29. #' @param opacity Desired opacity of the output color
  30. #' @export
  31. apply_alpha <- function(color_hex, opacity = 0.5) {
  32. paste0(color_hex, as.hexmode(round(255 * opacity, 0)))
  33. }
  34. adjust_value_color <- function(color_hex, strength = 0.5) {
  35. color_hsv <- rgb2hsv(col2rgb(color_hex))[, 1]
  36. color_hsv["v"] <- strength
  37. hsv(color_hsv[1], color_hsv[2], color_hsv[3])
  38. }
  39. #' Choose dark or light color
  40. #'
  41. #' Takes a color input as `x` and returns either the black or white color (or
  42. #' expression) if dark or light text should be used over the input color for
  43. #' best contrast. Follows W3C Recommendations.
  44. #'
  45. #' @references <https://stackoverflow.com/a/3943023/2022615>
  46. #' @param x The background color (hex)
  47. #' @param black Text or foreground color, e.g. "#222" or
  48. #' `substitute(darken_color(x, 0.8))`, if black text provides the best contrast.
  49. #' @param white Text or foreground color or expression, e.g. "#EEE" or
  50. #' `substitute(lighten_color(x, 0.8))`, if white text provides the best contrast.
  51. #' @export
  52. choose_dark_or_light <- function(x, black = "#000000", white = "#FFFFFF") {
  53. if (is_light_color(x)) eval(black) else eval(white)
  54. }
  55. is_light_color <- function(x) {
  56. # this function returns TRUE if the given color
  57. # is light-colored and requires dark text
  58. color_rgb <- col2rgb(x)[, 1]
  59. # from https://stackoverflow.com/a/3943023/2022615
  60. color_rgb <- color_rgb / 255
  61. color_rgb[color_rgb <= 0.03928] <- color_rgb[color_rgb <= 0.03928] / 12.92
  62. color_rgb[color_rgb > 0.03928] <- ((color_rgb[color_rgb > 0.03928] + 0.055) / 1.055)^2.4
  63. lum <- t(c(0.2126, 0.7152, 0.0722)) %*% color_rgb
  64. lum[1, 1] > 0.179
  65. }
  66. prepare_colors <- function(colors = NULL) {
  67. if (is.null(colors) || length(colors) < 1) return(NULL)
  68. if (is.null(names(colors))) {
  69. stop(
  70. "`colors` must have names corresponding to valid CSS classes",
  71. call. = FALSE
  72. )
  73. }
  74. if (any(grepl("\\s", names(colors)))) {
  75. stop(
  76. "Color names in `colors` must be valid CSS classes",
  77. " and cannot contain spaces",
  78. call. = FALSE)
  79. }
  80. if (any(grepl("[^[:alpha:]_-]", names(colors)))) {
  81. stop("Color names in `colors` must be valid CSS classes", call. = FALSE)
  82. }
  83. whisker::iteratelist(colors, "color_name")
  84. }
  85. full_length_hex <- function(x) {
  86. if (!grepl("^#", x) || grepl("[^#0-9a-fA-F]", x)) {
  87. stop(paste0('"', x, '" is not a hexadecimal color'))
  88. }
  89. x <- sub("^#", "", x)
  90. if (nchar(x) == 3) {
  91. x <- strsplit(x, character(0))[[1]]
  92. x <- rep(x, each = 2)
  93. x <- paste(x, collapse = "")
  94. } else if (nchar(x) != 6) {
  95. stop(paste0('"', x, '" is not a hexadecimal color'))
  96. }
  97. paste0("#", x)
  98. }