fCCNeumorphicDecoration function
BoxDecoration
fCCNeumorphicDecoration({})
Implementation
BoxDecoration fCCNeumorphicDecoration({
required ThemeData theme,
required Color baseColor,
double borderRadiusValue = 24,
NeumorphicStyle style = NeumorphicStyle.lowered,
bool transparentBackground = false,
double? borderWidth,
Color? borderColor,
double protrusionIntensity = 1.0,
}) {
final intensity = protrusionIntensity.clamp(0.0, 2.0);
final lift = (0.7 + 0.5 * intensity); // controls contrast and shadow travel
final hslBase = HSLColor.fromColor(baseColor);
final shadows = _computeNeumorphicShadows(theme, baseColor);
final topShadow = shadows.topShadow;
final bottomShadow = shadows.bottomShadow;
final isDark = shadows.isDark;
final effectiveBorderWidth =
borderWidth ?? 0.0; // default: no outline unless asked for
final effectiveBorderColor = borderColor ??
(theme.brightness == Brightness.dark
? Color.lerp(bottomShadow, baseColor, 0.2)
: Color.lerp(topShadow, bottomShadow, 0.35)) ??
baseColor.withValues(
alpha: theme.brightness == Brightness.dark ? 0.35 : 0.6);
final radius = BorderRadius.circular(borderRadiusValue);
if (style == NeumorphicStyle.protruded) {
final bgOpacity = transparentBackground ? 0.88 : 0.96;
final bgTop = hslBase
.withLightness((hslBase.lightness + 0.06 * lift).clamp(0.0, 1.0))
.toColor()
.withValues(alpha: bgOpacity);
final bgBottom = hslBase
.withLightness((hslBase.lightness - 0.06 * lift).clamp(0.0, 1.0))
.toColor()
.withValues(alpha: bgOpacity);
return BoxDecoration(
color: null,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [bgTop, bgBottom],
),
borderRadius: radius,
border: effectiveBorderWidth > 0
? Border.all(
color: effectiveBorderColor,
width: effectiveBorderWidth,
)
: null,
boxShadow: [
BoxShadow(
color: topShadow.withValues(
alpha: (isDark ? 0.3 : 0.45 + 0.15 * intensity).clamp(0.0, 0.85)),
offset: Offset(
-(6 + 4 * intensity),
-(6 + 4 * intensity),
),
blurRadius: 12 + 4 * intensity,
spreadRadius: -(2.5 + intensity),
),
BoxShadow(
color: bottomShadow.withValues(
alpha: (isDark ? 0.45 : 0.60 + 0.15 * intensity).clamp(0.0, 0.9)),
offset: Offset(
8 + 5 * intensity,
8 + 5 * intensity,
),
blurRadius: 18 + 5 * intensity,
spreadRadius: 2 + intensity,
),
],
);
}
// Slightly stronger shadows for better separation on light/transparent cards.
final shadowScale = (0.5 + 0.6 * intensity).clamp(0.6, 1.5);
final double baseOffset = 8 * shadowScale;
final double baseBlur = 14 * shadowScale;
return BoxDecoration(
color: transparentBackground
? baseColor.withValues(alpha: 0.08)
: baseColor.withValues(alpha: 0.92),
borderRadius: radius,
boxShadow: [
BoxShadow(
color: bottomShadow.withValues(
alpha: ((isDark ? 0.4 : 0.6) * shadowScale).clamp(0.0, 1.0)),
offset: Offset(baseOffset, baseOffset),
blurRadius: baseBlur,
inset: true,
),
BoxShadow(
color: topShadow.withValues(
alpha: ((isDark ? 0.6 : 0.8) * shadowScale).clamp(0.0, 1.0)),
offset: Offset(-baseOffset, -baseOffset),
blurRadius: baseBlur,
inset: true,
),
],
);
}