tguerin / newton

An Easy To Use Particle Emitter
https://newton.7omtech.fr
MIT License
22 stars 7 forks source link

Effects reset #21

Open NeroThroN opened 7 months ago

NeroThroN commented 7 months ago

Each time an effect is modified, the animations are reset. For example to have a dynamic origin or to have emitDuration based on a dynamic value. Is there a way to keep the particles generated without everything being reset?

tguerin commented 7 months ago

Do you have a sample app to reproduce? or some code? Normally you should be able to have the effect not resetting.

NeroThroN commented 7 months ago

I have create this small sample code to recreate the behavior:

Code ``` dart import 'package:flutter/material.dart'; import 'package:newton_particles/newton_particles.dart'; import 'package:pausable_timer/pausable_timer.dart'; void main() { runApp(const MainApp()); } class MainApp extends StatelessWidget { const MainApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp(home: HomeScreen()); } } class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { late final PausableTimer _timer = PausableTimer.periodic(const Duration(milliseconds: 100), _updateOrigin); Offset origin = const Offset(0, 0); @override void dispose() { _timer.cancel(); super.dispose(); } void _updateOrigin() { setState(() => origin += const Offset(5, 5)); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Newton( activeEffects: [ ExplodeEffect( particleConfiguration: ParticleConfiguration( shape: CircleShape(), color: const SingleParticleColor(color: Colors.red), size: const Size(10, 10), ), effectConfiguration: EffectConfiguration( origin: origin, minAngle: -180, maxAngle: 180, particlesPerEmit: 10, ), ) ], child: Center( child: TextButton( child: const Text('Update Origin'), onPressed: () { setState(() => origin += const Offset(5, 5)); }, ), ), ), floatingActionButton: FloatingActionButton( child: const Icon(Icons.play_arrow), onPressed: () { if (_timer.isPaused) { _timer.start(); } else { _timer.pause(); } }, ), ); } } ```

Each time the setState function is called inside the _updateOrigin method, the particles are reset and the explode animation start from scratch

tguerin commented 3 weeks ago

Took time to answer but what kind of animation are you trying to achieve? Updating the origin through setState will trigger a refresh cause there is no way to know that the same explode effect. If you want to move the explode effect around, you can use a global key on Newton widget to access the current state and add a new exploding effect with a fixed particle count and that should achieve the desired effect. Something like:

void _updateOrigin(Timer timer) {
    origin += const Offset(5, 5);
    newtonKey.currentState?.addEffect(ExplodeEffect(
      particleConfiguration: ParticleConfiguration(
        shape: CircleShape(),
        color: const SingleParticleColor(color: Colors.red),
        size: const Size(10, 10),
      ),
      effectConfiguration: EffectConfiguration(
        origin: origin,
        minAngle: -180,
        maxAngle: 180,
        particlesPerEmit: 10,
        particleCount: 100
      ),
    ));
  }