mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
fix(backgrounds): configurable wave colors and boxes grid color with explicit multicolor mode
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useRef, useMemo } from 'react';
|
import React, { useEffect, useRef, useMemo } from 'react';
|
||||||
import { sanitizeColor, clampNumber } from './types';
|
import { sanitizeColor, clampNumber, safeBoolean } from './types';
|
||||||
import { useAnimationLoop, getMobileDpr } from '@/hooks/useAnimationLoop';
|
import { useAnimationLoop, getMobileDpr } from '@/hooks/useAnimationLoop';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -18,7 +18,14 @@ const COLORS = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
function hexToRgb(hex: string): [number, number, number] {
|
function hexToRgb(hex: string): [number, number, number] {
|
||||||
const v = parseInt(hex.slice(1), 16);
|
let value = hex.replace('#', '');
|
||||||
|
if (value.length === 3)
|
||||||
|
value = value
|
||||||
|
.split('')
|
||||||
|
.map((c) => c + c)
|
||||||
|
.join('');
|
||||||
|
if (!/^[0-9a-fA-F]{6}$/.test(value)) return [129, 140, 248];
|
||||||
|
const v = parseInt(value, 16);
|
||||||
return [(v >> 16) & 255, (v >> 8) & 255, v & 255];
|
return [(v >> 16) & 255, (v >> 8) & 255, v & 255];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,16 +51,16 @@ export default React.memo(function BackgroundBoxes({ settings }: Props) {
|
|||||||
const rows = clampNumber(settings.rows, 4, 30, 15);
|
const rows = clampNumber(settings.rows, 4, 30, 15);
|
||||||
const cols = clampNumber(settings.cols, 4, 30, 15);
|
const cols = clampNumber(settings.cols, 4, 30, 15);
|
||||||
const boxColor = sanitizeColor(settings.boxColor, '#818cf8');
|
const boxColor = sanitizeColor(settings.boxColor, '#818cf8');
|
||||||
|
const lineColor = sanitizeColor(settings.lineColor, 'rgba(51,65,85,0.5)');
|
||||||
|
const multicolor = safeBoolean(settings.multicolor, true);
|
||||||
|
|
||||||
const cells = useMemo((): CellData[] => {
|
const cells = useMemo((): CellData[] => {
|
||||||
return Array.from({ length: rows * cols }, () => ({
|
return Array.from({ length: rows * cols }, () => ({
|
||||||
rgb: hexToRgb(
|
rgb: hexToRgb(multicolor ? COLORS[Math.floor(Math.random() * COLORS.length)] : boxColor),
|
||||||
boxColor === '#818cf8' ? COLORS[Math.floor(Math.random() * COLORS.length)] : boxColor,
|
|
||||||
),
|
|
||||||
phase: Math.random() * 8,
|
phase: Math.random() * 8,
|
||||||
period: 3 + Math.random() * 4,
|
period: 3 + Math.random() * 4,
|
||||||
}));
|
}));
|
||||||
}, [rows, cols, boxColor]);
|
}, [rows, cols, boxColor, multicolor]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvas = canvasRef.current;
|
const canvas = canvasRef.current;
|
||||||
@@ -124,7 +131,7 @@ export default React.memo(function BackgroundBoxes({ settings }: Props) {
|
|||||||
ctx.fillRect(ox + col * cellW, oy + row * cellH, cellW, cellH);
|
ctx.fillRect(ox + col * cellW, oy + row * cellH, cellW, cellH);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.strokeStyle = 'rgba(51,65,85,0.5)';
|
ctx.strokeStyle = lineColor;
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
|
|
||||||
@@ -142,7 +149,7 @@ export default React.memo(function BackgroundBoxes({ settings }: Props) {
|
|||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
},
|
},
|
||||||
[cells, rows, cols],
|
[cells, rows, cols, lineColor],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -351,6 +351,11 @@ export const backgroundRegistry: BackgroundDefinition[] = [
|
|||||||
type: 'color',
|
type: 'color',
|
||||||
default: '#000000',
|
default: '#000000',
|
||||||
},
|
},
|
||||||
|
{ key: 'waveColor1', label: 'admin.backgrounds.color1', type: 'color', default: '#38bdf8' },
|
||||||
|
{ key: 'waveColor2', label: 'admin.backgrounds.color2', type: 'color', default: '#818cf8' },
|
||||||
|
{ key: 'waveColor3', label: 'admin.backgrounds.color3', type: 'color', default: '#c084fc' },
|
||||||
|
{ key: 'waveColor4', label: 'admin.backgrounds.color4', type: 'color', default: '#e879f9' },
|
||||||
|
{ key: 'waveColor5', label: 'admin.backgrounds.color5', type: 'color', default: '#22d3ee' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -419,6 +424,18 @@ export const backgroundRegistry: BackgroundDefinition[] = [
|
|||||||
default: 12,
|
default: 12,
|
||||||
},
|
},
|
||||||
{ key: 'boxColor', label: 'admin.backgrounds.fillColor', type: 'color', default: '#818cf8' },
|
{ key: 'boxColor', label: 'admin.backgrounds.fillColor', type: 'color', default: '#818cf8' },
|
||||||
|
{
|
||||||
|
key: 'multicolor',
|
||||||
|
label: 'admin.backgrounds.multicolor',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'lineColor',
|
||||||
|
label: 'admin.backgrounds.lineColor',
|
||||||
|
type: 'color',
|
||||||
|
default: 'rgba(51,65,85,0.5)',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,13 @@ export default function WavyBackground({ settings }: Props) {
|
|||||||
const blur = clampNumber(settings.blur, 0, 50, 10);
|
const blur = clampNumber(settings.blur, 0, 50, 10);
|
||||||
const waveOpacity = clampNumber(settings.waveOpacity, 0.05, 1, 0.5);
|
const waveOpacity = clampNumber(settings.waveOpacity, 0.05, 1, 0.5);
|
||||||
const backgroundFill = sanitizeColor(settings.backgroundFill, '#000000');
|
const backgroundFill = sanitizeColor(settings.backgroundFill, '#000000');
|
||||||
const colors = ['#38bdf8', '#818cf8', '#c084fc', '#e879f9', '#22d3ee'];
|
const colors = [
|
||||||
|
sanitizeColor(settings.waveColor1, '#38bdf8'),
|
||||||
|
sanitizeColor(settings.waveColor2, '#818cf8'),
|
||||||
|
sanitizeColor(settings.waveColor3, '#c084fc'),
|
||||||
|
sanitizeColor(settings.waveColor4, '#e879f9'),
|
||||||
|
sanitizeColor(settings.waveColor5, '#22d3ee'),
|
||||||
|
];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvas = canvasRef.current;
|
const canvas = canvasRef.current;
|
||||||
@@ -100,7 +106,7 @@ export default function WavyBackground({ settings }: Props) {
|
|||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
}
|
}
|
||||||
}, [speed, waveWidth, blur, waveOpacity, backgroundFill]);
|
}, [speed, waveWidth, blur, waveOpacity, backgroundFill, ...colors]);
|
||||||
|
|
||||||
return <canvas ref={canvasRef} className="absolute inset-0 h-full w-full" />;
|
return <canvas ref={canvasRef} className="absolute inset-0 h-full w-full" />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1172,6 +1172,8 @@
|
|||||||
"pointerColor": "Pointer Color",
|
"pointerColor": "Pointer Color",
|
||||||
"beamColor": "Beam Color",
|
"beamColor": "Beam Color",
|
||||||
"explosionColor": "Explosion Color",
|
"explosionColor": "Explosion Color",
|
||||||
|
"multicolor": "Multicolor",
|
||||||
|
"lineColor": "Line Color",
|
||||||
"bgColor": "Background Color",
|
"bgColor": "Background Color",
|
||||||
"fillColor": "Fill Color",
|
"fillColor": "Fill Color",
|
||||||
"color1": "Color 1",
|
"color1": "Color 1",
|
||||||
|
|||||||
@@ -1202,6 +1202,8 @@
|
|||||||
"pointerColor": "Цвет курсорного блоба",
|
"pointerColor": "Цвет курсорного блоба",
|
||||||
"beamColor": "Цвет лучей",
|
"beamColor": "Цвет лучей",
|
||||||
"explosionColor": "Цвет взрыва",
|
"explosionColor": "Цвет взрыва",
|
||||||
|
"multicolor": "Разноцветный режим",
|
||||||
|
"lineColor": "Цвет линий",
|
||||||
"bgColor": "Цвет фона",
|
"bgColor": "Цвет фона",
|
||||||
"fillColor": "Цвет заливки",
|
"fillColor": "Цвет заливки",
|
||||||
"color1": "Цвет 1",
|
"color1": "Цвет 1",
|
||||||
|
|||||||
Reference in New Issue
Block a user