|
|
|
@ -1,9 +1,10 @@ |
|
|
|
export const gradient = (node, config = {}) => { |
|
|
|
const defaultConfig = { |
|
|
|
points: 10, |
|
|
|
saturation: 0.8, |
|
|
|
points: 12, |
|
|
|
saturation: 0.85, |
|
|
|
lightness: 0.7, |
|
|
|
softness: 0.9, |
|
|
|
seed: null, |
|
|
|
} |
|
|
|
|
|
|
|
// Applies a gradient background
|
|
|
|
@ -13,42 +14,67 @@ export const gradient = (node, config = {}) => { |
|
|
|
...config, |
|
|
|
} |
|
|
|
const { saturation, lightness, softness, points } = config |
|
|
|
const seed = config.seed || Math.random().toString(32).substring(2) |
|
|
|
|
|
|
|
// Generates a random number between min and max
|
|
|
|
const rand = (min, max) => { |
|
|
|
return Math.round(min + Math.random() * (max - min)) |
|
|
|
// 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 = () => { |
|
|
|
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 = rand(0, 360) |
|
|
|
const sat = `${rand(lowerSaturation, upperSaturation)}%` |
|
|
|
const light = `${rand(lowerLightness, upperLightness)}%` |
|
|
|
return `hsl(${hue},${sat},${light})` |
|
|
|
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 = () => { |
|
|
|
const randomGradientPoint = (seed, version) => { |
|
|
|
const lowerTransparency = Math.min(100, softness * 100) |
|
|
|
const upperTransparency = Math.min(100, (softness + 0.2) * 100) |
|
|
|
const transparency = rand(lowerTransparency, upperTransparency) |
|
|
|
const transparency = rangeHash( |
|
|
|
seed, |
|
|
|
lowerTransparency, |
|
|
|
upperTransparency, |
|
|
|
version |
|
|
|
) |
|
|
|
return ( |
|
|
|
`radial-gradient(` + |
|
|
|
`at ${rand(10, 90)}% ${rand(10, 90)}%,` + |
|
|
|
`${randomHSL()} 0,` + |
|
|
|
`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-color:${randomHSL()};background-image:` |
|
|
|
let css = `opacity:0.9;background:${randomHSL(seed, 0, 0.7)};` |
|
|
|
css += "background-image:" |
|
|
|
for (let i = 0; i < points - 1; i++) { |
|
|
|
css += `${randomGradientPoint()},` |
|
|
|
css += `${randomGradientPoint(seed, i)},` |
|
|
|
} |
|
|
|
css += `${randomGradientPoint()};` |
|
|
|
css += `${randomGradientPoint(seed, points)};` |
|
|
|
node.style = css |
|
|
|
} |
|
|
|
|
|
|
|
|