logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://anongit.hacktivis.me/git/pleroma-fe.git/

theme3_slot_functions.js (6105B)


  1. import { convert, brightness } from 'chromatism'
  2. import { alphaBlend, getTextColor, relativeLuminance } from '../color_convert/color_convert.js'
  3. export const process = (text, functions, { findColor, findShadow }, { dynamicVars, staticVars }) => {
  4. const { funcName, argsString } = /\$(?<funcName>\w+)\((?<argsString>[#a-zA-Z0-9-,.'"\s]*)\)/.exec(text).groups
  5. const args = argsString.split(/ /g).map(a => a.trim())
  6. const func = functions[funcName]
  7. if (args.length < func.argsNeeded) {
  8. throw new Error(`$${funcName} requires at least ${func.argsNeeded} arguments, but ${args.length} were provided`)
  9. }
  10. return func.exec(args, { findColor, findShadow }, { dynamicVars, staticVars })
  11. }
  12. export const colorFunctions = {
  13. alpha: {
  14. argsNeeded: 2,
  15. documentation: 'Changes alpha value of the color only to be used for CSS variables',
  16. args: [
  17. 'color: source color used',
  18. 'amount: alpha value'
  19. ],
  20. exec: (args, { findColor }, { dynamicVars, staticVars }) => {
  21. const [color, amountArg] = args
  22. const colorArg = convert(findColor(color, { dynamicVars, staticVars })).rgb
  23. const amount = Number(amountArg)
  24. return { ...colorArg, a: amount }
  25. }
  26. },
  27. brightness: {
  28. argsNeeded: 2,
  29. document: 'Changes brightness/lightness of color in HSL colorspace',
  30. args: [
  31. 'color: source color used',
  32. 'amount: lightness value'
  33. ],
  34. exec: (args, { findColor }, { dynamicVars, staticVars }) => {
  35. const [color, amountArg] = args
  36. const colorArg = convert(findColor(color, { dynamicVars, staticVars })).hsl
  37. colorArg.l += Number(amountArg)
  38. return { ...convert(colorArg).rgb }
  39. }
  40. },
  41. textColor: {
  42. argsNeeded: 2,
  43. documentation: 'Get text color with adequate contrast for given background and intended text color. Same function is used internally',
  44. args: [
  45. 'background: color of backdrop where text will be shown',
  46. 'foreground: intended text color',
  47. `[preserve]: (optional) intended color preservation:
  48. 'preserve' - try to preserve the color
  49. 'no-preserve' - if can't get adequate color - fall back to black or white
  50. 'no-auto' - don't do anything (useless as a color function)`
  51. ],
  52. exec: (args, { findColor }, { dynamicVars, staticVars }) => {
  53. const [backgroundArg, foregroundArg, preserve = 'preserve'] = args
  54. const background = convert(findColor(backgroundArg, { dynamicVars, staticVars })).rgb
  55. const foreground = convert(findColor(foregroundArg, { dynamicVars, staticVars })).rgb
  56. return getTextColor(background, foreground, preserve === 'preserve')
  57. }
  58. },
  59. blend: {
  60. argsNeeded: 3,
  61. documentation: 'Alpha blending between two colors',
  62. args: [
  63. 'background: bottom layer color',
  64. 'amount: opacity of top layer',
  65. 'foreground: upper layer color'
  66. ],
  67. exec: (args, { findColor }, { dynamicVars, staticVars }) => {
  68. const [backgroundArg, amountArg, foregroundArg] = args
  69. const background = convert(findColor(backgroundArg, { dynamicVars, staticVars })).rgb
  70. const foreground = convert(findColor(foregroundArg, { dynamicVars, staticVars })).rgb
  71. const amount = Number(amountArg)
  72. return alphaBlend(background, amount, foreground)
  73. }
  74. },
  75. boost: {
  76. argsNeeded: 2,
  77. documentation: 'If given color is dark makes it darker, if color is light - makes it lighter',
  78. args: [
  79. 'color: source color',
  80. 'amount: how much darken/brighten the color'
  81. ],
  82. exec: (args, { findColor }, { dynamicVars, staticVars }) => {
  83. const [colorArg, amountArg] = args
  84. const color = convert(findColor(colorArg, { dynamicVars, staticVars })).rgb
  85. const amount = Number(amountArg)
  86. const isLight = relativeLuminance(color) < 0.5
  87. const mod = isLight ? -1 : 1
  88. return brightness(amount * mod, color).rgb
  89. }
  90. },
  91. mod: {
  92. argsNeeded: 2,
  93. documentation: 'Old function that increases or decreases brightness depending if background color is dark or light. Advised against using it as it might give unexpected results.',
  94. args: [
  95. 'color: source color',
  96. 'amount: how much darken/brighten the color'
  97. ],
  98. exec: (args, { findColor }, { dynamicVars, staticVars }) => {
  99. const [colorArg, amountArg] = args
  100. const color = convert(findColor(colorArg, { dynamicVars, staticVars })).rgb
  101. const amount = Number(amountArg)
  102. const effectiveBackground = dynamicVars.lowerLevelBackground
  103. const isLightOnDark = relativeLuminance(convert(effectiveBackground).rgb) < 0.5
  104. const mod = isLightOnDark ? 1 : -1
  105. return brightness(amount * mod, color).rgb
  106. }
  107. }
  108. }
  109. export const shadowFunctions = {
  110. borderSide: {
  111. argsNeeded: 3,
  112. documentation: 'Simulate a border on a side with a shadow, best works on inset border',
  113. args: [
  114. 'color: border color',
  115. 'side: string indicating on which side border should be, takes either one word or two words joined by dash (i.e. "left" or "bottom-right")',
  116. 'width: border width (thickness)',
  117. '[alpha]: (Optional) border opacity, defaults to 1 (fully opaque)',
  118. '[inset]: (Optional) whether border should be on the inside or outside, defaults to inside'
  119. ],
  120. exec: (args) => {
  121. const [color, side, alpha = '1', widthArg = '1', inset = 'inset'] = args
  122. const width = Number(widthArg)
  123. const isInset = inset === 'inset'
  124. const targetShadow = {
  125. x: 0,
  126. y: 0,
  127. blur: 0,
  128. spread: 0,
  129. color,
  130. alpha: Number(alpha),
  131. inset: isInset
  132. }
  133. side.split('-').forEach((position) => {
  134. switch (position) {
  135. case 'left':
  136. targetShadow.x = width * (inset ? 1 : -1)
  137. break
  138. case 'right':
  139. targetShadow.x = -1 * width * (inset ? 1 : -1)
  140. break
  141. case 'top':
  142. targetShadow.y = width * (inset ? 1 : -1)
  143. break
  144. case 'bottom':
  145. targetShadow.y = -1 * width * (inset ? 1 : -1)
  146. break
  147. }
  148. })
  149. return [targetShadow]
  150. }
  151. }
  152. }