😎 Give your xaringan slides some style
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

145 lines
5.3KB

  1. `%||%` <- function(x, y) if (is.null(x)) y else x
  2. `%??%` <- function(x, y) if (!is.null(x)) y else NULL
  3. #' @title Generate lighter or darker version of a color
  4. #' @description Produces a linear blend of the color with white or black.
  5. #' @param color_hex A character string representing a hex color
  6. #' @param strength The "strength" of the blend with white or black,
  7. #' 0 low to 1 high.
  8. #' @name lighten_darken_color
  9. NULL
  10. #' @rdname lighten_darken_color
  11. #' @export
  12. lighten_color <- function(color_hex, strength = 0.7) {
  13. stopifnot(strength >= 0 && strength <= 1)
  14. color_rgb <- col2rgb(color_hex)[, 1]
  15. color_rgb <- (1 - strength) * color_rgb + strength * 255
  16. rgb(color_rgb[1], color_rgb[2], color_rgb[3], maxColorValue = 255)
  17. }
  18. #' @rdname lighten_darken_color
  19. #' @export
  20. darken_color <- function(color_hex, strength = 0.8) {
  21. stopifnot(strength >= 0 && strength <= 1)
  22. color_rgb <- col2rgb(color_hex)[, 1]
  23. color_rgb <- (1 - strength) * color_rgb
  24. rgb(color_rgb[1], color_rgb[2], color_rgb[3], maxColorValue = 255)
  25. }
  26. #' @title Add alpha to hex color
  27. #' @description Applies alpha (or opacity) to a color in hexadecimal form by
  28. #' converting opacity in the `[0, 1]` range to hex in the `[0, 255]` range
  29. #' and appending to the hex color.
  30. #' @inheritParams lighten_darken_color
  31. #' @param opacity Desired opacity of the output color
  32. #' @export
  33. apply_alpha <- function(color_hex, opacity = 0.5) {
  34. paste0(color_hex, as.hexmode(round(255*opacity, 0)))
  35. }
  36. adjust_value_color <- function(color_hex, strength = 0.5) {
  37. color_hsv <- rgb2hsv(col2rgb(color_hex))[, 1]
  38. color_hsv['v'] <- strength
  39. hsv(color_hsv[1], color_hsv[2], color_hsv[3])
  40. }
  41. #' Choose dark or light color
  42. #'
  43. #' Takes a color input as `x` and returns either the black or white color (or
  44. #' expression) if dark or light text should be used over the input color for
  45. #' best contrast. Follows W3C Recommendations.
  46. #'
  47. #' @references <https://stackoverflow.com/a/3943023/2022615>
  48. #' @param x The background color (hex)
  49. #' @param black Text or foreground color, e.g. "#222" or
  50. #' `substitute(darken_color(x, 0.8))`, if black text provides the best contrast.
  51. #' @param white Text or foreground color or expression, e.g. "#EEE" or
  52. #' `substitute(lighten_color(x, 0.8))`, if white text provides the best contrast.
  53. #' @export
  54. choose_dark_or_light <- function(x, black = "#000000", white = "#FFFFFF") {
  55. if (is_light_color(x)) eval(black) else eval(white)
  56. }
  57. is_light_color <- function(x) {
  58. # this function returns TRUE if the given color
  59. # is light-colored and requires dark text
  60. color_rgb <- col2rgb(x)[, 1]
  61. # from https://stackoverflow.com/a/3943023/2022615
  62. color_rgb <- color_rgb / 255
  63. color_rgb[color_rgb <= 0.03928] <- color_rgb[color_rgb <= 0.03928]/12.92
  64. color_rgb[color_rgb > 0.03928] <- ((color_rgb[color_rgb > 0.03928] + 0.055)/1.055)^2.4
  65. lum <- t(c(0.2126, 0.7152, 0.0722)) %*% color_rgb
  66. lum[1, 1] > 0.179
  67. }
  68. #' @keywords internal
  69. call_style_xaringan <- function() {
  70. paste0("style_xaringan(",
  71. paste(names(formals(style_xaringan)), collapse = ", "),
  72. ")")
  73. }
  74. #' Specify Google Font
  75. #'
  76. #' Builds Google Fonts URL from family name. Extra weights are given in the
  77. #' `...` parameters. Languages can be specified in `langauges` and must one or
  78. #' more of the language codes as given by `google_language_codes()`.
  79. #'
  80. #' @examples
  81. #' google_font("Josefin Sans", "400", "400i", "600i", "700")
  82. #' google_font("Josefin Sans", languages = c("latin-ext", "vietnamese"))
  83. #' @param family Font family
  84. #' @param ... Font weights to include, example "400", "400i"
  85. #' @param languages Font languages to include (dependent on the font.) See
  86. #' [google_language_codes()].
  87. #' @export
  88. google_font <- function(family, ..., languages = NULL) {
  89. base = "https://fonts.googleapis.com/css?family="
  90. weights <- if (length(list(...))) paste(c(...), collapse = ",")
  91. languages <- if (!is.null(languages)) paste(google_language_codes(languages), collapse = ",")
  92. structure(list(
  93. family = family,
  94. weights = weights,
  95. languages = languages,
  96. url = paste0(
  97. base, gsub(" ", "+", family),
  98. if (!is.null(weights)) paste0(":", weights),
  99. if (!is.null(languages)) paste0("&subset=", languages)
  100. )
  101. ), class = "google_font")
  102. }
  103. #' @title List Valid Google Language Codes
  104. #' @description Gives a list of valid Language Codes for Google Fonts, or
  105. #' validates that the language codes given are valid.
  106. #' @seealso [google_font()]
  107. #' @param language_codes Vector of potential Google language codes
  108. #' @export
  109. google_language_codes <- function(
  110. language_codes = c("latin", "latin-ext", "sinhala", "greek", "hebrew",
  111. "vietnamese", "cyrillic", "cyrillic-ext", "devanagari", "arabic", "khmer",
  112. "tamil", "greek-ext", "thai", "bengali", "gujarati", "oriya",
  113. "malayalam", "gurmukhi", "kannada", "telugu", "myanmar")
  114. ) {
  115. unique(match.arg(language_codes, several.ok = TRUE))
  116. }
  117. print.google_font <- function(x) {
  118. cat(
  119. "Family: ", x$family,
  120. if (!is.null(x$weights)) paste("\nWeights:", x$weights),
  121. if (!is.null(x$languages)) paste("\nLangs: ", x$languages),
  122. "\nURL: ", x$url
  123. )
  124. }
  125. quote_elements_w_spaces <- function(x) {
  126. x <- strsplit(x, ", ?")[[1]]
  127. has_space <- grepl("\\w \\w", x)
  128. not_quoted <- grepl("^\\w.+\\w$", x)
  129. x[has_space & not_quoted] <- paste0("'", x[has_space & not_quoted], "'")
  130. paste(x, collapse = ", ")
  131. }