1
0
Fork 0
mirror of synced 2024-06-01 18:20:18 +12:00
budibase/packages/builder/src/actions.js

93 lines
2.7 KiB
JavaScript

export const gradient = (node, config = {}) => {
const defaultConfig = {
points: 12,
saturation: 0.85,
lightness: 0.7,
softness: 0.9,
seed: null,
version: null,
}
// Applies a gradient background
const createGradient = config => {
config = {
...defaultConfig,
...config,
}
const { saturation, lightness, softness, points } = config
const seed = config.seed || Math.random().toString(32).substring(2)
const version = config.version ?? 0
// Hash function which returns a fixed hash between specified limits
// for a given seed and a given version
const rangeHash = (seed, min = 0, max = 100, version = 0) => {
const range = max - min
let hash = range + version
for (let i = 0; i < seed.length * 2 + version; i++) {
hash = (hash << 5) - hash + seed.charCodeAt(i % seed.length)
hash = ((hash & hash) % range) + version
}
return min + (hash % range)
}
// Generates a random HSL colour using the options specified
const randomHSL = (seed, version, alpha = 1) => {
const lowerSaturation = Math.min(100, saturation * 100)
const upperSaturation = Math.min(100, (saturation + 0.2) * 100)
const lowerLightness = Math.min(100, lightness * 100)
const upperLightness = Math.min(100, (lightness + 0.2) * 100)
const hue = rangeHash(seed, 0, 360, version)
const sat = `${rangeHash(
seed,
lowerSaturation,
upperSaturation,
version
)}%`
const light = `${rangeHash(
seed,
lowerLightness,
upperLightness,
version
)}%`
return `hsla(${hue},${sat},${light},${alpha})`
}
// Generates a radial gradient stop point
const randomGradientPoint = (seed, version) => {
const lowerTransparency = Math.min(100, softness * 100)
const upperTransparency = Math.min(100, (softness + 0.2) * 100)
const transparency = rangeHash(
seed,
lowerTransparency,
upperTransparency,
version
)
return (
`radial-gradient(at ` +
`${rangeHash(seed, 0, 100, version)}% ` +
`${rangeHash(seed, 0, 100, version + 1)}%,` +
`${randomHSL(seed, version, saturation)} 0,` +
`transparent ${transparency}%)`
)
}
let css = `opacity:0.9;background:${randomHSL(seed, version, 0.7)};`
css += "background-image:"
for (let i = 0; i < points - 1; i++) {
css += `${randomGradientPoint(seed, version + i)},`
}
css += `${randomGradientPoint(seed, points)};`
node.style = css
}
// Apply the initial gradient
createGradient(config)
return {
// Apply a new gradient
update: config => {
createGradient(config)
},
}
}