Celebrate more with this lightweight confetti particle system 🎊

Overview

Konfetti 🎊


License API level 16 API level 16 API level 16 Build Status

πŸ₯³ Celebrate more with this lightweight confetti particle system. Create realistic confetti by implementing this easy to use library.

Demo app

Sample app

Download on Google Play:

Android app on Google Play

Or download the APK here

Usage

XML

All you need in your layout is the KonfettiView to render the particles on:

<nl.dionsegijn.konfetti.KonfettiView
        android:id="@+id/viewKonfetti"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

Example in Kotlin

viewKonfetti.build()
    .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA)
    .setDirection(0.0, 359.0)
    .setSpeed(1f, 5f)
    .setFadeOutEnabled(true)
    .setTimeToLive(2000L)
    .addShapes(Shape.Square, Shape.Circle)
    .addSizes(Size(12))
    .setPosition(-50f, viewKonfetti.width + 50f, -50f, -50f)
    .streamFor(300, 5000L)

Example in Java

final KonfettiView konfettiView = findViewById(R.id.konfettiView);
konfettiView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(final View view) {
        konfettiView.build()
                .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA)
                .setDirection(0.0, 359.0)
                .setSpeed(1f, 5f)
                .setFadeOutEnabled(true)
                .setTimeToLive(2000L)
                .addShapes(Shape.Square.INSTANCE, Shape.Circle.INSTANCE)
                .addSizes(new Size(12, 5f))
                .setPosition(-50f, konfettiView.getWidth() + 50f, -50f, -50f)
                .streamFor(300, 5000L);
    }
});

See sample code here: https://github.com/DanielMartinus/Konfetti/blob/main/demo-simple-java/src/main/java/nl/dionsegijn/simple_demo/MainActivity.java

Custom shapes

Add a custom shape by using:

Shape.DrawableShape(drawable: Drawable)

The 3D flip effect works best for symmetrical shapes, for example a drawable with a width and a height of 24x24.

Indefinite streams

Stream for an indefinite amount of time using StreamEmitter.INDEFINITE

viewKonfetti.build()
    ...
    .streamFor(particlesPerSecond = 300, emittingTime = StreamEmitter.INDEFINITE)

The only way to stop streams that run for an indefinite amount of time is either by calling:

Reset

Call reset to immediately stop rendering all particles.

viewKonfetti.reset()

stopGracefully

Call this function to stop rendering new particles. The ones visible will live out their lifetime.

viewKonfetti.stopGracefully()

Download

Add the following dependency in your app's build.gradle

dependencies {
      implementation 'nl.dionsegijn:konfetti:1.3.2'
}

Download

Java project

If you haven't configured Kotlin for your Java only project, add the following to your project:

implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:$latest_version'

Read more about the latest version and kotlin via gradle here: https://kotlinlang.org/docs/reference/using-gradle.html

Community

Need help or want to receive the latest updates? Join the telegram groups:

Contribute

There is always room for improvement.

Report issue

Did you encounter bugs? Report them here. The more relevant information you provide the easier and faster it can be resolved.

Contribute

As mentioned, there is always room for improvement. Do you have any performance improvement ideas? Please suggest them here. Before submitting a large Pull Request, creating an issue to discuss your ideas would be the preferred way so we can be sure it is in line with other improvements currently being developed. Is it a simple improvement? Go ahead and submit a Pull Request! I very welcome any contributions.

Roadmap

In line with the previous contribute section there are some already known issues that could be resolved and are open for discussion.

  • Determining the size of the particles in the current implementation is not ideal. More here: #7 Confetti size system
  • A performance improvement to the library could for one be to implement a shared object pool amongst all particle systems instead of having them to handle confetti instances themselves.

License

Konfetti is released under the ISC license. See LICENSE for details.

Comments
  • NoClassDefFoundError kotlin/jvm/internal/Intrinsics

    NoClassDefFoundError kotlin/jvm/internal/Intrinsics

    Hi,

    This error occures with the new version 1.1.1

    java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
    	at nl.dionsegijn.konfetti.ParticleSystem.<init>(ParticleSystem.kt)
    	at nl.dionsegijn.konfetti.KonfettiView.build(KonfettiView.kt:39)
    

    1.1.0 is OK.

    opened by kwiky 13
  • Version 2.0 and 2.1 xml class not found

    Version 2.0 and 2.1 xml class not found

    i have added the implementation to my build.gradle, but in xml the KonfettiView is not found: These are my dependencies: dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'nl.dionsegijn:konfetti-xml:2.0.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    

    }

    opened by 0Flush0 9
  • Activity crash without errors

    Activity crash without errors

    My activity layout:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".Activities.ActAdelante">
    
        <nl.dionsegijn.konfetti.KonfettiView
            android:id="@+id/viewKonfetti"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </LinearLayout>
    

    And my activity:

    public class ActAdelante extends AppCompatActivity {
    
        private MediaPlayer mp;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_act_adelante);
            mp = MediaPlayer.create(this, R.raw.best_part);
            mp.start();
            KonfettiView viewKonfetti = findViewById(R.id.viewKonfetti);
            viewKonfetti.build()
                    .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA)
                    .setDirection(0.0, 359.0)
                    .setSpeed(1f, 5f)
                    .setFadeOutEnabled(true)
                    .setTimeToLive(2000L)
                    .addShapes(Shape.RECT, Shape.CIRCLE)
                    .addSizes(new Size(12, 5f))
                    .setPosition(-50f, viewKonfetti.getWidth() + 50f, -50f, -50f)
                    .streamFor(300, 5000L);
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            mp.stop();
            mp.release();
        }
    }
    

    Not working and also not showing any error why is crashing.

    opened by hbjosemaria 9
  • Upgrading to Konfetti 2.0.1 -> compilation warning

    Upgrading to Konfetti 2.0.1 -> compilation warning

    See this PR: https://buildkite.com/matrix-dot-org/element-android/builds/5770

    You can see the warning in the CI logs. I get this warning:

     w: Runtime JAR files in the classpath should have the same version. These files were found in the classpath:
        /home/runner/.gradle/caches/transforms-3/41d05d97beee476cec3719b95e795601/transformed/jetified-kotlin-stdlib-jdk8-1.5.31.jar (version 1.5)
        /home/runner/.gradle/caches/transforms-3/cee23d725568e4b6759fa7d67a5ff9d9/transformed/jetified-kotlin-stdlib-jdk7-1.5.31.jar (version 1.5)
        /home/runner/.gradle/caches/transforms-3/0393eb3dd5596ff020754d2c6fc3662b/transformed/jetified-kotlin-stdlib-1.6.0.jar (version 1.6)
        /home/runner/.gradle/caches/transforms-3/78fef6caf680a33558f1ee83f52758dc/transformed/jetified-kotlin-stdlib-common-1.6.0.jar (version 1.6)
    w: Some runtime JAR files in the classpath have an incompatible version. Consider removing them from the classpath
    

    I am not sure how to get ride of this warning, if anyone has an idea.

    opened by bmarty 7
  • added method to expose gravity control.

    added method to expose gravity control.

    Hey @DanielMartinus

    added method to expose vertical/bottom gravity control. I think this would be helpful in controlling the momentum of the confettis with higher speeds, so that they don't just jump out of screen, when burst in upward direction. Kept the defaults same.

    I'm also thinking to work on gravity control on x-axis, to allow change in gravity direction as well. let me know what you think.

    opened by akashraghav 7
  • Particles alignment problem

    Particles alignment problem

    When I call below code directly in onCreate method of my activity, I get particles coming down from left of the screen. But, If I put the same code in onClick event, I see that particles come down from the center.

    oncreate() {
      konfettiView.build()
            .addColors(Color.rgb(255, 36, 0), Color.rgb(120, 116, 242), Color.rgb(255, 232, 103))
            //.addColors(Color.rgb(168,100,253), Color.rgb(255,113,141), Color.rgb(120,255,68))
            .setDirection(0.0, 359.0)
            .setSpeed(1f, 5f)
            .setFadeOutEnabled(true)
            .setTimeToLive(2000L)
            .addShapes(Shape.RECT, Shape.CIRCLE)
            .addSizes(new Size(12, 5f))
            .setPosition(-50f, konfettiView.getWidth() + 50f, -50f, -50f)
            .streamFor(300, 5000L);
    }
    
    konfettiView.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(final View view) {
              konfettiView.build()
                .addColors(Color.rgb(255, 36, 0), Color.rgb(120, 116, 242), Color.rgb(255, 232, 103))
                //.addColors(Color.rgb(168,100,253), Color.rgb(255,113,141), Color.rgb(120,255,68))
                .setDirection(0.0, 359.0)
                .setSpeed(1f, 5f)
                .setFadeOutEnabled(true)
                .setTimeToLive(2000L)
                .addShapes(Shape.RECT, Shape.CIRCLE)
                .addSizes(new Size(12, 5f))
                .setPosition(-50f, konfettiView.getWidth() + 50f, -50f, -50f)
                .streamFor(300, 5000L);
          }
    });
    
    opened by durgesh2020 7
  • make speed density independent

    make speed density independent

    Hi @DanielMartinus!

    I noticed in my project that devices with low pixel density had much higher particle velocity than I had developed for and realized that this is because velocity is in terms of pixels and not dip in the library. Here is a comparison between 5 inch ldpi and xxhdpi devices with no change on the simple demo:

    LDPI: ldpi-before XXHDPI: xxhdpi-before

    as you can see the particles on the ldpi device are traveling 4x as fast as the xxhdpi device. Here is a comparison after the change:

    LDPI: ldpi-after XXHDPI: xxhdpi-after

    I would expect that velocity remaining constant across pixel densities is desired behavior, but if you think that some might not want this I would be happy to update the PR so that this is an option passed to the particle system (something like setSpeedPixelIndependent()). Thanks for the great library!

    opened by cmt218 6
  • Add support for custom shapes

    Add support for custom shapes

    Closes #11

    Main API change is a switch of the Shape type from an enum to an interface. With an interface, consumers are free to create whatever shape they want, so long as they can draw it using canvas operations. I also added rectangles and drawables as built-in shape implementations.

    opened by mattprecious 6
  • OutOfMemoryError

    OutOfMemoryError

    Hi, thanks for your awesome library.

    I got a crash report of an OutOfMemoryError that was caused by Konfetti.

    Device: Samsung Galaxy S7 Android version: 7.0 Trace:

    Fatal Exception: java.lang.OutOfMemoryError: Failed to allocate a 4861960 byte allocation with 2445416 free bytes and 2MB until OOM
           at java.util.Arrays.copyOf(Arrays.java:3231)
           at java.util.Arrays.copyOf(Arrays.java:3204)
           at java.util.ArrayList.grow(ArrayList.java:249)
           at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:223)
           at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:215)
           at java.util.ArrayList.add(ArrayList.java:441)
           at nl.dionsegijn.konfetti.emitters.RenderSystem.addConfetti(RenderSystem.kt:1034)
           at nl.dionsegijn.konfetti.emitters.RenderSystem$1.invoke(RenderSystem.kt:1030)
           at nl.dionsegijn.konfetti.emitters.StreamEmitter.createParticle(StreamEmitter.kt:2057)
           at nl.dionsegijn.konfetti.KonfettiView.nl.dionsegijn.konfetti.emitters.RenderSystem.render(KonfettiView.kt:2046)
           at android.view.View.draw(View.java:18319)
           at android.view.View.updateDisplayListIfDirty(View.java:17297)
           at android.view.View.draw(View.java:18081)
           at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
           at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
           at android.view.View.updateDisplayListIfDirty(View.java:17292)
           at android.view.View.draw(View.java:18081)
           at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
           at android.support.design.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1254)
           at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
           at android.view.View.updateDisplayListIfDirty(View.java:17292)
           at android.view.View.draw(View.java:18081)
           at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
           at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
           at android.view.View.updateDisplayListIfDirty(View.java:17292)
           at android.view.View.draw(View.java:18081)
           at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
           at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
           at android.view.View.updateDisplayListIfDirty(View.java:17292)
           at android.view.View.draw(View.java:18081)
           at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
           at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
           at android.view.View.updateDisplayListIfDirty(View.java:17292)
           at android.view.View.draw(View.java:18081)
           at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
           at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
           at android.view.View.updateDisplayListIfDirty(View.java:17292)
           at android.view.View.draw(View.java:18081)
           at android.view.ViewGroup.drawChild(ViewGroup.java:3966)
           at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3752)
           at android.view.View.draw(View.java:18322)
           at com.android.internal.policy.DecorView.draw(DecorView.java:854)
           at android.view.View.updateDisplayListIfDirty(View.java:17297)
           at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:666)
           at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:672)
           at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:780)
           at android.view.ViewRootImpl.draw(ViewRootImpl.java:3112)
           at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2908)
           at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2502)
           at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1509)
           at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7051)
           at android.view.Choreographer$CallbackRecord.run(Choreographer.java:927)
           at android.view.Choreographer.doCallbacks(Choreographer.java:702)
           at android.view.Choreographer.doFrame(Choreographer.java:638)
           at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:913)
           at android.os.Handler.handleCallback(Handler.java:751)
           at android.os.Handler.dispatchMessage(Handler.java:95)
           at android.os.Looper.loop(Looper.java:154)
           at android.app.ActivityThread.main(ActivityThread.java:6692)
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
    

    And my setup was:

    binding.konfetti.build() 
        .addColors(Color.rgb(239, 115, 47), Color.rgb(161, 44, 46), Color.rgb(39, 71, 134), Color.WHITE) 
        .setSpeed(1f, 3f) 
        .setFadeOutEnabled(true) 
        .setTimeToLive(3000L) 
        .addShapes(Shape.RECT, Shape.CIRCLE) 
        .addSizes(new Size(12, 5)) 
        .setDirection(0.0, 180.0) 
        .setPosition(0, (float) binding.mainContent.getWidth(), -100F, -100F) 
        .stream(70, 3000L);
    

    I just got one crash report, so I guess is some edge case.

    Cheers!

    opened by davidmigloz 6
  • Change axis acceleration option

    Change axis acceleration option

    I wonder if it is possible to change axis acceleration, to make the confettis fall faster/slower, or even fall in a constant velocity. I think it would be great to manipulate the acceleration, specially on y axis.

    Oh, and thanks for the great lib!

    feature 
    opened by GBL147852 6
  • Add a stop function to konfettiView

    Add a stop function to konfettiView

    There is no way to stop active particle systems yet. This should be an easy implementation.

    • Add support to stop a single particle system
    • Add support to stop alle particle systems alltogether
    feature 
    opened by DanielMartinus 6
  • Fatal Exception: java.lang.OutOfMemoryError

    Fatal Exception: java.lang.OutOfMemoryError

    Hi, faced with crash while using compose version of lib:

    Fatal Exception: java.lang.OutOfMemoryError
    Failed to allocate a 96 byte allocation with 916176 free bytes and 894KB until OOM, target footprint 268435456, growth limit 268435456; giving up on allocation because <1% of heap free after GC.
    

    Here is full stacktrace:

    android.graphics.drawable.VectorDrawable.mutate (VectorDrawable.java:389)
    **nl.dionsegijn.konfetti.core.emitter.PartyEmitter.getRandomShape (PartyEmitter.kt:160)**
    nl.dionsegijn.konfetti.core.emitter.PartyEmitter.createParticle (PartyEmitter.kt:79)
    nl.dionsegijn.konfetti.core.emitter.PartyEmitter.createConfetti (PartyEmitter.kt:56)
    nl.dionsegijn.konfetti.core.PartySystem.render (PartySystem.kt:32)
    nl.dionsegijn.konfetti.compose.KonfettiViewKt$KonfettiView$1$2.invoke (KonfettiView.kt:63)
    nl.dionsegijn.konfetti.compose.KonfettiViewKt$KonfettiView$1$2.invoke (KonfettiView.kt:45)
    androidx.compose.runtime.MonotonicFrameClockKt$withFrameMillis$2.invoke (MonotonicFrameClock.kt:66)
    androidx.compose.runtime.MonotonicFrameClockKt$withFrameMillis$2.invoke (MonotonicFrameClock.kt:66)
    androidx.compose.runtime.BroadcastFrameClock$FrameAwaiter.resume (BroadcastFrameClock.kt:42)
    androidx.compose.runtime.BroadcastFrameClock.sendFrame (BroadcastFrameClock.kt:71)
    androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke (Recomposer.kt:510)
    androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke (Recomposer.kt:503)
    androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame (AndroidUiFrameClock.android.kt:34)
    androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch (AndroidUiDispatcher.android.kt:109)
    androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch (AndroidUiDispatcher.android.kt:41)
    androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame (AndroidUiDispatcher.android.kt:69)
    android.view.Choreographer$CallbackRecord.run (Choreographer.java:1229)
    android.view.Choreographer$CallbackRecord.run (Choreographer.java:1239)
    android.view.Choreographer.doCallbacks (Choreographer.java:899)
    android.view.Choreographer.doFrame (Choreographer.java:827)
    android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:1214)
    android.os.Handler.handleCallback (Handler.java:942)
    android.os.Handler.dispatchMessage (Handler.java:99)
    android.os.Looper.loopOnce (Looper.java:201)
    android.os.Looper.loop (Looper.java:288)
    android.app.ActivityThread.main (ActivityThread.java:7898)
    java.lang.reflect.Method.invoke (Method.java)
    com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
    com.android.internal.os.ZygoteInit.main (ZygoteInit.java:936)
    
    opened by NKosyanchuk 1
  • Add support for Emoji/Text confetti Shapes

    Add support for Emoji/Text confetti Shapes

    It would be nice to have the ability add emojis to the confetti.

    These updates only update the "engine" to support adding emojis. I have found that they look better without the 3D rotation, so in my own project I have changed that part of the rotation code to look like so:

    particles.forEach { particle ->
                    withTransform({
                        if (particle.shape is Shape.Text) {
                            rotate(
                                degrees = particle.rotation,
                                pivot = Offset(
                                    x = particle.x,
                                    y = particle.y
                                )
                            )
                        } else {
                            rotate(
                                degrees = particle.rotation,
                                pivot = Offset(
                                    x = particle.x + (particle.width / 2),
                                    y = particle.y + (particle.height / 2)
                                )
                            )
                            scale(
                                scaleX = particle.scaleX,
                                scaleY = 1f,
                                pivot = Offset(particle.x + (particle.width / 2), particle.y)
                            )
                        }
                    }) {
                        particle.shape.draw(this, particle)
                    }
                }
    

    But I do not know if you want this part of the composable to be configurable or not. I am open to suggestions (if you even want to add emoji support).

    I could not add anything to the samples since they use the pre built dependency, but here is a video of what it looks like from my own project:

    https://user-images.githubusercontent.com/17356172/173049943-b30fe915-b789-453c-8402-6a295eb5b4bd.mp4

    opened by jasonctoms 0
  • Custom DrawableShape (PNG drawable) displays incorrectly

    Custom DrawableShape (PNG drawable) displays incorrectly

    Using a PNG drawable to create a custom DrawableShape with tint = false results in the drawable being displayed as though a white tint has been applied (see video below along with the PNG file I'm using).

    Environment

    Device: moto g31(w) Android version: 11 Konfetti: nl.dionsegijn:konfetti-compose:2.0.2

    Code

    @Composable
    fun EmojiRain(
        @DrawableRes drawables: List<Int>,
        onEnd: (() -> Unit)?,
        modifier: Modifier = Modifier
    ) {
        val shapes = drawables.mapNotNull {
            ContextCompat.getDrawable(LocalContext.current, it)?.let { drawable ->
                Shape.DrawableShape(drawable = drawable, tint = false)
            }
        }
    
        KonfettiView(
            parties = listOf(
                Party(
                    angle = Angle.BOTTOM,
                    spread = 1,
                    rotation = Rotation(
                        enabled = true,
                        multiplier2D = 1f,
                        multiplier3D = 0f,
                    ),
                    speed = 1f,
                    maxSpeed = 6f,
                    damping = 1f,
                    timeToLive = 2000L,
                    size = (12..42 step 6).map { Size(it) },
                    shapes = shapes,
                    emitter = Emitter(duration = 2, TimeUnit.SECONDS).perSecond(10),
                    position = Position
                        .Relative(0.0, 0.0)
                        .between(Position.Relative(1.0, 0.0)),
                )
            ),
            updateListener = object : OnParticleSystemUpdateListener {
                override fun onParticleSystemEnded(system: PartySystem, activeSystems: Int) {
                    onEnd?.invoke()
                }
            },
            modifier = modifier,
        )
    }
    

    Video of issue

    https://user-images.githubusercontent.com/13498475/168575719-75eff0e2-d48d-44ef-a386-55f7ee898a92.mp4

    PNG drawable

    emoji_thumbs_up

    opened by MatthewCallery 1
  • API 21/22 crash during onVisibilityChanged

    API 21/22 crash during onVisibilityChanged

    When running konfetti-xml : 2.0.2 on API 21/22 (could also include lower version but haven't tested) the View lifecycle causes a crash. It looks like the constructor is directly calling into onVisibilityChanged causing a NPE as the fields are not yet initialised

    Caused by: java.lang.NullPointerException: 
      at nl.dionsegijn.konfetti.xml.KonfettiView.onVisibilityChanged (KonfettiView.kt:3)
      at android.view.View.dispatchVisibilityChanged (View.java:9306)
      at android.view.View.setFlags (View.java:10737)
      at android.view.View.<init> (View.java:4410)
      at android.view.View.<init> (View.java:3891)
      at android.view.View.<init> (View.java:3870)
      at nl.dionsegijn.konfetti.xml.KonfettiView.<init> (KonfettiView.kt:1)
    
    opened by ouchadam 0
  • java.lang.OutOfMemoryError

    java.lang.OutOfMemoryError

    Samsung Galaxy Android10, Android11 lib version:1.2.0

    java.lang.OutOfMemoryError: at java.util.Arrays.copyOf (Arrays.java:3136) at java.util.Arrays.copyOf (Arrays.java:3106) at java.util.ArrayList.grow (ArrayList.java:275) at java.util.ArrayList.ensureExplicitCapacity (ArrayList.java:249) at java.util.ArrayList.ensureCapacityInternal (ArrayList.java:241) at java.util.ArrayList.add (ArrayList.java:467) at nl.dionsegijn.konfetti.emitters.RenderSystem.addConfetti (RenderSystem.java) at nl.dionsegijn.konfetti.emitters.RenderSystem.access$addConfetti (RenderSystem.java) at nl.dionsegijn.konfetti.emitters.RenderSystem$1.invoke (RenderSystem.java) at nl.dionsegijn.konfetti.emitters.RenderSystem$1.invoke (RenderSystem.java) at nl.dionsegijn.konfetti.emitters.StreamEmitter.createParticle (StreamEmitter.java) at nl.dionsegijn.konfetti.emitters.StreamEmitter.createConfetti (StreamEmitter.java) at nl.dionsegijn.konfetti.emitters.RenderSystem.render (RenderSystem.java) at nl.dionsegijn.konfetti.KonfettiView.onDraw (KonfettiView.java) at android.view.View.draw (View.java:23187) at android.view.View.updateDisplayListIfDirty (View.java:22062) at android.view.View.draw (View.java:22917) at android.view.ViewGroup.drawChild (ViewGroup.java:5230) at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4987) at android.view.View.draw (View.java:23190) at com.google.android.material.appbar.AppBarLayout.draw (AppBarLayout.java) or .shouldDrawStatusBarForeground (AppBarLayout.java) at android.view.View.updateDisplayListIfDirty (View.java:22062) at android.view.View.draw (View.java:22917) at android.view.ViewGroup.drawChild (ViewGroup.java:5230) at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild (CoordinatorLayout.java:140) at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4987) at android.view.View.updateDisplayListIfDirty (View.java:22048) at android.view.View.draw (View.java:22917) at android.view.ViewGroup.drawChild (ViewGroup.java:5230) at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4987) at android.view.View.updateDisplayListIfDirty (View.java:22048) at android.view.View.draw (View.java:22917) at android.view.ViewGroup.drawChild (ViewGroup.java:5230) at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4987) at android.view.View.updateDisplayListIfDirty (View.java:22048) at android.view.View.draw (View.java:22917) at android.view.ViewGroup.drawChild (ViewGroup.java:5230) at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4987) at android.view.View.updateDisplayListIfDirty (View.java:22048) at android.view.View.draw (View.java:22917) at android.view.ViewGroup.drawChild (ViewGroup.java:5230) at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4987) at android.view.View.updateDisplayListIfDirty (View.java:22048) at android.view.View.draw (View.java:22917) at android.view.ViewGroup.drawChild (ViewGroup.java:5230) at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4987) at android.view.View.draw (View.java:23190) at com.android.internal.policy.DecorView.draw (DecorView.java:1154) at android.view.View.updateDisplayListIfDirty (View.java:22062) at android.view.ThreadedRenderer.updateViewTreeDisplayList (ThreadedRenderer.java:588) at android.view.ThreadedRenderer.updateRootDisplayList (ThreadedRenderer.java:594) at android.view.ThreadedRenderer.draw (ThreadedRenderer.java:667) at android.view.ViewRootImpl.draw (ViewRootImpl.java:4296) at android.view.ViewRootImpl.performDraw (ViewRootImpl.java:4080) at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:3348) at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:2225) at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:9126) at android.view.Choreographer$CallbackRecord.run (Choreographer.java:999) at android.view.Choreographer.doCallbacks (Choreographer.java:797) at android.view.Choreographer.doFrame (Choreographer.java:732) at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:984) at android.os.Handler.handleCallback (Handler.java:883) at android.os.Handler.dispatchMessage (Handler.java:100) at android.os.Looper.loop (Looper.java:237) at android.app.ActivityThread.main (ActivityThread.java:8173) at java.lang.reflect.Method.invoke (Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:496) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1100)

    opened by HolyShot 0
Releases(v2.0.2)
  • v2.0.2(Feb 20, 2022)

    Fixes

    • (#287) Lower minSdk for konfetti-compose to api 21
    • (#288) Fix Out of Memory exception by @PaulKlauser
    • (#295) Improve transitive dependency setup
    Source code(tar.gz)
    Source code(zip)
  • v2.0.1(Jan 2, 2022)

    This is a patch for the 2.0.0 release. Core classes weren't exposed making the library unusable and it includes some other small fixes that shouldn't have end up in a release.

    Fixes

    • (https://github.com/DanielMartinus/Konfetti/issues/284) Include core classes in konfetti-xml and konfetti-compose. Thanks @GhislainVerrier for reporting the issue
    • (https://github.com/DanielMartinus/Konfetti/commit/28789939f3fd49399041b532cea89ca5bdda4a48) Remove log from core library
    • (https://github.com/DanielMartinus/Konfetti/commit/2da7554f99a7763fe0eead8cc9eee4ef55ca82f2) Remove unused compose dependencies and replace them with foundation https://github.com/DanielMartinus/Konfetti/commit/882232326378c2f25caa8c0fa7f5d0aaed4c1648
    Source code(tar.gz)
    Source code(zip)
    compose-kotlin-debug.apk(7.50 MB)
    xml-java-debug.apk(4.22 MB)
    xml-kotlin-debug.apk(4.25 MB)
  • v2.0.0(Dec 29, 2021)

    Migrating from 1.x.x to 2.x.x? Read on how to migrate here

    Be aware that the path to include Konfetti in Gradle has changed:

    // old
    implementation 'nl.dionsegijn:konfetti:1.3.2'
    
    // new
    implementation 'nl.dionsegijn:konfetti-compose:2.0.0'
    implementation 'nl.dionsegijn:konfetti-xml:2.0.0'
    

    What changed?

    • Support for compose
    • New and improved API using Party for configuring Confetti
    • Add more options for customization and randomness
    • Improved animation using damping which is configurable in Party
    • Beisdes using absolute position with Position.Absolute(x,y) there's now also a way to set the relative position with Position.Relative(x, y) and randomize spawn point chaining two positions with between with: Position.Relative(x,y).between(Position.Relative(x,y))
    • Easily configure Party with Presets such as Angle.TOP, Spread.Wide, and Rotation.disabled()
    • Simplified and improved core implementation
    • Decoupled core code to decouple core code from rendering
    • Modularized core - compose - xml
    • Add more sample projects and simplified existing sample projects
    • Updated readme with details on the new API
    • Releasing with blog post as migration guide to v2.0.0 https://dionsegijn.dev/konfetti-migration-guide-v2.0.0
    Source code(tar.gz)
    Source code(zip)
    compose-kotlin-debug.apk(12.56 MB)
    xml-java-debug.apk(4.22 MB)
    xml-kotlin-debug.apk(4.25 MB)
  • v1.3.2(Mar 11, 2021)

    This release contains an important fix that addresses showing a different velocity across between low density and high density pixel devices. Thanks to the fix of @cmt218 the pixel density is taken into account.

    Important when updating

    When migrating to this new version the results of your Konfetti might look different. Please check whether it's still the desired outcome. To opt-out for this change you can set setSpeedDensityIndependent to false. However, this is a temporary solution. It's advised to test out your Konfetti implementation to see if it still behaves as expected. More information in this PR:

    • (#249) Fix density independent velocity calculations by @cmt218

    This is the same release as v1.3.0 but includes the correct .aar which caused some issues in v1.3.0

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Mar 9, 2021)

    This release contains an important fix that addresses showing a different velocity across between low density and high density pixel devices. Thanks to the fix of @cmt218 the pixel density is taken into account.

    Important when updating

    When migrating to this new version the results of your Konfetti might look different. Please check whether it's still the desired outcome. To opt-out for this change you can set setSpeedDensityIndependent to false. However, this is a temporary solution. It's advised to test out your Konfetti implementation to see if it still behaves as expected. More information in this PR:

    • (#249) Fix density independent velocity calculations by @cmt218
    Source code(tar.gz)
    Source code(zip)
  • v1.2.6(Sep 27, 2020)

    Added

    • (https://github.com/DanielMartinus/Konfetti/pull/237) Added functionality to expose and control gravity by @akashraghav

    Enhancement

    • (https://github.com/DanielMartinus/Konfetti/pull/224) Fix loss of precision when calculating deltatime by @uwemaurer
    • (https://github.com/DanielMartinus/Konfetti/pull/226) Optimizations in the rendering loop @learnice

    A list of pull requests tagged for v1.2.6 can be found here: https://github.com/DanielMartinus/Konfetti/pulls?q=is%3Apr+is%3Aclosed+milestone%3A1.2.6

    Source code(tar.gz)
    Source code(zip)
  • v1.2.4(Sep 10, 2020)

    This release adds the option to control the rotation speed of the particles

    Use setRotationSpeedMultiplier to set a multiplier to control the rotation speed of the Confetti Use setRotationSpeedVariance to control the randomness of the confetti

    Pull request: #189 Issue: #185

    Thanks to @carlfindahl for his contribution

    Source code(tar.gz)
    Source code(zip)
  • v1.2.2(Jul 5, 2020)

    This release adds the option to control the acceleration of the particles Pull request: #158 Issue: #48

    Turn off acceleration

    Only turning off the acceleration will result the particles having the same velocity they begin with. This can be done with:

    konfettiView.build()
        ...
        .setAccelerationEnabled(false)
    

    Set max acceleration

    If you don't want the particles to keep the speed they begin with but have a slight change in velocity for a more natural feeling, you can use setMaxAccelaration.

    konfettiView.build()
        ...
        .setMaxAcceleration(1.5f)
    

    A maxAcceleration between 1.0 - 3.0 is visible in the lifetime of a particle

    Source code(tar.gz)
    Source code(zip)
  • v1.2.1(Jun 27, 2020)

    Added

    • ae8ca95 Stream for an indefinite amount of time when using streamFor by using StreamEmitter.INDEFINITE
    • a8cf9d1 Stop all particles from rendering gracefully and live out their lifetime by calling stopGracefully() on KonfettiView or a RenderSystem
    • 3f04a65 KonfettiView can now be extended since it's made open
    • 7f7e8c7 Disable 3D rotations of the confetti particles by calling .setRotationEnabled(false)

    Fixes

    • caf8992 Fix streamMaxParticles isFinished check
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Mar 7, 2020)

    Added

    • (https://github.com/DanielMartinus/Konfetti/pull/129) Add custom drawables as confetti thanks to @mattprecious

    Changes

    Minor API change, old ones still work due to backwards compatibility.

    | Before | Becomes | | - | - | | Shape.RECT | Shape.Square | | Shape.CIRCLE | Shape.Circle |

    Add a custom drawable like this:

    val drawable = ContextCompat.getDrawable(context, R.drawable.star)
    val star = Shape.DrawableShape(drawable)
    
    viewKonfetti.build()
                 ...
                .addShapes(star)
                .streamFor(300, 5000L)
    

    If you want to keep the original colours of the drawable set tinting to false. This is by default set to true.

    val drawable = ContextCompat.getDrawable(context, R.drawable.gradientDrawable)
    Shape.DrawableShape(drawable, false)
    
    Source code(tar.gz)
    Source code(zip)
  • v1.1.3(Apr 29, 2019)

    Minor improvements in this release.

    Added

    • (https://github.com/DanielMartinus/Konfetti/issues/61) Make particle system update listener available
    • (https://github.com/DanielMartinus/Konfetti/issues/27) Stop a particular particle system
    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(May 3, 2018)

    New contribution from @jurriaan

    Enhancements

    • (#50) Update build-tools, kotlin version and dependencies

    This update removes the following warning:

    2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.2.0/ec8b969e26fbcf2265a4d1a1539c4d1d4c5af380/kotlin-stdlib-jre7-1.2.0.jar: kotlin-stdlib-jre7 is deprecated. Please use kotlin-stdlib-jdk7 instead
    
    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Feb 25, 2018)

    Small release with a couple of enhancements

    Added

    • (https://github.com/DanielMartinus/Konfetti/pull/44) Add another way of setting colors to the ParticleSystem by @simon1573

    Enhancements

    • (https://github.com/DanielMartinus/Konfetti/pull/45) Deprecate stream functions, replaced by: streamFor and streamMaxParticles as suggested by @PaulWoitaschek here: https://github.com/DanielMartinus/Konfetti/issues/32
    • (https://github.com/DanielMartinus/Konfetti/pull/46) Changed direction to degrees as suggested by @PaulWoitaschek here: https://github.com/DanielMartinus/Konfetti/issues/33
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Sep 3, 2017)

    Added

    • (https://github.com/DanielMartinus/Konfetti/pull/26) Create your own custom emitter. Read more about it here

    Fixed issue

    • (https://github.com/DanielMartinus/Konfetti/issues/20) setting amount for particles per second didn't work. Issue reported by: @ANPez
    • (https://github.com/DanielMartinus/Konfetti/pull/18) Remove allowBackup="true" and android:supportsRtl="true" issue reported by: @foxware00
    • (https://github.com/DanielMartinus/Konfetti/issues/13) object allocation in onDraw. Move RectF creation outside of the rendering block. Issue reported by: @nekocode

    Removed

    • (https://github.com/DanielMartinus/Konfetti/pull/23) Single parameter, particles per second. This function was useless until a stop function is build in the particle system.
    • (https://github.com/DanielMartinus/Konfetti/pull/22) Three parameters, particles per second, emiting time, max particles. You are able to achieve the same results with either .stream(particlesPerSecond: Int, emittingTime: Long) or .stream(particlesPerSecond: Int, maxParticles: Int)

    I want to thank everyone who took the time to submit a pull request or reported an issue. Really appreciated πŸ‘

    Custom emiter

    With this pull request you're able to add your own custom emitter to Konfetti.

    /**
     * Created by dionsegijn on 9/03/17.
     *
     * An abstract class for creating a custom emitter
     * The only goal of the emitter is to tell when and how many particles to create
     */
    abstract class Emitter {
    
        /**
         * Call this function to tell the RenderSystem to render a particle
         */
        var addConfettiFunc: (() -> Unit)? = null
    
        /**
         * This function is called on each update when the [RenderSystem] is active
         * Keep this function as light as possible otherwise you'll slow down the render system
         */
        abstract fun createConfetti(deltaTime: Float)
    
        /**
         * Tell the [RenderSystem] when the emitter is done creating particles
         * @return true if the renderSystem is not longer creating any particles
         *         false if the renderSystem is still busy
         */
        abstract fun isFinished(): Boolean
    }
    
    

    See BurstEmitter or StreamEmitter for examples

    To start using your custom Emitter, call the following function in ParticleSystem and supply it with your custom emitter:

    
    /**
     * Add your own custom Emitter. Create your own class and extend from [Emitter]
     * See [BurstEmitter] and [StreamEmitter] as example classes on how to create your own emitter
     * By calling this function the system wil start rendering the confetti according to your custom
     * implementation
     * @param [emitter] Custom implementation of the Emitter class
     */
    fun emitter(emitter: Emitter) {
        startRenderSystem(emitter)
    }
    

    Calling your custom emitter will look something like this:

    viewKonfetti.build()
        .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA)
        ... // other properties
        .emitter(CustomEmitter())
    
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Jun 3, 2017)

    Added

    • (https://github.com/DanielMartinus/Konfetti/pull/12) Implement new size system. Instead of Size.SMALL, Size.MEDIUM, Size.LARGE add Size(12) for the size in dip or Size(12, 5f) to specify a mass and add as many sizes as you want.
    • (https://github.com/DanielMartinus/Konfetti/commit/5d8d4f6eb87f151bc715d7eccc45847877e0faf1) Remove support library from konfetti library fixing the need of a resolutionStrategy to forcefully set the support library to the same version as the one using in your app.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Jun 3, 2017)

    Added

    • (https://github.com/DanielMartinus/Konfetti/pull/10) Add callback to get notified of particle system changes OnParticleSystemUpdateListener
    Source code(tar.gz)
    Source code(zip)
  • 1.0(May 28, 2017)

Owner
Dion Segijn
Android @ Disney+
Dion Segijn
Another-read-more-lib - Another read more library for android

another-read-more-lib ?? Another read more library. Add it in your root build.gr

Geovani Amaral 9 Nov 2, 2022
[] Apply background tinting to the Android system UI when using KitKat translucent modes

Android System Bar Tint Apply background tinting to the Android system UI when using KitKat translucent modes. Android 4.4 (KitKat) introduced translu

Jeff Gilfelt 5.4k Dec 9, 2022
Floating Notification for Android app - Facebook ChatHeads Notification system

FloatingView (Application Demo on Play Store) DEPRECATED SEE FloatingView Floating View for Android app - Facebook ChatHeads Notification system This

Fernandez Anthony 530 Nov 17, 2022
Floating Notification for Android app - Facebook ChatHeads Notification system

FloatingView (Application Demo on Play Store) DEPRECATED SEE FloatingView Floating View for Android app - Facebook ChatHeads Notification system This

Fernandez Anthony 530 Nov 17, 2022
NeoPOP was created with one simple goal; to create the next generation of a beautiful, affirmative design system

NeoPop is CRED's inbuilt library for using NeoPop components in your app

CRED 254 Dec 29, 2022
Material Design implementation for Android 4.0+. Shadows, ripples, vectors, fonts, animations, widgets, rounded corners and more.

Carbon Material Design implementation for Android 4.0 and newer. This is not the exact copy of the Lollipop's API and features. It's a custom implemen

null 3k Dec 30, 2022
A nicer-looking, more intuitive and highly customizable alternative for radio buttons and dropdowns for Android.

SwipeSelector Undergoing for some API changes for a 2.0 major version, see example usage in the sample module! What and why? Bored of dull looking rad

Iiro Krankka 1.1k Dec 30, 2022
:balloon: A lightweight popup like tooltips, fully customizable with an arrow and animations.

Balloon ?? A lightweight popup like tooltips, fully customizable with arrow and animations. Including in your project Gradle Add below codes to your r

Jaewoong Eum 2.8k Jan 5, 2023
Lightweight audiowave progressbar for Android

Audiogram Super lightweight audiowave progressbar written in Kotlin Getting started Add to your root build.gradle: allprojects { repositories {

Alexey Derbyshev 465 Jan 5, 2023
A lightweight non intrusive app rate reminder for Android

Discreet App Rate A lightweight non intrusive app rate reminder for Android Download repositories { mavenCentral() } dependencies { compile '

Nicolas POMEPUY 469 Nov 10, 2022
Simple and lightweight UI library for user new experience, combining floating bottom navigation and bottom sheet behaviour. Simple and beautiful.

Simple and lightweight UI library for user new experience, combining floating bottom navigation and bottom sheet behaviour. Simple and beautiful.

Rizki Maulana 118 Dec 14, 2022
A Lightweight Framework for Code Generating

Codegen A lightweight framework for code generating. Why Codegen? In Java/Kotlin world, engineers usually use JavaPoet or KotlinPoet for code generati

Johnson Lee 38 Dec 20, 2022
Celebrate more with this lightweight confetti particle system 🎊

Konfetti ?? ?? Celebrate more with this lightweight confetti particle system. Create realistic confetti by implementing this easy to use library. Demo

Dion Segijn 2.7k Dec 28, 2022
A lightweight particle system for Jetpack Compose - Quarks

compose-particle-system Quarks is a lightweight particle system for Jetpack Compose. There are endless possibilities for creating generative art with

Nikhil Chaudhari 41 Dec 28, 2022
Particle clock created with Jetpack Compose framework

Jetpack Compose Particle Clock made with Jetpack Compose This project is inspired by Flutter Particle Clock. License Copyright 2018 Adib Faramarzi. Li

Adib Faramarzi 366 Dec 29, 2022
Effect of particle Boom

ParticleDismissLayout #η²’ε­η’Žθ£‚ζ•ˆζžœ Effect of particle Boom. θ§†ε›Ύη’Žθ£‚ζ•ˆζžœγ€‚ #Preview #Usage #java final ParticleView particleAnimator = new ParticleView(MainActiv

张珂 43 Jan 21, 2022
A particle view library written in kotlin, easy to use

particle 中文介绍 This is a handy android library for particle effect. To start with, you need to add it in your root build.gradle at the end of repositor

null 89 Nov 14, 2022
A plugin system that runs like a browser, but instead of load web pages, it load apk plugins which runs natively on Android system.

Android Dynamic Loader Android Dynamic Loader is a plugin system. The host application is like a browser, but instead of load web pages, it load plugi

Tu Yimin 1.4k Dec 28, 2022
Awesome RunnerBe design system and more!

Honeycomb Awesome RunnerBe design system and more! Core Preview 아직 λͺ¨λ“  μš”μ†Œκ°€ κ΅¬ν˜„λ˜μ§€ μ•Šμ•˜μœΌλ©° λ‹¨μˆœνžˆ 미리보기 μž…λ‹ˆλ‹€ class MainActivity : AppCompatActivity() { overri

RunnerBe 2 Apr 21, 2022
πŸ“­ Extension to Ktor’s routing system to add object oriented routing and much more. πŸ’œ

?? Ktor Routing Extensions Extension to Ktor’s routing system to add object-oriented routing and much more. ?? Why? This extension library was created

Noelware 6 Dec 28, 2022