Migration Guide: 0.2.x to 0.3.x
This guide will help you migrate your Newton particle effects from version 0.2.x to 0.3.x. The new version introduces a more organized API using grouped properties, which provides better type safety and code organization.
Overview of Changes
Breaking Changes
-
RelativisticEffectConfigurationrenamed toPhysicsEffectConfiguration- The class name has been changed to better reflect its purpose.
-
activeEffectsparameter renamed toeffectConfigurations- The
Newtonwidget now useseffectConfigurationsinstead ofactiveEffects.
- The
-
Properties are now grouped into dedicated classes
- Individual properties are now organized into grouped property classes for better organization and validation.
Step-by-Step Migration
1. Update Newton Widget Parameter
Before (0.2.x):
Newton(
activeEffects: [
// effects...
],
)
After (0.3.x):
Newton(
effectConfigurations: [
// effects...
],
)
2. Rename RelativisticEffectConfiguration
Before (0.2.x):
RelativisticEffectConfiguration(
// properties...
)
After (0.3.x):
PhysicsEffectConfiguration(
// properties...
)
3. Migrate Properties to Grouped Classes
The biggest change is that properties are now organized into grouped classes. Here's how to migrate:
Physics-Based Effects
Before (0.2.x):
RelativisticEffectConfiguration(
gravity: Gravity.earthGravity,
minAngle: 90,
maxAngle: 90,
minVelocity: Velocity.stationary,
maxVelocity: Velocity.stationary,
minEndScale: 1,
maxEndScale: 1,
minFadeOutThreshold: 0.6,
maxFadeOutThreshold: 0.8,
origin: Offset.zero,
maxOriginOffset: Offset(1, 0),
minParticleLifespan: Duration(seconds: 7),
maxParticleLifespan: Duration(seconds: 10),
particleConfiguration: ParticleConfiguration(...),
)
After (0.3.x):
PhysicsEffectConfiguration(
physicsProperties: PhysicsProperties(
gravity: Gravity.earthGravity,
angle: NumRange.single(90),
velocity: NumRange.between(Velocity.stationary, Velocity.stationary),
),
visualProperties: VisualProperties(
endScale: NumRange.single(1),
fadeOutThreshold: NumRange.between(0.6, 0.8),
),
emissionProperties: EmissionProperties(
origin: Offset.zero,
maxOriginOffset: Offset(1, 0),
particleLifespan: DurationRange.between(Duration(seconds: 7), Duration(seconds: 10)),
),
particleConfiguration: ParticleConfiguration(...),
)
Deterministic Effects
Before (0.2.x):
DeterministicEffectConfiguration(
minAngle: 90,
maxAngle: 90,
minDistance: 200,
maxDistance: 200,
minEndScale: 1,
maxEndScale: 1,
minFadeOutThreshold: 0.6,
maxFadeOutThreshold: 0.8,
origin: Offset.zero,
maxOriginOffset: Offset(1, 0),
minParticleLifespan: Duration(seconds: 4),
maxParticleLifespan: Duration(seconds: 7),
particleConfiguration: ParticleConfiguration(...),
)
After (0.3.x):
DeterministicEffectConfiguration(
deterministicProperties: DeterministicProperties(
angle: NumRange.single(90),
distance: NumRange.single(200),
),
visualProperties: VisualProperties(
endScale: NumRange.single(1),
fadeOutThreshold: NumRange.between(0.6, 0.8),
),
emissionProperties: EmissionProperties(
origin: Offset.zero,
maxOriginOffset: Offset(1, 0),
particleLifespan: DurationRange.between(Duration(seconds: 4), Duration(seconds: 7)),
),
particleConfiguration: ParticleConfiguration(...),
)
Property Group Mapping
PhysicsProperties
Groups all physics-related properties:
gravity→physicsProperties.gravityminAngle/maxAngle→physicsProperties.angle: NumRange.between(min, max)orNumRange.single(value)minVelocity/maxVelocity→physicsProperties.velocity: NumRange.between(min, max)minDensity/maxDensity→physicsProperties.density: NumRange.between(min, max)minFriction/maxFriction→physicsProperties.friction: NumRange.between(min, max)minRestitution/maxRestitution→physicsProperties.restitution: NumRange.between(min, max)onlyInteractWithEdges→physicsProperties.onlyInteractWithEdgessolidEdges→physicsProperties.solidEdges
VisualProperties
Groups all visual appearance properties:
minEndScale/maxEndScale→visualProperties.endScale: NumRange.between(min, max)orNumRange.single(value)minFadeInThreshold/maxFadeInThreshold→visualProperties.fadeInThreshold: NumRange.between(min, max)minFadeOutThreshold/maxFadeOutThreshold→visualProperties.fadeOutThreshold: NumRange.between(min, max)scaleCurve→visualProperties.scaleCurvefadeInCurve→visualProperties.fadeInCurvefadeOutCurve→visualProperties.fadeOutCurve
EmissionProperties
Groups all emission-related properties. Note: EmissionProperties is now part of the base EffectConfiguration class, making it available to both PhysicsEffectConfiguration and DeterministicEffectConfiguration:
origin→emissionProperties.originminOriginOffset/maxOriginOffset→emissionProperties.minOriginOffset/maxOriginOffsetparticleCount→emissionProperties.particleCountparticlesPerEmit→emissionProperties.particlesPerEmitemitDuration→emissionProperties.emitDurationemitCurve→emissionProperties.emitCurveminParticleLifespan/maxParticleLifespan→emissionProperties.particleLifespan: DurationRange.between(min, max)
DeterministicProperties
Groups deterministic-specific properties:
minAngle/maxAngle→deterministicProperties.angle: NumRange.between(min, max)minDistance/maxDistance→deterministicProperties.distance: NumRange.between(min, max)
AnimationProperties
Groups animation timing properties:
startDelay→animationProperties.startDelay
LayerProperties
Groups layer and trail properties:
particleLayer→layerProperties.particleLayertrail→layerProperties.trail
Using Range Helpers
The new API uses NumRange and DurationRange objects for min/max values. Use these helpers:
NumRange.single(value)- For a single numeric value (no variation)NumRange.between(min, max)- For a numeric range between min and maxDurationRange.single(Duration(...))- For a single duration valueDurationRange.between(Duration(...), Duration(...))- For a duration range
Example:
// Single numeric value
endScale: NumRange.single(1)
// Numeric range
fadeOutThreshold: NumRange.between(0.6, 0.8)
velocity: NumRange.between(Velocity.custom(3), Velocity.custom(5))
// Duration range
particleLifespan: DurationRange.between(Duration(seconds: 3), Duration(seconds: 5))
Configuration Overrider Changes
If you're using configurationOverrider (formerly effectOverrider), update the copyWith call:
Before (0.2.x):
configurationOverrider: (effect) {
return effect.effectConfiguration.copyWith(
physicsProperties: effect.effectConfiguration.physicsProperties.copyWith(
angle: NumRange.single(angle),
),
);
}
After (0.3.x):
configurationOverrider: (effect) {
return effect.effectConfiguration.copyWith(
physicsProperties: effect.effectConfiguration.physicsProperties.copyWith(
angle: NumRange.single(angle),
),
);
}
Post Effect Builder Changes
When creating post effects in postEffectBuilder, use the new API:
Before (0.2.x):
postEffectBuilder: (particle, effect) {
return PhysicsEffectConfiguration(
physicsProperties: const PhysicsProperties(
gravity: Gravity.earthGravity,
angle: NumRange.between(-180, 180),
// ... other properties
);
}
After (0.3.x):
postEffectBuilder: (particle, effect) {
return PhysicsEffectConfiguration(
physicsProperties: const PhysicsProperties(
gravity: Gravity.earthGravity,
angle: NumRange.between(-180, 180),
),
// ... other grouped properties
);
}
Benefits of the New API
-
Better Organization: Properties are logically grouped, making configurations easier to understand and maintain.
-
Type Safety: Grouped properties provide better validation and type checking.
-
Consistency: Both physics and deterministic effects use similar property grouping patterns.
-
Extensibility: New properties can be added to appropriate groups without cluttering the main configuration class.
Common Patterns
Rain Effect Migration
Before:
RelativisticEffectConfiguration(
gravity: Gravity.earthGravity,
minAngle: 90,
maxAngle: 90,
minVelocity: Velocity.stationary,
maxVelocity: Velocity.stationary,
origin: Offset.zero,
maxOriginOffset: Offset(1, 0),
minParticleLifespan: Duration(seconds: 7),
maxParticleLifespan: Duration(seconds: 10),
particleConfiguration: ParticleConfiguration(...),
)
After:
PhysicsEffectConfiguration(
physicsProperties: const PhysicsProperties(
gravity: Gravity.earthGravity,
angle: NumRange.single(90),
velocity: NumRange.between(Velocity.stationary, Velocity.stationary),
),
emissionProperties: const EmissionProperties(
origin: Offset.zero,
maxOriginOffset: Offset(1, 0),
particleLifespan: DurationRange.between(Duration(seconds: 7), Duration(seconds: 10)),
),
particleConfiguration: ParticleConfiguration(...),
)
Need Help?
If you encounter issues during migration, please:
- Check the updated documentation
- Review the effect samples for examples
- Open an issue on GitHub