mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-08-30 23:00:06 -04:00
Static gradients, no tilt or shine when reduce motion
This commit is contained in:
parent
438fbcc603
commit
ffb5f1dc1a
@ -29,7 +29,7 @@ export class GradientAnimationService {
|
||||
|
||||
constructor(private cssVariableService: CssVariableService) {}
|
||||
|
||||
startAnimation(canvas: HTMLCanvasElement, isReducedMotion: boolean = false): void {
|
||||
startAnimation(canvas: HTMLCanvasElement, isReducedMotion: boolean = false, isStaticMode: boolean = false): void {
|
||||
if (!canvas) return;
|
||||
|
||||
// Stop any existing animation
|
||||
@ -48,12 +48,23 @@ export class GradientAnimationService {
|
||||
this.canvasHeight = window.innerHeight;
|
||||
canvas.width = this.canvasWidth;
|
||||
canvas.height = this.canvasHeight;
|
||||
|
||||
// If static mode, render once and stop
|
||||
if (isStaticMode) {
|
||||
this.renderStaticGradients(ctx);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
this.resizeHandler = resizeCanvas;
|
||||
resizeCanvas();
|
||||
window.addEventListener('resize', this.resizeHandler, { passive: true });
|
||||
|
||||
// If static mode requested, don't start animation loop
|
||||
if (isStaticMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle window focus/blur
|
||||
this.blurHandler = () => { this.isWindowFocused = false; };
|
||||
this.focusHandler = () => { this.isWindowFocused = true; };
|
||||
@ -69,9 +80,9 @@ export class GradientAnimationService {
|
||||
const gradientColor3 = this.cssVariableService.getVariableAsRgb('--gradient-color-3') || { r: 255, g: 215, b: 0 };
|
||||
const gradientColor4 = this.cssVariableService.getVariableAsRgb('--gradient-color-4') || { r: 255, g: 20, b: 147 };
|
||||
|
||||
// Slightly faster but still very subtle movement
|
||||
const baseSpeed = isReducedMotion ? 0.00015 : 0.001; // Slightly increased from ultra-slow
|
||||
const speedVariation = 0.0001; // Small increase in variation
|
||||
// Respect accessibility preferences - much slower or static for reduced motion
|
||||
const baseSpeed = isReducedMotion ? 0.00001 : 0.0003; // Nearly static for reduced motion
|
||||
const speedVariation = isReducedMotion ? 0.000005 : 0.0001; // Minimal variation for reduced motion
|
||||
|
||||
const gradientPoints: GradientPoint[] = [
|
||||
{
|
||||
@ -80,7 +91,7 @@ export class GradientAnimationService {
|
||||
vx: baseSpeed + speedVariation * 0.5,
|
||||
vy: (baseSpeed + speedVariation) * 1.2,
|
||||
color: gradientColor1,
|
||||
size: 1 // Reduced but still large
|
||||
size: 1.4 // Reduced but still large
|
||||
},
|
||||
{
|
||||
x: 0.95, // Moved closer to edge
|
||||
@ -88,7 +99,7 @@ export class GradientAnimationService {
|
||||
vx: -(baseSpeed + speedVariation * 0.8),
|
||||
vy: baseSpeed + speedVariation * 0.6,
|
||||
color: gradientColor2,
|
||||
size: 1.2 // Reduced but still large
|
||||
size: 1.5 // Reduced but still large
|
||||
},
|
||||
{
|
||||
x: 0.5, // Center position
|
||||
@ -183,7 +194,7 @@ export class GradientAnimationService {
|
||||
|
||||
this.animationId = requestAnimationFrame(animate);
|
||||
} catch (error) {
|
||||
console.error('Animation error:', error);
|
||||
// Silently handle animation errors and stop animation
|
||||
this.stopAnimation();
|
||||
}
|
||||
};
|
||||
@ -192,6 +203,59 @@ export class GradientAnimationService {
|
||||
this.animationId = requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
private renderStaticGradients(ctx: CanvasRenderingContext2D): void {
|
||||
// Get colors from CSS variables with fallbacks
|
||||
const gradientColor1 = this.cssVariableService.getVariableAsRgb('--gradient-color-1') || { r: 73, g: 197, b: 147 };
|
||||
const gradientColor2 = this.cssVariableService.getVariableAsRgb('--gradient-color-2') || { r: 138, g: 43, b: 226 };
|
||||
const gradientColor3 = this.cssVariableService.getVariableAsRgb('--gradient-color-3') || { r: 255, g: 215, b: 0 };
|
||||
const gradientColor4 = this.cssVariableService.getVariableAsRgb('--gradient-color-4') || { r: 255, g: 20, b: 147 };
|
||||
|
||||
// Static gradient positions (no animation)
|
||||
const staticGradientPoints = [
|
||||
{ x: 0.2, y: 0.2, color: gradientColor1, size: 1.4 },
|
||||
{ x: 0.8, y: 0.3, color: gradientColor2, size: 1.5 },
|
||||
{ x: 0.5, y: 0.8, color: gradientColor3, size: 1.3 },
|
||||
{ x: 0.3, y: 0.6, color: gradientColor4, size: 1.4 },
|
||||
{ x: 0.7, y: 0.7, color: gradientColor1, size: 1.2 }
|
||||
];
|
||||
|
||||
// Pre-calculate background color
|
||||
const backgroundColor = this.cssVariableService.getVariable('--elevation-layer2-dark-solid') || '#1f2020';
|
||||
|
||||
// Clear canvas with background color
|
||||
ctx.fillStyle = backgroundColor;
|
||||
ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||
|
||||
// Set blend mode for smoother gradients
|
||||
ctx.globalCompositeOperation = 'screen';
|
||||
|
||||
// Render static gradients
|
||||
staticGradientPoints.forEach(point => {
|
||||
const pointX = point.x * this.canvasWidth;
|
||||
const pointY = point.y * this.canvasHeight;
|
||||
const radius = Math.min(this.canvasWidth, this.canvasHeight) * 0.9 * point.size;
|
||||
|
||||
const gradient = ctx.createRadialGradient(
|
||||
pointX, pointY, 0,
|
||||
pointX, pointY, radius
|
||||
);
|
||||
|
||||
const { r, g, b } = point.color;
|
||||
gradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, 0.25)`);
|
||||
gradient.addColorStop(0.15, `rgba(${r}, ${g}, ${b}, 0.18)`);
|
||||
gradient.addColorStop(0.35, `rgba(${r}, ${g}, ${b}, 0.12)`);
|
||||
gradient.addColorStop(0.6, `rgba(${r}, ${g}, ${b}, 0.06)`);
|
||||
gradient.addColorStop(0.8, `rgba(${r}, ${g}, ${b}, 0.03)`);
|
||||
gradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`);
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
|
||||
});
|
||||
|
||||
// Reset composite operation
|
||||
ctx.globalCompositeOperation = 'source-over';
|
||||
}
|
||||
|
||||
stopAnimation(): void {
|
||||
if (this.animationId !== undefined) {
|
||||
cancelAnimationFrame(this.animationId);
|
||||
|
@ -33,7 +33,6 @@ export class SplashContainerComponent implements OnInit, OnDestroy, AfterViewIni
|
||||
tiltElement!: ElementRef<HTMLElement>;
|
||||
|
||||
ngOnInit() {
|
||||
// Initialize CSS variables with default values
|
||||
this.initializeCssVariables();
|
||||
}
|
||||
|
||||
@ -53,12 +52,10 @@ export class SplashContainerComponent implements OnInit, OnDestroy, AfterViewIni
|
||||
'--shadow-intensity': '0.5'
|
||||
};
|
||||
|
||||
// Batch set all variables at once to minimize DOM operations
|
||||
this.cssVariableService.setVariablesBatch(defaultVariables);
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
// Use requestAnimationFrame for better performance and Zone.js integration
|
||||
requestAnimationFrame(() => {
|
||||
this.initializeAnimations();
|
||||
});
|
||||
@ -71,32 +68,26 @@ export class SplashContainerComponent implements OnInit, OnDestroy, AfterViewIni
|
||||
|
||||
private initializeAnimations(): void {
|
||||
try {
|
||||
console.log('Initializing animations...');
|
||||
console.log('Canvas element:', this.gradientCanvas?.nativeElement);
|
||||
console.log('Tilt element:', this.tiltElement?.nativeElement);
|
||||
|
||||
const isReducedMotion = this.tiltService.shouldReduceMotion();
|
||||
console.log('Reduced motion detected:', isReducedMotion);
|
||||
|
||||
// For maximum accessibility, offer completely static gradients for reduced motion
|
||||
// You can change this to `false` if you want very slow animation instead
|
||||
const useStaticGradients = isReducedMotion;
|
||||
|
||||
// Always initialize gradient animation (but slower for reduced motion)
|
||||
// Initialize gradient animation
|
||||
if (this.gradientCanvas?.nativeElement) {
|
||||
console.log('Starting gradient animation');
|
||||
this.gradientService.startAnimation(this.gradientCanvas.nativeElement, isReducedMotion);
|
||||
} else {
|
||||
console.warn('Gradient canvas element not found');
|
||||
this.gradientService.startAnimation(
|
||||
this.gradientCanvas.nativeElement,
|
||||
isReducedMotion,
|
||||
useStaticGradients
|
||||
);
|
||||
}
|
||||
|
||||
// Only initialize tilt tracking if reduced motion is not enabled
|
||||
// Initialize tilt tracking only if reduced motion is not enabled
|
||||
if (!isReducedMotion && this.tiltElement?.nativeElement) {
|
||||
console.log('Starting tilt tracking');
|
||||
this.tiltService.initializeMouseTracking(this.tiltElement.nativeElement);
|
||||
} else if (isReducedMotion) {
|
||||
console.log('Skipping tilt tracking due to reduced motion preference');
|
||||
} else {
|
||||
console.warn('Tilt element not found');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error initializing animations:', error);
|
||||
// Clean up any partially initialized services
|
||||
this.cleanupServices();
|
||||
// Fallback: try to initialize with a delay
|
||||
@ -111,26 +102,23 @@ export class SplashContainerComponent implements OnInit, OnDestroy, AfterViewIni
|
||||
this.gradientService.stopAnimation();
|
||||
this.tiltService.cleanup();
|
||||
} catch (error) {
|
||||
console.error('Error during service cleanup:', error);
|
||||
// Silent cleanup - errors here are not critical
|
||||
}
|
||||
}
|
||||
|
||||
private initializeAnimationsFallback(): void {
|
||||
console.log('Trying fallback initialization...');
|
||||
|
||||
const isReducedMotion = this.tiltService.shouldReduceMotion();
|
||||
const useStaticGradients = isReducedMotion;
|
||||
|
||||
// Try to find elements by ID as fallback
|
||||
const canvas = document.getElementById('gradient-canvas') as HTMLCanvasElement;
|
||||
const tiltElement = document.querySelector('.tilt') as HTMLElement;
|
||||
|
||||
if (canvas && !this.gradientService.isAnimating()) {
|
||||
console.log('Fallback: Starting gradient animation');
|
||||
this.gradientService.startAnimation(canvas, isReducedMotion);
|
||||
this.gradientService.startAnimation(canvas, isReducedMotion, useStaticGradients);
|
||||
}
|
||||
|
||||
if (tiltElement && !isReducedMotion) {
|
||||
console.log('Fallback: Starting tilt tracking');
|
||||
this.tiltService.initializeMouseTracking(tiltElement);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user