This commit is contained in:
Thomas Peterson 2025-11-12 14:08:15 +01:00
parent d7e3a95f9b
commit da0d560301
2 changed files with 75 additions and 45 deletions

View File

@ -0,0 +1,24 @@
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use PHPNative\Framework\Application;
use PHPNative\Ui\Widget\Container;
use PHPNative\Ui\Window;
// Create application
$app = new Application();
$window = new Window('Simple Shadow Test', 400, 400);
// Main container with light background
$mainContainer = new Container('flex items-center justify-center bg-gray-200');
// Simple box with shadow
$box = new Container('w-48 h-48 bg-white rounded-lg shadow-lg');
$mainContainer->addComponent($box);
// Set window content and run
$window->setRoot($mainContainer);
$app->addWindow($window);
$app->run();

View File

@ -403,14 +403,6 @@ abstract class Component
Profiler::increment('render_normal'); Profiler::increment('render_normal');
// Render shadow if present (before background)
if (
isset($this->computedStyles[\PHPNative\Tailwind\Style\Shadow::class]) &&
($shadow = $this->computedStyles[\PHPNative\Tailwind\Style\Shadow::class])
) {
$this->renderShadow($renderer, $shadow);
}
// Render normally if no cache or cache building // Render normally if no cache or cache building
if ( if (
isset($this->computedStyles[\PHPNative\Tailwind\Style\Background::class]) && isset($this->computedStyles[\PHPNative\Tailwind\Style\Background::class]) &&
@ -857,15 +849,16 @@ abstract class Component
} }
// Define shadow properties based on size // Define shadow properties based on size
// Using fewer layers with proper alpha distribution
$shadowProps = match ($shadow->size) { $shadowProps = match ($shadow->size) {
'sm' => ['blur' => 1, 'offsetX' => 0, 'offsetY' => 1, 'alpha' => 15], 'sm' => ['blur' => 3, 'spread' => 1, 'offsetX' => 0, 'offsetY' => 1, 'alpha' => 40],
'base' => ['blur' => 2, 'offsetX' => 0, 'offsetY' => 2, 'alpha' => 25], 'base' => ['blur' => 4, 'spread' => 2, 'offsetX' => 0, 'offsetY' => 2, 'alpha' => 45],
'md' => ['blur' => 3, 'offsetX' => 0, 'offsetY' => 4, 'alpha' => 30], 'md' => ['blur' => 6, 'spread' => 3, 'offsetX' => 0, 'offsetY' => 4, 'alpha' => 50],
'lg' => ['blur' => 4, 'offsetX' => 0, 'offsetY' => 6, 'alpha' => 35], 'lg' => ['blur' => 8, 'spread' => 5, 'offsetX' => 0, 'offsetY' => 6, 'alpha' => 55],
'xl' => ['blur' => 5, 'offsetX' => 0, 'offsetY' => 10, 'alpha' => 40], 'xl' => ['blur' => 10, 'spread' => 7, 'offsetX' => 0, 'offsetY' => 10, 'alpha' => 60],
'2xl' => ['blur' => 7, 'offsetX' => 0, 'offsetY' => 15, 'alpha' => 50], '2xl' => ['blur' => 15, 'spread' => 10, 'offsetX' => 0, 'offsetY' => 15, 'alpha' => 70],
'inner' => ['blur' => 2, 'offsetX' => 0, 'offsetY' => 0, 'alpha' => 20, 'inner' => true], 'inner' => ['blur' => 4, 'spread' => 2, 'offsetX' => 0, 'offsetY' => 0, 'alpha' => 45, 'inner' => true],
default => ['blur' => 2, 'offsetX' => 0, 'offsetY' => 2, 'alpha' => 25], default => ['blur' => 4, 'spread' => 2, 'offsetX' => 0, 'offsetY' => 2, 'alpha' => 45],
}; };
// Get shadow color (default to black/gray if not specified) // Get shadow color (default to black/gray if not specified)
@ -891,51 +884,58 @@ abstract class Component
$borderRadius = $border->roundTopLeft ?? 0; $borderRadius = $border->roundTopLeft ?? 0;
} }
// Render shadow layers (simulate blur with multiple semi-transparent layers) // Render shadow layers (simulate blur with expanding semi-transparent layers)
for ($i = 0; $i < $shadowProps['blur']; $i++) { // Note: Alpha blending is automatic when using alpha values < 255 in sdl_set_render_draw_color
$offset = $i; // Render from outermost to innermost for proper blending
$layerAlpha = (int) ($shadowColor->alpha / $shadowProps['blur']); for ($i = $shadowProps['blur'] - 1; $i >= 0; $i--) {
// Calculate alpha that decreases towards outer layers (blur effect)
// Innermost layer (i=0) has full alpha, outermost has minimal alpha
$progress = 1.0 - ($i / $shadowProps['blur']);
$layerAlpha = (int) ($shadowProps['alpha'] * $progress);
// Ensure minimum visibility
if ($layerAlpha < 5) {
$layerAlpha = 5;
}
// Calculate expansion for blur effect
$expansion = $shadowProps['spread'] * ($i / $shadowProps['blur']);
if (isset($shadowProps['inner']) && $shadowProps['inner']) { if (isset($shadowProps['inner']) && $shadowProps['inner']) {
// Inner shadow - render inside the element // Inner shadow - render inside the element, shrinking inwards
$shadowX = (int) ($this->viewport->x + $offset); $shadowX = (int) ($this->viewport->x + $expansion);
$shadowY = (int) ($this->viewport->y + $offset); $shadowY = (int) ($this->viewport->y + $expansion);
$shadowWidth = (int) max(0, $this->viewport->width - ($offset * 2)); $shadowWidth = (int) max(0, $this->viewport->width - ($expansion * 2));
$shadowHeight = (int) max(0, $this->viewport->height - ($offset * 2)); $shadowHeight = (int) max(0, $this->viewport->height - ($expansion * 2));
} else { } else {
// Outer shadow - render behind the element // Outer shadow - expand outwards from element
$shadowX = (int) ($this->viewport->x + $shadowProps['offsetX'] + $offset); $shadowX = (int) ($this->viewport->x + $shadowProps['offsetX'] - $expansion);
$shadowY = (int) ($this->viewport->y + $shadowProps['offsetY'] + $offset); $shadowY = (int) ($this->viewport->y + $shadowProps['offsetY'] - $expansion);
$shadowWidth = (int) $this->viewport->width; $shadowWidth = (int) ($this->viewport->width + ($expansion * 2));
$shadowHeight = (int) $this->viewport->height; $shadowHeight = (int) ($this->viewport->height + ($expansion * 2));
} }
// Skip if shadow is too small // Skip if shadow is too small or alpha is too low
if ($shadowWidth <= 0 || $shadowHeight <= 0) { if ($shadowWidth <= 0 || $shadowHeight <= 0 || $layerAlpha < 1) {
continue; continue;
} }
sdl_set_render_draw_color(
$renderer,
$shadowColor->red,
$shadowColor->green,
$shadowColor->blue,
$layerAlpha,
);
if ($borderRadius > 0 && $border !== null) { if ($borderRadius > 0 && $border !== null) {
// Render rounded shadow // Render rounded shadow with expanding border radius
$x2 = $shadowX + $shadowWidth; $x2 = $shadowX + $shadowWidth;
$y2 = $shadowY + $shadowHeight; $y2 = $shadowY + $shadowHeight;
$radiusExpansion = $expansion / 2;
sdl_rounded_box_ex( sdl_rounded_box_ex(
$renderer, $renderer,
$shadowX, $shadowX,
$shadowY, $shadowY,
$x2, $x2,
$y2, $y2,
$border->roundTopLeft ?? 0, (int) (($border->roundTopLeft ?? 0) + $radiusExpansion),
$border->roundTopRight ?? 0, (int) (($border->roundTopRight ?? 0) + $radiusExpansion),
$border->roundBottomRight ?? 0, (int) (($border->roundBottomRight ?? 0) + $radiusExpansion),
$border->roundBottomLeft ?? 0, (int) (($border->roundBottomLeft ?? 0) + $radiusExpansion),
$shadowColor->red, $shadowColor->red,
$shadowColor->green, $shadowColor->green,
$shadowColor->blue, $shadowColor->blue,
@ -943,7 +943,13 @@ abstract class Component
); );
} else { } else {
// Render rectangular shadow // Render rectangular shadow
error_log(sprintf('%s,%s,%s,%s', $shadowX, $shadowY, $shadowWidth, $shadowHeight)); sdl_set_render_draw_color(
$renderer,
$shadowColor->red,
$shadowColor->green,
$shadowColor->blue,
$layerAlpha,
);
sdl_render_fill_rect($renderer, [ sdl_render_fill_rect($renderer, [
'x' => $shadowX, 'x' => $shadowX,
'y' => $shadowY, 'y' => $shadowY,