Color code hooks for RR
Add color-coding for generated hooks and mirror colors on RR partition. - Introduce hookColors and baseHue state for pastel color shading. - Generate random base color per run and derive diagonal hook colors across both diagrams. - Apply consistent colors to Ferrers diagram highlights and Rogers-Ramanujan partition boxes. - Ensure muted pastel shades traverse along the diagonal hooks and reflect on both views. X-Lovable-Edit-ID: edt-8409dc4c-1a65-459a-9898-f0e32c8966a0
This commit is contained in:
commit
b398f4864b
1 changed files with 87 additions and 12 deletions
|
|
@ -13,6 +13,8 @@ const FerrersRogersRamanujan = () => {
|
|||
const [animatingHook, setAnimatingHook] = useState<{ row: number; col: number } | null>(null);
|
||||
const [animationStep, setAnimationStep] = useState(0);
|
||||
const [isAnimating, setIsAnimating] = useState(false);
|
||||
const [hookColors, setHookColors] = useState<string[]>([]);
|
||||
const [baseHue, setBaseHue] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
// Initialize sliders with all zeros
|
||||
|
|
@ -45,6 +47,7 @@ const FerrersRogersRamanujan = () => {
|
|||
setAnimatingHook(null);
|
||||
setAnimationStep(0);
|
||||
setIsAnimating(false);
|
||||
setHookColors([]);
|
||||
};
|
||||
|
||||
const generateRRPartition = () => {
|
||||
|
|
@ -53,11 +56,25 @@ const FerrersRogersRamanujan = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
// Pick a random base hue (0-360)
|
||||
const newBaseHue = Math.floor(Math.random() * 360);
|
||||
setBaseHue(newBaseHue);
|
||||
setHookColors([]);
|
||||
setRRPartition([]);
|
||||
setAnimationStep(0);
|
||||
setIsAnimating(true);
|
||||
};
|
||||
|
||||
// Generate muted pastel color for current hook
|
||||
const generateHookColor = (index: number, total: number) => {
|
||||
// Move through shades of the base hue
|
||||
const hueVariation = (index / Math.max(total - 1, 1)) * 60 - 30; // ±30 degrees
|
||||
const hue = (baseHue + hueVariation + 360) % 360;
|
||||
const saturation = 45 + (index % 3) * 10; // 45-65% for muted pastels
|
||||
const lightness = 75 + (index % 2) * 5; // 75-80% for pastels
|
||||
return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
|
||||
};
|
||||
|
||||
// Animation effect - traverse main diagonal only
|
||||
useEffect(() => {
|
||||
if (!isAnimating || committedPartition.length === 0) return;
|
||||
|
|
@ -90,7 +107,12 @@ const FerrersRogersRamanujan = () => {
|
|||
}
|
||||
const hookSize = boxesRight + boxesBelow + 1;
|
||||
|
||||
// Update RR partition
|
||||
// Generate color for this hook (estimate total hooks as partition length)
|
||||
const estimatedTotalHooks = Math.min(partition.length, partition[0] || 0);
|
||||
const color = generateHookColor(animationStep, estimatedTotalHooks);
|
||||
|
||||
// Update colors and RR partition
|
||||
setHookColors(prev => [...prev, color]);
|
||||
setRRPartition(prev => [...prev, hookSize]);
|
||||
|
||||
// Schedule next step
|
||||
|
|
@ -99,9 +121,9 @@ const FerrersRogersRamanujan = () => {
|
|||
}, 500);
|
||||
|
||||
return () => clearTimeout(timeout);
|
||||
}, [isAnimating, animationStep, committedPartition]);
|
||||
}, [isAnimating, animationStep, committedPartition, baseHue]);
|
||||
|
||||
const renderFerrersDiagram = (partition: number[], highlightHook?: { row: number; col: number }) => {
|
||||
const renderFerrersDiagram = (partition: number[], highlightHook?: { row: number; col: number }, isOriginal = true) => {
|
||||
if (partition.length === 0) return null;
|
||||
|
||||
const boxSize = 30;
|
||||
|
|
@ -112,18 +134,71 @@ const FerrersRogersRamanujan = () => {
|
|||
{partition.map((count, rowIdx) => (
|
||||
<div key={rowIdx} className="flex gap-[2px] mb-[2px]">
|
||||
{Array.from({ length: count }).map((_, colIdx) => {
|
||||
const isHook = highlightHook &&
|
||||
((rowIdx === highlightHook.row && colIdx >= highlightHook.col) ||
|
||||
(colIdx === highlightHook.col && rowIdx >= highlightHook.row));
|
||||
let backgroundColor = 'bg-secondary';
|
||||
let borderColor = 'border-border';
|
||||
let extraClasses = 'hover:bg-secondary/80';
|
||||
|
||||
if (isOriginal) {
|
||||
// Original diagram: color completed hooks on diagonal
|
||||
if (rowIdx === colIdx && rowIdx < hookColors.length) {
|
||||
const color = hookColors[rowIdx];
|
||||
backgroundColor = '';
|
||||
borderColor = '';
|
||||
extraClasses = `scale-105 shadow-md`;
|
||||
return (
|
||||
<div
|
||||
key={colIdx}
|
||||
className={`w-[30px] h-[30px] border-2 transition-all duration-300 ${extraClasses}`}
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
borderColor: color
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Highlight current hook being processed
|
||||
const isHook = highlightHook &&
|
||||
((rowIdx === highlightHook.row && colIdx >= highlightHook.col) ||
|
||||
(colIdx === highlightHook.col && rowIdx >= highlightHook.row));
|
||||
|
||||
if (isHook) {
|
||||
backgroundColor = 'bg-primary';
|
||||
borderColor = 'border-primary';
|
||||
extraClasses = 'scale-110 shadow-lg';
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
key={colIdx}
|
||||
className={`w-[30px] h-[30px] border-2 transition-all duration-300 ${
|
||||
isHook
|
||||
? 'bg-primary border-primary scale-110 shadow-lg'
|
||||
: 'bg-secondary border-border hover:bg-secondary/80'
|
||||
}`}
|
||||
className={`w-[30px] h-[30px] border-2 transition-all duration-300 ${backgroundColor} ${borderColor} ${extraClasses}`}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const renderRRDiagram = (partition: number[]) => {
|
||||
if (partition.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div className="inline-block p-4 bg-card rounded-lg border">
|
||||
{partition.map((count, rowIdx) => (
|
||||
<div key={rowIdx} className="flex gap-[2px] mb-[2px]">
|
||||
{Array.from({ length: count }).map((_, colIdx) => {
|
||||
const color = hookColors[rowIdx] || 'hsl(var(--secondary))';
|
||||
return (
|
||||
<div
|
||||
key={colIdx}
|
||||
className="w-[30px] h-[30px] border-2 transition-all duration-300 scale-105 shadow-md"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
borderColor: color
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
@ -230,7 +305,7 @@ const FerrersRogersRamanujan = () => {
|
|||
<p className="text-sm text-muted-foreground mb-4">
|
||||
{rrPartition.join(" + ")} = {n} (parts differ by ≥ 2)
|
||||
</p>
|
||||
{renderFerrersDiagram(rrPartition)}
|
||||
{renderRRDiagram(rrPartition)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue