Coder Social home page Coder Social logo

danielmartinus / konfetti Goto Github PK

View Code? Open in Web Editor NEW
3.0K 48.0 294.0 4.81 MB

Celebrate more with this lightweight confetti particle system 🎊

License: MIT License

Kotlin 100.00%
android kotlin animations particles canvas party particle-system android-animation android-ui compose

konfetti's Introduction


Logo

Easily celebrate little and big moments in your app with this lightweight confetti library!

License API level 16 API level 16 Build Status

Getting startedHow To UseCommunityContributeReport issueLicense

New version: 2.0.0 is now released! Jetpack compose support - improved animations and API - see migration guide here

Getting started

Compose project:

dependencies {
    implementation 'nl.dionsegijn:konfetti-compose:2.0.4'
}

View based (XML) project:

dependencies {
    implementation 'nl.dionsegijn:konfetti-xml:2.0.4'
}

Find latest version and release notes here

Usage

Samples:
composexml-kotlinxml-javapresets

Configure your confetti using the Party configuration object. This holds all the information on how the confetti will be generated. Almost all properties of a Party object have a default configuration! This makes it super easy to create beautiful and natural looking confetti.

The bare minimum you need is an Emitter to tell how often and how many confetti should spawn, like this:

Party(
    emitter = Emitter(duration = 5, TimeUnit.SECONDS).perSecond(30)
)

But the possibilities are endless! You can fully control how the confetti will be generated and behave by customizing the values of the Party object. An example of a customized Party configuration is this:

Party(
    speed = 0f,
    maxSpeed = 30f,
    damping = 0.9f,
    spread = 360,
    colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
    position = Position.Relative(0.5, 0.3),
    emitter = Emitter(duration = 100, TimeUnit.MILLISECONDS).max(100)
)

To learn more, see more samples linked at the top of this section

Party options

  • Angle - Int (default: 0): The direction the confetti will shoot. Use any integer between 0-360 or use presets like: Angle.TOP, Angle.RIGHT, Angle.BOTTOM, Angle.LEFT. Angle.RIGHT equates to 0 degrees, and larger values move clockwise from this position.
  • spread - Int (default: 360): How wide the confetti will shoot in the direction of Angle. Use any integer between 0-360. Use 1 to shoot in a straight line and 360 to form a circle
  • speed - Float (default: 30f): The start speed of the confetti at the time of creation.
  • maxSpeed - Float (default: 0f): Set to -1 to disable maxSpeed. A random speed between speed and maxSpeed will be chosen. Using randomness creates a more natural and realistic look to the confetti when animating.)
  • damping - Float (default: 0.9f): The rate at which the speed will decrease right after shooting the confetti
  • size - List<Size> (default: SMALL, MEDIUM, LARGE): The size of the confetti. Use: Size.SMALL, MEDIUM or LARGE for default sizes or create your custom size using a new instance of Size.
  • colors - List<Int> (default: 0xfce18a, 0xff726d, 0xf4306d, 0xb48def): List of colors that will be randomly picked from
  • shapes - List<Shape> (default: Shape.Square, Shape.Circle): Or use a custom shape with Shape.DrawableShape
  • timeToLive - Long (default: 2000): The time in milliseconds a particle will stay alive after that the confetti will disappear.
  • fadeOutEnabled - Boolean (default: true): If true and a confetti disappears because it ran out of time (set with timeToLive) it will slowly fade out. If set to falls it will instantly disappear from the screen.
  • position - Position (default: Position.Relative(0.5, 0.5)): the location where the confetti will spawn from relative to the canvas. Use absolute coordinates with [Position.Absolute] or relative coordinates between 0.0 and 1.0 using [Position.Relative]. Spawn confetti between random locations using [Position.between].
  • delay - Int (default: 0): the amount of milliseconds to wait before the rendering of the confetti starts
  • rotation - Rotation (default: Rotation): enable the 3D rotation of a Confetti. See [Rotation] class for the configuration options. Easily enable or disable it using [Rotation].enabled() or [Rotation].disabled() and control the speed of rotations.
  • emitter - EmitterConfig: Instructions how many and how often a confetti particle should spawn. Use Emitter(duration, timeUnit).max(amount) or Emitter(duration, timeUnit).perSecond(amount) to configure the Emitter.

See Party implementation here

KonfettiView

Create a KonfettiView in your compose UI or add one to your xml layout depending on your setup.

Compose

KonfettiView(
    modifier = Modifier.fillMaxSize(),
    parties = state.party,
)

View-based (xml)

<nl.dionsegijn.konfetti.xml.KonfettiView
    android:id="@+id/konfettiView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
Party(
    speed = 0f,
    maxSpeed = 30f,
    damping = 0.9f,
    spread = 360,
    colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def),
    emitter = Emitter(duration = 100, TimeUnit.MILLISECONDS).max(100),
    position = Position.Relative(0.5, 0.3)
)
viewKonfetti.start(party)

And that's it! There are endless possibilities to configure the confetti. If you want to learn more on how to implement Konfetti in a java, xml or compose project then see the samples linked at the top of this section

Community

  • Follow me on twitter for updates here
  • Do you have any questions or need help implementing this library? Search if your question is already asked here
  • Or join our telegram chat group and maybe someone can help you out here

Contribute

Do you see any improvements or want to implement a missing feature? Contributions are very welcome!

  • Is your contribution relatively small? You can, make your changes, run the code checks, open a PR and make sure the CI is green. That's it!
  • Are the changes big and do they make a lot of impact? Please open an issue here or reach out and let's discuss.

Take into account that changes and requests can be rejected if they don't align with the purpose of the library. To not waste any time you can always open an issue here to talk before you start making any changes.

What is the purpose of this library?

To have a lightweight particle system to easily generate confetti particles to celebrate little and big moments. Even though this is a particle system the purpose is not to be a fully fledged particle system. Changes and features are meant to be in line with being a confetti library. A great example is the implementation of custom shapes by @mattprecious here.

Report an issue

  • Did you find an issue and want to fix it yourself? See Contribute for more information
  • Want to report an issue? You can do that here. By adding as much details when reporting the issue and steps to reproduce you improve the change it will be solved quickly.

License

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

konfetti's People

Contributors

alexbirkett avatar benju69 avatar carlfindahl avatar danielmartinus avatar davwheat avatar dependabot-preview[bot] avatar dependabot[bot] avatar dostalleos avatar foxware00 avatar jaeheonshim avatar jurriaan avatar kevinrob avatar konfetti-bot avatar laurentyhuel avatar learnice avatar mattprecious avatar paulklauser avatar uwemaurer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

konfetti's Issues

KonfettiView blocking touch?

I want to overlay the KonfettiView over another view, but that view should remain clickable.
It seems KonfettiView is not allowing the view below it to capture clicks. If I put the other view above it, the KonfettiView isn't visible.
Here's my xml:


        <LinearLayout
            android:id="@+id/support_dialog"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content"
            android:layout_margin="15dp"
            android:layout_gravity="center_horizontal|center_vertical"
            android:orientation="horizontal"
            >
            <Button
                android:id="@+id/support_btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/circle"
                android:layout_marginRight="15dp"
                android:layout_marginEnd="15dp"
                android:text="@string/support"
                />

            <Button
                android:id="@+id/dont_support_btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/circle"
                android:layout_marginRight="15dp"
                android:layout_marginEnd="15dp"
                android:text="@string/dont_support"
                />
        </LinearLayout>
    <nl.dionsegijn.konfetti.KonfettiView
        android:id="@+id/viewKonfetti"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible"
        />

Annimation Not working

I used you library to show the animation it worked fine on moto but when i checked on S8+ it did not worked .
But I installed your app form playstore it worked fine
What can be the issue

Crashes when I add the view

Hello, I am using java, tried every version of konfetti but App keeps crashing when i add the view like this;

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

Here are the logs

java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
        at nl.dionsegijn.konfetti.KonfettiView.onDraw(Unknown Source:2)
        at android.view.View.draw(View.java:20207)
        at android.view.View.updateDisplayListIfDirty(View.java:19082)
        at android.view.View.draw(View.java:19935)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
        at android.view.View.draw(View.java:20210)
        at android.view.View.updateDisplayListIfDirty(View.java:19082)
        at android.view.View.draw(View.java:19935)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
        at android.view.View.updateDisplayListIfDirty(View.java:19073)
        at android.view.View.draw(View.java:19935)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
        at android.view.View.draw(View.java:20210)
        at android.view.View.updateDisplayListIfDirty(View.java:19082)
        at android.view.View.draw(View.java:19935)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
        at android.view.View.updateDisplayListIfDirty(View.java:19073)
        at android.view.View.draw(View.java:19935)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
        at android.view.View.updateDisplayListIfDirty(View.java:19073)
        at android.view.View.draw(View.java:19935)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
        at android.view.View.updateDisplayListIfDirty(View.java:19073)
        at android.view.View.draw(View.java:19935)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
        at android.view.View.updateDisplayListIfDirty(View.java:19073)
        at android.view.View.draw(View.java:19935)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4333)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4112)
        at android.view.View.draw(View.java:20210)
        at com.android.internal.policy.DecorView.draw(DecorView.java:780)
        at android.view.View.updateDisplayListIfDirty(View.java:19082)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:801)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:3311)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3115)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2484)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1460)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
        at android.view.Choreographer.doCallbacks(Choreographer.java:761)
        at android.view.Choreographer.doFrame(Choreographer.java:696)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.ClassNotFoundException: Didn't find class "kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "/data/app/com.example.contest-BRT3db-F44Q04qET2fDloQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.contest-BRT3db-F44Q04qET2fDloQ==/lib/x86, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
2019-11-29 16:11:08.344 23671-23671/com.example.contest E/AndroidRuntime:     at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        	... 58 more

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.

Use drawable

I wonder if it is possible to use drawables as confetti. It would be great if we could pass pictures and drawables to the library.

ANR: Input dispatching timed out

Hi, having problem some reports with this:

Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 10. Wait queue head age: 7251.3ms.)

"main" tid=1 Runnable
"main" prio=5 tid=1 Runnable
| group="main" sCount=0 dsCount=0 flags=0 obj=0x73664710 self=0x7e7ecc2a00
| sysTid=24824 nice=-10 cgrp=default sched=0/0 handle=0x7e836b99b0
| state=R schedstat=( 157132874466 40567429970 321874 ) utm=11754 stm=3959 core=5 HZ=100
| stack=0x7ff4178000-0x7ff417a000 stackSize=8MB
| held mutexes= "mutator lock"(shared held)
at java.util.Locale.equals (Locale.java)
at android.os.LocaleList.getDefault (LocaleList.java:483)

  • locked <0x0fcf420e> (a java.lang.Object)
    at android.os.LocaleList.getAdjustedDefault (LocaleList.java:511)
    at android.graphics.Paint. (Paint.java:489)
    at android.graphics.Paint. (Paint.java:471)
    at nl.dionsegijn.konfetti.Confetti. (Confetti.java)
    at nl.dionsegijn.konfetti.Confetti. (Confetti.java)
    at nl.dionsegijn.konfetti.emitters.RenderSystem.addConfetti (RenderSystem.java)
    at nl.dionsegijn.konfetti.emitters.RenderSystem.access$addConfetti (RenderSystem.java)
    or .isDoneEmitting (RenderSystem.java)
    or .render (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.build (StreamEmitter.java)
    or .build$default (StreamEmitter.java)
    or .createConfetti (StreamEmitter.java)
    at nl.dionsegijn.konfetti.emitters.RenderSystem.access$addConfetti (RenderSystem.java)
    or .isDoneEmitting (RenderSystem.java)
    or .render (RenderSystem.java)
    at nl.dionsegijn.konfetti.KonfettiView.onDraw (KonfettiView.java)
    at android.view.View.draw (View.java:19123)
    at android.view.View.updateDisplayListIfDirty (View.java:18073)
    at android.view.View.draw (View.java:18851)
    at android.view.ViewGroup.drawChild (ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4000)
    at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw (ConstraintLayout.java)
    at android.view.View.draw (View.java:19126)
    at android.view.View.updateDisplayListIfDirty (View.java:18073)
    at android.view.View.draw (View.java:18851)
    at android.view.ViewGroup.drawChild (ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4000)
    at android.view.View.draw (View.java:19126)
    at android.view.View.updateDisplayListIfDirty (View.java:18073)
    at android.view.View.draw (View.java:18851)
    at android.view.ViewGroup.drawChild (ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4000)
    at android.view.View.draw (View.java:19126)
    at android.view.View.updateDisplayListIfDirty (View.java:18073)
    at android.view.View.draw (View.java:18851)
    at android.view.ViewGroup.drawChild (ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4000)
    at android.view.View.draw (View.java:19126)
    at android.view.View.updateDisplayListIfDirty (View.java:18073)
    at android.view.View.draw (View.java:18851)
    at android.view.ViewGroup.drawChild (ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4000)
    at android.view.View.draw (View.java:19126)
    at android.view.View.updateDisplayListIfDirty (View.java:18073)
    at android.view.View.draw (View.java:18851)
    at android.view.ViewGroup.drawChild (ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4000)
    at android.view.View.draw (View.java:19126)
    at android.view.View.updateDisplayListIfDirty (View.java:18073)
    at android.view.View.draw (View.java:18851)
    at android.view.ViewGroup.drawChild (ViewGroup.java:4214)
    at android.view.ViewGroup.dispatchDraw (ViewGroup.java:4000)
    at android.view.View.draw (View.java:19126)
    at com.android.internal.policy.DecorView.draw (DecorView.java:795)
    at android.view.View.updateDisplayListIfDirty (View.java:18073)
    at android.view.ThreadedRenderer.updateViewTreeDisplayList (ThreadedRenderer.java:643)
    at android.view.ThreadedRenderer.updateRootDisplayList (ThreadedRenderer.java:649)
    at android.view.ThreadedRenderer.draw (ThreadedRenderer.java:757)
    at android.view.ViewRootImpl.draw (ViewRootImpl.java:2994)
    at android.view.ViewRootImpl.performDraw (ViewRootImpl.java:2798)
    at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2351)
    at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1390)
    at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:6754)
    at android.view.Choreographer$CallbackRecord.run (Choreographer.java:911)
    at android.view.Choreographer.doCallbacks (Choreographer.java:723)
    at android.view.Choreographer.doFrame (Choreographer.java:658)
    at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:897)
    at android.os.Handler.handleCallback (Handler.java:789)
    at android.os.Handler.dispatchMessage (Handler.java:98)
    at android.os.Looper.loop (Looper.java:251)
    at android.app.ActivityThread.main (ActivityThread.java:6563)
    at java.lang.reflect.Method.invoke (Method.java)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:767)

How to show konfetti with dialog?

I would like to show this konfetti animation when a dialog pop's up. Now if i make the dialog full screen and add the konfetti to it, then when i add animation to the dialog , when the dialog is appearing the konfetti animation dsn't look good.

Is there any way possible?

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!

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.

RunTimeException DexArchiveMergerException: Unable to merge dex

I'm unable to use this library as it keeps on failing compilation with

Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'. > java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex

I've tried enabling multiDex, rebuild project, deleting all my build folders, invalidate caches..nothing works.
I am using Android Studio 3.0.1, Gradle 4.1

Confusing API: stream

The overloads of stream are really confusing due to the almost same signature and really different outcome.

Instead I suggest deprecating both and instead adding streamMaxParticles and streamFor(particlesPerSecond: Int, emittingTime: Long, timeUnit : TimeUnit)

to make the api more clear to the user.

    /**
     * Emit a certain amount of particles per second for the duration of specified time
     * calling this function will start the system rendering the confetti
     * [particlesPerSecond] amount of particles created per second
     * [emittingTime] max amount of time to emit in milliseconds
     */
    fun stream(particlesPerSecond: Int, emittingTime: Long) {
        val stream = StreamEmitter().build(particlesPerSecond = particlesPerSecond, emittingTime = emittingTime)
        startRenderSystem(stream)
    }

    /**
     * Emit a certain amount of particles per second until [maxParticles] are created
     * calling this function will start the system rendering the confetti
     * [particlesPerSecond] amount of particles created per second
     * [maxParticles] max amount of particles to emit
     */
    fun stream(particlesPerSecond: Int, maxParticles: Int) {
        val stream = StreamEmitter().build(particlesPerSecond = particlesPerSecond, maxParticles = maxParticles)
        startRenderSystem(stream)
    }

Bug

I'm trying to implement Konfetti library using java code, but I get this error:
It seems something related to Kotlin while I'm using Java,

2019-03-09 18:10:46.023 14058-14058/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.particle3, PID: 14058
java.lang.NoClassDefFoundError: Failed resolution of: Lkotlin/jvm/internal/Intrinsics;
at nl.dionsegijn.konfetti.KonfettiView.onDraw(Unknown Source:2)
at android.view.View.draw(View.java:19226)
at android.view.View.updateDisplayListIfDirty(View.java:18176)
at android.view.View.draw(View.java:18954)
at android.view.ViewGroup.drawChild(ViewGroup.java:4240)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4024)
at android.view.View.updateDisplayListIfDirty(View.java:18167)
at android.view.View.draw(View.java:18954)
at android.view.ViewGroup.drawChild(ViewGroup.java:4240)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4024)
at android.view.View.updateDisplayListIfDirty(View.java:18167)
at android.view.View.draw(View.java:18954)
at android.view.ViewGroup.drawChild(ViewGroup.java:4240)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4024)
at android.view.View.updateDisplayListIfDirty(View.java:18167)
at android.view.View.draw(View.java:18954)
at android.view.ViewGroup.drawChild(ViewGroup.java:4240)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4024)
at android.view.View.updateDisplayListIfDirty(View.java:18167)
at android.view.View.draw(View.java:18954)
at android.view.ViewGroup.drawChild(ViewGroup.java:4240)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4024)
at android.view.View.updateDisplayListIfDirty(View.java:18167)
at android.view.View.draw(View.java:18954)
at android.view.ViewGroup.drawChild(ViewGroup.java:4240)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4024)
at android.view.View.draw(View.java:19229)
at com.android.internal.policy.DecorView.draw(DecorView.java:791)
at android.view.View.updateDisplayListIfDirty(View.java:18176)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:685)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:691)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:799)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3051)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2846)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2399)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1432)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6861)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1026)
at android.view.Choreographer.doCallbacks(Choreographer.java:838)
at android.view.Choreographer.doFrame(Choreographer.java:769)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1012)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:171)
at android.app.ActivityThread.main(ActivityThread.java:6651)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
2019-03-09 18:10:46.026 14058-14058/? E/AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/base.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_dependencies_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_resources_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_0_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_1_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_2_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_3_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_4_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_5_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_6_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_7_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_8_apk.apk", zip file "/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/lib/arm64, /system/lib64, /system/vendor/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 48 more
Suppressed: java.io.IOException: No original dex files found for dex location /data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_resources_apk.apk
at dalvik.system.DexFile.openDexFileNative(Native Method)
at dalvik.system.DexFile.openDexFile(DexFile.java:353)
at dalvik.system.DexFile.(DexFile.java:100)
at dalvik.system.DexFile.(DexFile.java:74)
at dalvik.system.DexPathList.loadDexFile(DexPathList.java:374)
at dalvik.system.DexPathList.makeDexElements(DexPathList.java:337)
at dalvik.system.DexPathList.(DexPathList.java:157)
at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:65)
at dalvik.system.PathClassLoader.(PathClassLoader.java:64)
at com.android.internal.os.ClassLoaderFactory.createClassLoader(ClassLoaderFactory.java:73)
at com.android.internal.os.ClassLoaderFactory.createClassLoader(ClassLoaderFactory.java:88)
at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:69)
at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:35)
at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:695)
at android.app.LoadedApk.getClassLoader(LoadedApk.java:729)
at android.app.LoadedApk.getResources(LoadedApk.java:956)
at android.app.ContextImpl.createAppContext(ContextImpl.java:2282)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5722)
at android.app.ActivityThread.-wrap1(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1685)
at android.os.Handler.dispatchMessage(Handler.java:106)
... 5 more
Suppressed: java.io.IOException: No original dex files found for dex location /data/app/com.example.particle3-PoJzt4mGNj3x2DeFOgkRwg==/split_lib_slice_5_apk.apk
at dalvik.system.DexFile.openDexFileNative(Native Method)
at dalvik.system.DexFile.openDexFile(DexFile.java:353)
at dalvik.system.DexFile.(DexFile.java:100)
at dalvik.system.DexFile.(DexFile.java:74)
at dalvik.system.DexPathList.loadDexFile(DexPathList.java:374)
at dalvik.system.DexPathList.makeDexElements(DexPathList.java:337)
at dalvik.system.DexPathList.(DexPathList.java:157)
at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:65)
at dalvik.system.PathClassLoader.(PathClassLoader.java:64)
2019-03-09 18:10:46.027 14058-14058/? E/AndroidRuntime: at com.android.internal.os.ClassLoaderFactory.createClassLoader(ClassLoaderFactory.java:73)
at com.android.internal.os.ClassLoaderFactory.createClassLoader(ClassLoaderFactory.java:88)
at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:69)
at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:35)
at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:695)
at android.app.LoadedApk.getClassLoader(LoadedApk.java:729)
at android.app.LoadedApk.getResources(LoadedApk.java:956)
at android.app.ContextImpl.createAppContext(ContextImpl.java:2282)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5722)
at android.app.ActivityThread.-wrap1(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1685)
at android.os.Handler.dispatchMessage(Handler.java:106)
... 5 more

Typos in docs

new Size(12, 5) instead of Size(12)
viewKonfetti.getWidth() instead of viewKonfetti.width

Add dependency implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.41'

Getting No Class Found Error With 1.1.2

Hi,
I unable to play animation after updating gradle 1.1.0 to 1.1.2 .

Note : I'm using java

Error Log :

Process: com.test.test.dev, PID: 26786 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) at com.test.test.ui.alert.InfoAlertFragment.onPlayAnimation(InfoAlertFragment.java:148) at com.test.test.ui.alert.InfoAlertFragment.onViewCreated(InfoAlertFragment.java:118) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1439) at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827) at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797) at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596) at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383) at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703) at android.os.Handler.handleCallback(Handler.java:746) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5443) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) Caused by: java.lang.ClassNotFoundException: Didn't find class "kotlin.jvm.internal.Intrinsics" on path: DexPathList[[zip file "/data/app/com.test.test.dev-1/base.apk", zip file "/data/app/com.test.test.dev-1/split_lib_dependencies_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_0_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_1_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_2_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_3_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_4_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_5_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_6_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_7_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_8_apk.apk", zip file "/data/app/com.test.test.dev-1/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.test.test.dev-1/lib/arm, /data/app/com.test.test.dev-1/base.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_dependencies_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_0_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_1_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_2_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_3_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_4_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_5_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_6_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_7_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_8_apk.apk!/lib/armeabi-v7a, /data/app/com.test.test.dev-1/split_lib_slice_9_apk.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:511) at java.lang.ClassLoader.loadClass(ClassLoader.java:469) at nl.dionsegijn.konfetti.ParticleSystem.<init>(ParticleSystem.kt)  at nl.dionsegijn.konfetti.KonfettiView.build(KonfettiView.kt:39)  at com.test.test.ui.alert.InfoAlertFragment.onPlayAnimation(InfoAlertFragment.java:148)  at com.test.test.ui.alert.InfoAlertFragment.onViewCreated(InfoAlertFragment.java:118)  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1439)  at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)  at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)  at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)  at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)  at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)  at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:703)  at android.os.Handler.handleCallback(Handler.java:746)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5443)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)  Suppressed: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics at java.lang.Class.classForName

Infinite Particles

It would be useful to have an option to infinitely emit particles.

Something like this:
KonfettiView.build().streamFor(xxx, INFINITE)

Documentation for what direction means

It would be great if you could add for the direction, what exactly it means.

Is it radian? Is it degrees? Let that be reflected in the parameter names. minDirectionDegrees.
Describe what 0 degrees mean. Is it top? Is it bottom? Is it right?

里面一些参数不能用

这两个参数不能用,
size和width 这两个参数爆红,不能正常使用
.addSizes(Size(12))
.setPosition(-50f, viewKonfetti.width + 50f, -50f, -50f)

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!

Confetti size system

Problem

  • The current system to adjust and add sizes to confetti library is not ideal. It only lets you choose between three sizes which are relatively large on small mdpi screens because they are defined in pixels and were tested on large phone screens.
  • konfetti.models.Size class has a confusing name since Size is also already used in the Android SDK

Solution

Currently thinking of rewriting this part of the system to allow the users to add any particle size to the system instead of having to rely on Size.SMALL, Size.MEDIUM and Size.LARGE.

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);
      }
});

Konfetti doesn't work onAnimationEnd

KonfettiView doesn't work onAnimationEnd in an class that implements Animation.AnimationListener. Still, it doesn't give any kind of error.

` public void onAnimationEnd(Animation animation) {
Toast toast = Toast.makeText("test");
toast.show();

    konfettiView.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, konfettiView.getWidth() + 50f, -50f, -50f)
            .streamFor(300, 5000L);


}`

Any ideas?

Size : Rounding errors and property naming

For size the property size should be called sizeInDp.

val Size.sizeDp: Int should be named sizeInPx as it's actually the pixels. It should not be casted toInt() as it's inaccurate. As it's only used in Confetti as private var width = size.sizeDp.toFloat() it should just be left as a float.

Also mass tells me quite nothing about what it does. What does negative mass mean? What does positive mass mean?
What does mass 0 mean? (it actually crashes the app as in Vector you are dividing by that value). So better validate the argument:

  data class Size(val sizeInDp: Int, val mass: Float = 5f) {

    internal val sizeInPx: Float
      get() = sizeInDp * Resources.getSystem().displayMetrics.density

    init {
      require(mass != 0F) { "mass=$mass must be != 0" }
    }
  }

The kofetti does not display correctly when it is called in fragment OnViewCreated

in my fragment calling the startConfetti method in onCreateView results in the following

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        startConfetti()
    }

screenshot_20190308-145239

however if i delay the startConfetti method call the animation works as expected

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Timer().schedule(object : TimerTask() {
            override fun run() {
               startConfetti()
            }
        }, 100L)
    }

screenshot_20190308-145249

here is the startConfettiMethod

private fun startConfetti() {
        viewKonfetti.build()
            .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA)
            .setDirection(0.0, 359.0)
            .setSpeed(4f, 7f)
            .setFadeOutEnabled(true)
            .setTimeToLive(2000L)
            .addShapes(Shape.RECT, Shape.CIRCLE)
            .addSizes(Size(12), Size(16, 6f))
            .setPosition(-50f, viewKonfetti.width + 50f, -50f, -50f)
            .streamFor(300, 5000L)
    }

Issue while running with kotlin 1.3.11 and nl.dionsegijn:konfetti:1.1.2

Caused by: java.lang.ClassNotFoundException: Didn't find class "nl.dionsegijn.konfetti.KonfettiView" on path: DexPathList[[zip file "/data/app/com.zilingo.users.delta.debug-2/base.apk"],nativeLibraryDirectories=[/data/app/com.zilingo.users.delta.debug-2/lib/arm64, /data/app/com.zilingo.users.delta.debug-2/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]]

enhancement:Please provide demo app source code

It would be great if we have source code of the demo app.Because I observe completely different picture when I paste params from demo app into my code.
Also documentation would be much appreciated looks like setSpeed method behaves not the way I expect.

License

Hi, this isn't an issue, I thought you made a really cool thing that I'd like to include in my app that at some point I'll be deploying to Google Play Store, but I didn't really understand what the license part meant and just wanted to seek out clarification - is it ok if I include your api? How do I cite and acknowledge your work? Please let me know, thanks!

New shapes

I am thinking it would be nice to have more shapes :) Rectangles (not just squares), stars and long rectangles maybe (or serpentine streamers)

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

getWidth Konfetti

I am making a simple game application, I want when the player finishes the game confetti will appear, I have applied it but the width of the confetti does not fill the screen. How do I get the width of the screen that matches the match for confetti?

konfettiView.build ()
                .addColors (Color.YELLOW, Color.GREEN, Color.MAGENTA, Color.RED, Color.GREEN)
                .setDirection (0.0, 359.0)
                .setSpeed ​​(1f, 5f)
                .setFadeOutEnabled (true)
                .setTimeToLive (3000L)
                .addShapes (Shape.RECT, Shape.CIRCLE)
                .addSizes (Size (10), Size (12, 6f))
                .setPosition (-50f, konfettiView.width + 50f, -50f, -50f)
                .streamFor (300, 5000L)

Add callbacks to KonfettiView to get notified about confetti system changes

Problem
Currently there are no callbacks in the library available to know if the state of the confetti systems have changed.

Solution
Add the following callbacks:

  • Get notified if a particle system is done and how many are active
    This way you can figure out yourself if all systems are done or if a single one has stopped but another one is still active.

Any suggestions for more callbacks are welcome in the comments

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.