initializeParticles method
Initializes the particle system with necessary bounds and configuration.
path: The area where particles can exist (e.g. text outlines).
config: Configuration for speed, density, color, etc.
rects: Optional explicit list of rectangles (e.g. for individual words).
If provided, this is preferred for shader rendering to ensure precise per-rect shapes.
Implementation
void initializeParticles(Path path, SpoilerConfig config, {List<Rect>? rects}) {
final previousShaderPath = _config.shaderConfig?.customShaderPath;
final nextShaderPath = config.shaderConfig?.customShaderPath;
// Ensure maxParticleSize is valid
assert(config.particleConfig.maxParticleSize >= 1, 'maxParticleSize must be >= 1');
_config = config;
_spoilerRects = rects ?? [];
_cachedClipPath = null; // Invalidate cache
if (_spoilerPath != path) {
_spoilerPath.reset();
if (config.maskConfig != null) {
final newPath = Path.combine(
config.maskConfig!.maskOperation,
path,
config.maskConfig!.maskPath.shift(
config.maskConfig!.offset,
),
);
_spoilerPath.addPath(newPath, Offset.zero);
} else {
_spoilerPath.addPath(path, Offset.zero);
}
_spoilerBounds = _spoilerPath.getBounds();
}
// If rects weren't provided, try to approximate them from path bounds
if (_spoilerRects.isEmpty) {
// Fallback: use subPaths derived rects
final subPaths = _spoilerPath.subPaths;
_encapsulatedPaths = subPaths.toList();
_spoilerRects = _encapsulatedPaths.map((p) => p.getBounds()).toList();
}
_initFadeIfNeeded();
// If shader changed (or removed), allow re-init and fall back to atlas while loading.
if (previousShaderPath != nextShaderPath) {
_shaderInitAttempted = false;
if (_drawer is ShaderSpoilerDrawer || nextShaderPath == null) {
_drawer = AtlasSpoilerDrawer();
}
}
// Ensure we are using Atlas drawer initially or if config changes
final subPaths = _spoilerPath.subPaths;
_encapsulatedPaths = subPaths.toList();
if (_drawer is! ShaderSpoilerDrawer) {
if (_drawer is! AtlasSpoilerDrawer) {
_drawer = AtlasSpoilerDrawer();
}
(_drawer as AtlasSpoilerDrawer).initializeParticles(
paths: subPaths,
config: _config,
);
}
_isEnabled = config.isEnabled;
_startParticleAnimationIfNeeded();
// Attempt to switch to shader if configured
if (_config.shaderConfig?.customShaderPath != null) {
_initShaderIfNeeded();
}
}