From f4db0dbdd4c575bf1d7999b913f3d23be455b11b Mon Sep 17 00:00:00 2001 From: Pleroma User <66706-pleromian@users.noreply.git.pleroma.social> Date: Tue, 24 Jun 2025 12:35:50 +0000 Subject: [PATCH] Add arithmetic blend --- changelog.d/arithmetic-blend.add | 2 ++ src/services/color_convert/color_convert.js | 26 +++++++++++++++++++ .../theme_data/theme3_slot_functions.js | 21 +++++++++++++-- 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 changelog.d/arithmetic-blend.add diff --git a/changelog.d/arithmetic-blend.add b/changelog.d/arithmetic-blend.add new file mode 100644 index 000000000..c579dca28 --- /dev/null +++ b/changelog.d/arithmetic-blend.add @@ -0,0 +1,2 @@ +Add arithmetic blend ISS function + diff --git a/src/services/color_convert/color_convert.js b/src/services/color_convert/color_convert.js index 0e78b57af..aadbc90ff 100644 --- a/src/services/color_convert/color_convert.js +++ b/src/services/color_convert/color_convert.js @@ -95,6 +95,32 @@ export const getContrastRatioLayers = (text, layers, bedrock) => { return getContrastRatio(alphaBlendLayers(bedrock, layers), text) } +/** + * Blending of two solid colors with a user-defined operator: origin +- value + * + * @param {Object} origin - base color + * @param {Object} value - modification argument + * @param {string} operator - math operator to use + */ +export const arithmeticBlend = (origin, value, operator) => { + const func = (a, b) => { + switch (operator) { + case '+': + return Math.min(a + b, 255) + case '-': + return Math.max(a - b, 0) + default: + return a + } + } + + return { + r: func(origin.r, value.r), + g: func(origin.g, value.g), + b: func(origin.b, value.b), + } +} + /** * This performs alpha blending between solid background and semi-transparent foreground * diff --git a/src/services/theme_data/theme3_slot_functions.js b/src/services/theme_data/theme3_slot_functions.js index 137f19bf0..f534b19f4 100644 --- a/src/services/theme_data/theme3_slot_functions.js +++ b/src/services/theme_data/theme3_slot_functions.js @@ -1,8 +1,8 @@ import { convert, brightness } from 'chromatism' -import { alphaBlend, getTextColor, relativeLuminance } from '../color_convert/color_convert.js' +import { alphaBlend, arithmeticBlend, getTextColor, relativeLuminance } from '../color_convert/color_convert.js' export const process = (text, functions, { findColor, findShadow }, { dynamicVars, staticVars }) => { - const { funcName, argsString } = /\$(?\w+)\((?[#a-zA-Z0-9-,.'"\s]*)\)/.exec(text).groups + const { funcName, argsString } = /\$(?\w+)\((?[#a-zA-Z0-9-+,.'"\s]*)\)/.exec(text).groups const args = argsString.split(/ /g).map(a => a.trim()) const func = functions[funcName] @@ -81,6 +81,23 @@ export const colorFunctions = { return alphaBlend(background, amount, foreground) } }, + shift: { + argsNeeded: 2, + documentation: 'Arithmetic blend between two colors', + args: [ + 'origin: base color', + 'value: shift value', + 'operator: math operator to use (+ or -)' + ], + exec: (args, { findColor }, { dynamicVars, staticVars }) => { + const [originArg, valueArg, operatorArg] = args + + const origin = convert(findColor(originArg, { dynamicVars, staticVars })).rgb + const value = convert(findColor(valueArg, { dynamicVars, staticVars })).rgb + + return arithmeticBlend(origin, value, operatorArg) + } + }, boost: { argsNeeded: 2, documentation: 'If given color is dark makes it darker, if color is light - makes it lighter',