Coder Social home page Coder Social logo

jinatonic / confetti Goto Github PK

View Code? Open in Web Editor NEW
1.3K 1.3K 151.0 2.41 MB

An Android particle system library for displaying confetti!

Home Page: https://medium.com/@jinatonic/its-parfetti-time-f40634472608

License: Apache License 2.0

Java 100.00%
android android-animation android-ui particle-system

confetti's People

Contributors

burntcookie90 avatar jinatonic avatar magneticflux- 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

confetti's Issues

A Tip of lower CPU usage

Hi there,

I read the source code and found that confettiView would be invalidated every millisecond in ValueAnimator.AnimatorUpdateListener。I used AndroidStudioProfileTool to check the cpu usage, about 6-7%。Then I changed frequency, redrawing view in every 30ms, then cpu usage would be 3-4%。And according to the Internet, Our eyes can accept this fraquence,no stumbling feeling.

Do you think it is a good idea? Looking forward to your reply @jinatonic

// ----------------------------
My change is:

// ConfettiManager.java
private void startNewAnimation() {
        ……
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            private long lastUpdateTime = -1;
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                final long elapsedTime = valueAnimator.getCurrentPlayTime();
                if(lastUpdateTime < 0) {
                    lastUpdateTime = elapsedTime;
                } else if(lastUpdateTime + 30 > elapsedTime) {
                    return;
                }
                 lastUpdateTime = elapsedTime;
               ……
            }
        });
        animator.start();
    }

Add multiple Images in BitmapConfetto

Can we add multiple bitmap in BitmapConfetto .Basically i want to add mutiple image in ShimmeringActivity without changing color

@Override public Confetto generateConfetto(Random random) { return new BitmapConfetto(confettoBitmaps); }

Simple Customizations

Hey,

First, thanks for the library. I recently had to do a lot of particle systems on Android and found very little options out there and yours is one of the most flexible ones I found.

I'm trying to create a bunch of simple customizations for an app I'm working on and I'm noticing that it is a bit limited to customize things without having to write my one ConfettiManager. Maybe I'm just missing something so let me know if I am.

For example, I want to be able to customize the initial position and direction of each confetto.

  • While technically I can do that in the listener, I want to still follow the rules set in the ConfettiManager about velocity for example. There are no getters for these though. Not in ConfettiManager or in Confetto as they are private. Why not have getters for these values on the Confetto?
    Edit: I just realized you already did this one in your current last commit on master but it is just not in the latest tagged version I added via Gradle.

  • Another option was to subclass ConfettiManager and override configureConfetto but unfortunately it is also set to private and not protected so I would have to override a whole lot of functions and variables that I don't really need. Is there a specific reason that function was not set to be overridable? If not, can you please set it to protected.

Show confetti for 5 seconds only

Hi,

How can I achieve to show confetti for 5 seconds and It should reach till the end of the screen within 5 sec timeframe.

I am using below code but this shows confetti on screen for 13 seconds (It takes 13 seconds to clear confetti screens from the screen)

   getConfettiManager(context, container).setNumInitialCount(0)
            .setEmissionDuration(4000)
            .setEmissionRate(15)
            .animate();

Am I doing anything wrong?

I appreciate your help.

Confetti direction

As we know, the confetti direction is from middle to the edge of the container. Is there any function make it reversed, from edge of container to center of container?

every item click

Hello, now I have a question, if I do a single picture click or single snowflake click event in the demo. You can't make the next step of operation such as animation

Confetti size option?

The raining confetti does exactly what I need except the individual squares are too small. I'm not seeing an option to set their scale (or a random scale ideally). Thanks for the cool lib!

Cant change X and Y values of confettiManager after initialization.

Hello, Thank you for this wonderful library.

I'm having a little trouble understanding if I'm doing things the right way. I created my own custom confetto using ConfettoGenerator and then initialized my ConfettiManager like this:

confettoGenerator = new ConfettoGenerator() {
            @Override
            public Confetto generateConfetto(Random random) {
                return new Particles(Assets.particle_blue);
            }
        };

confettiSource = new ConfettiSource(sW,sH/2);
        mConfetti = new ConfettiManager(getContext(), confettoGenerator, confettiSource, (ViewGroup) this.getParent().getParent())
                .setEmissionDuration(700)
                .setVelocityX(-100)
                .setTTL(700);

Now I'm able to draw my animation in my onDraw() method by simply doing confettiManager.animate() but what if I want to change the X and Y values during animation. For example, moving the animation as the user moves their finger on screen? Am I missing something since clearly I should not have to create a new confettiManager each time I wanna move the same animation and I must avoid object allocation at all costs in my onDraw() method.

Looking forward to your reply, thanks once again.

How to disable negative speed?

After falling to down my confetti returns to the top, because speed becomes negative

int height = container.getHeight();
        int speed = height/4;
        int acceleration = -(height/4)/8;
        final ConfettiSource confettiSource = new ConfettiSource(-container.getWidth()/4, 0,container.getWidth()/2, 0);
        confettiManager = new ConfettiManager(this, myConfettoGenerator, confettiSource, container)
                .setNumInitialCount(2)
              .setEmissionDuration(ConfettiManager.INFINITE_DURATION)
                .setInitialRotation(180, 180)
                .setEmissionRate(4f)
                .setVelocityY(speed)
                .setAccelerationY(acceleration)
                .setRotationalVelocity(30, 60)
                .animate();

Memory leak problems

Hi, i am using the library to display some confetti like this:

CommonConfetti.explosion(container, centerX, centerY, getConfettiColor(context, score))
.stream(1000)
.setBound(new Rect(0, 0, container.getWidth(), container.getHeight()))
.setNumInitialCount(1)
.setEmissionRate(1)
.setEmissionDuration(1000)
.animate();

And i had some crashes after about a minute because of memory overflow. So i checked the Android Studio monitors and the memory was constantly raising and raising until it crashes.

Is there any tip or API to release memory that i have not seen in the wiki??
Thanks

Which license do you use?

This library works great and I want to include it in an app for the play store.

I would like to give you credit for the library.

Could you update the project with a license?

How to display Confetti in background?

I wonder if it is possible to display Confetti on the background, i.e. behind any Buttons or TextViews.
I've already tried to set the elevation for the other layout components as 3dp, but the confettos are still being displayed in front of Buttons and TextViews.
I think it would be great to have an option to set confetti elevation or something like that.

Oh, and thanks for the great lib!

Confetti does not work with Dialog/DialogFragment.

Hi @jinatonic
I have used the rootview for setting the container for confetti as shown :

CommonConfetti.rainingConfetti(
(ViewGroup) dialog.getWindow().getDecorView().getRootView(),new int[]{
Color.WHITE,
ContextCompat.getColor(context, R.color.sky_blue),
Color.YELLOW,
Color.GREEN,
ContextCompat.getColor(context, R.color.red_pink),
ContextCompat.getColor(context, R.color.teal),
ContextCompat.getColor(context, R.color.teal_dark),
ContextCompat.getColor(context, R.color.dark_orange)})
.infinite();
)

I don't see confetti, nor i see an exception.

does not work on honor/huawei

config:
new ConfettiManager(this, this, source, container) .setEmissionDuration(ConfettiManager.INFINITE_DURATION) .setTTL(CONFETTI_LIFE_DURATION_MS) .setVelocityX(0, velocitySlow) .setVelocityY(velocityNormal, velocitySlow) .setRotationalVelocity(ROTATIONAL_VELOCITY, ROTATIONAL_DEVIATION) .setEmissionRate(CONFETTI_PER_SECOND);
works on samsung/asus/etc. but shows nothing on honor 8x (android 9, JSN-L22) and huawei p20 pro (android 9, CLT-L29).

I've got similar issue with Huawei devices - there is not working rotation animation.
For this case I have to use such workaround:
DeviceHelper.isHuawei() ? ObjectAnimator.ofFloat(guestAvatarImage, View.ALPHA, 1, 0) : ObjectAnimator.ofFloat(guestAvatarImage, View.ROTATION_Y, 0, 90);

public static boolean isHuawei() { return "HUAWEI".equals(Build.MANUFACTURER.toUpperCase()); }

What does fisrtTime and secondTime mean in computeBound()?

snippet:

( if (targetTime == null || targetTime < 0) {
//                 https://www.wolframalpha.com/input/
//                 ?i=solve+for+t+in+(d+%3D+x+%2B+v+*+t+%2B+0.5+*+a+*+t+*+t)

                final double tmp = Math.sqrt(
                        2 * acceleration * bound - 2 * acceleration * initialPos
                                + velocity * velocity);

                final double firstTime = (-tmp - velocity) / acceleration;
                if (firstTime > 0) {
                    return (long) firstTime;
                }

                final double secondTime = (tmp - velocity) / acceleration;
                if (secondTime > 0) {
                    return (long) secondTime;
                }

                return Long.MAX_VALUE;
            })

Hi,Confetti will Accelerate until reaching bound because it doest have targetTime.So tmp is the time of the reaching Bound.Why you have to calculate firstTime and secondTime to determine the reaching bound time?

Throwing ConcurrentModificationException when trying to terminate the ConfettiManager collection

In AbstractActivity the has used to terminate the ConfettiManager collection is throwing ConcurrentModificationException .

Bug Code:

 for (ConfettiManager confettiManager : activeConfettiManagers) {
                confettiManager.terminate();
    }

I tried to change the way for terminating the collection in below code, but still its throwing the same exception.

Iterator<ConfettiManager> iter = allConfettiManagers.iterator();		
while(iter.hasNext()) {					
ConfettiManager blah = iter.next();				  
if(blah != null) {					
         blah.terminate(); // Removes the 'current' item				
  }				
} 

Full Stack Trace:

STACK_TRACE=java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
at com.openskylabs.skymo.uiscreens.ScrollerActivity.endConfitti(ScrollerActivity.java:689)
at com.openskylabs.skymo.uiscreens.OSLCardHomeScreen.handleCardsonSwipe(OSLCardHomeScreen.java:860)
at com.openskylabs.skymo.uiscreens.OSLCardHomeScreen.access$11(OSLCardHomeScreen.java:824)
at com.openskylabs.skymo.uiscreens.OSLCardHomeScreen$8.onDislike(OSLCardHomeScreen.java:774)
at com.openskylabs.skymo.cardswipe.animation.CardContainer$GestureListener.onFling(CardContainer.java:472)
at android.view.GestureDetector.onTouchEvent(GestureDetector.java:600)
at com.openskylabs.skymo.cardswipe.animation.CardContainer.onTouchEvent(CardContainer.java:255)
at android.view.View.dispatchTouchEvent(View.java:7337)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2257)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1954)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2263)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1968)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1979)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1429)
at android.app.Activity.dispatchTouchEvent(Activity.java:2436)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:60)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1927)
at android.view.View.dispatchPointerEvent(View.java:7528)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3655)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3580)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4850)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4810)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4966)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:134)
at android.os.Looper.loop(Looper.java:151)
at android.app.ActivityThread.main(ActivityThread.java:5400)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
at dalvik.system.NativeStart.main(Native Method)

Incorrect copyright

Not sure if it is an issue, but it looks like the copyright of this library is attributed to Robinhood. Maybe this was a copy paste sort of error? 😛

unable to show confetti on click of button

`int[] confettiColors = new int[]{R.color.red, R.color.blue, R.color.green, R.color.black, R.color.orange, R.color.darkergray};

ConfettiSource confettiSource = new ConfettiSource(linearLayout.getWidth(),
linearLayout.getHeight());

CommonConfetti.rainingConfetti(linearLayout, confettiSource, confettiColors ).infinite();`

i have done this code ....is that sufficient for showing confetti?

explosion() is not working

Hey
I am trying to use the library and have called the explosion() -

CommonConfetti.explosion(container, centerX, centerY, new int[] {Color.RED}).oneShot();

its not showing whereas the raining-effects are working fine. Could you please have a look at the issue or anything i am missing in the explosion()

Scale [from, to] functionallity

Hi,

maybe you could implement setScaleX(int from, int to), setScaleY(int from, int to) in ConfettiManager? So for example, the bitmap would scale by the time elapsed.

At the moment I'm overriding Confetti class, accessing private "millisToReachBound" field with reflection and then preScaling matrix by calculating how much time have elapsed.

Custom Confetti with Explosion

I was not able to integrate a confetti generatot with custom bitmap for Explosion Effect ?

Is there any specific method i should use for Explosion type to change the Confetti drawable ?

Why confetti recreates on top after falling down to bottom?

I created list of BitmapConfetto with 200 different , not the same images. And I need to fall all of the to bottom from the top. But when first confetti FadeOut at the bottom, then it recreates on the top again.

  int height = container.getHeight();
        int speed = height/4;
        int acceleration = -(height/4)/8;
        final ConfettiSource confettiSource = new ConfettiSource(-container.getWidth()/4, 0,container.getWidth()/2, 0);
        confettiManager = new ConfettiManager(this, myConfettoGenerator, confettiSource, container)
                .setNumInitialCount(2)
                .setTTL(6000)
                .enableFadeOut(Utils.getDefaultAlphaInterpolator())
                .setEmissionDuration(ConfettiManager.INFINITE_DURATION)
                .setInitialRotation(180, 180)
                .setEmissionRate(4f)
                .setVelocityY(speed)
                .setAccelerationY(acceleration)
                .setRotationalVelocity(30, 60)
                .animate();

Library proguard rules

Hi there,

It would be extremely helpful if you could the the appropriate library proguard rules.

On Terminate crashing

'void android.view.ViewParent.requestLayout()' on a null object reference

In your sample app ShimmeringActivity added on more button stop and on click listener
getConfettiManager.terminate() crashing.

My use case will be I have to show infinite shower animation but on click on something dismiss the animation. Using terminate leads to crash copy pasting error log

java.lang.NullPointerException: Attempt to invoke interface method 'void android.view.ViewParent.requestLayout()' on a null object reference at com.github.jinatonic.confetti.ConfettiView.terminate(ConfettiView.java:86) at com.github.jinatonic.confetti.ConfettiManager.terminate(ConfettiManager.java:481) at com.github.jinatonic.confetti.ConfettiManager$2.onAnimationUpdate(ConfettiManager.java:534) at android.animation.ValueAnimator.animateValue(ValueAnimator.java:1463) at android.animation.ValueAnimator.animationFrame(ValueAnimator.java:1384) at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1427) at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:759) at android.animation.ValueAnimator$AnimationHandler$1.run(ValueAnimator.java:801) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) at android.view.Choreographer.doCallbacks(Choreographer.java:670) at android.view.Choreographer.doFrame(Choreographer.java:603) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:152) at android.app.ActivityThread.main(ActivityThread.java:5497) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Add a limit option to the number of confetti on screen

You can use some of the Guava caches here to optimize your confetto recycling and limit the number of active confetti on-screen.
This should be completely configurable, since some devices are more powerful than others. The animator could keep track of the last frame-time and also dynamically adjust the value.

ConfettiManager leaking

Hi,

I'm using LeakCanary and getting these leaks really often.
LeakCanay stacktrace

I'm not 100% sure, but I think that in ConfettiManager terminate method you should call animator.removeAllUpdateListeners.

Is there a limitation on the size of the drawable?

Hey! I am using a custom drawable, 2 different drawables in this case.

One that works is 128x128 which shows up just fine.

The other one being 10x120 which doesnt show, instead it picks one drawable from the library, that looks like a rounded square.

Any clue why I am seeing this?

Using Confetti with DialogFragment

Hei guys, can you explain me if I could use it with a DialogFragment.
I have tried but I am unable to display the confettis. I think it is because of the container I have to pass to the ConfetiiManager, because the widht/height I receive from it is 0.
Thank you!

1.1.1 release?

Hi,
I really like this library and was wondering if the 1.1.1 release was going to happen soon as I could really do with the animation listener.
Thanks

Fixed the crash on the terminate method

Hey,

I fixed the crash on the terminate method:

/**
   * Terminate the currently running animation if there is any.
   */
  public void terminate() {
      if (animator != null) {
          animator.cancel();
      }

      if (confettiView != null && confettiView.getParent() != null)
          confettiView.terminate();

      if (animationListener != null) {
          animationListener.onAnimationEnd(this);
      }
  }

The problem is when you initialize an ConfettiManager with confettiView null the terminate method will crash. This is easily avoidable by adding this extra check. I've tried making an PR for it but i can't seem to push on a separate branch getting error 403.

Btw this crash happens in Kotlin because you van initialize the ConfettiManager as Confettimanager(ConfettoGenerator,ConfettiSource,null,null) if you want.

Collect feature

Can i somehow collect all dropped images at the bottom of the screen, something like tetris?

The number of drops

Recommendation: I hope to be able to join the set to control the number of ways to drop, rather than the current second as a unit.
qq 20170112104250
this.emissionRate = emissionRate / 1000f;
1000f write fixed is not good.

Provide x- and y-velocities in drawInternal() Confetto method

These are not calculated because you already use twice-integrated equations of motion based on the current time, acceleration, and initial conditions, but they could be similar fields to currentX and currentY. I'd be happy to submit a PR implementing the feature!

As a side note, the comments in the computeDistance function talk about linear acceleration, when you are clearly dealing with constant acceleration. It would be possible to implement linear acceleration, but I don't see any use cases for it.

As a side note to the side note, If you were to go down that path, you could use generalized mathematical functions from Apache Math to take derivatives, etc.

Unable to show Confetti - No Crash No Confetti.

I am using it by trying the following code:

private CommonConfetti getCommonConfetti() {
final int size = getResources().getDimensionPixelSize(R.dimen.default_confetti_size);
final ConfettiSource confettiSource = new ConfettiSource(-size, -size);

    final Resources res = getResources();
    int goldDark = res.getColor(R.color.zotocolor);
    int goldMed = res.getColor(R.color.zotocolortrans);
    int gold = res.getColor(R.color.offer_blue);
    int goldLight = res.getColor(R.color.offer_validated_green);
    int[] colors = new int[]{goldDark, goldMed, gold, goldLight};

    final CommonConfetti commonConfetti =
            CommonConfetti.rainingConfetti(parentContainer, confettiSource, colors);

    final int velocitySlow = res.getDimensionPixelOffset(R.dimen.default_velocity_slow);
    final int velocityNormal = res.getDimensionPixelOffset(R.dimen.default_velocity_normal);
    final int velocityFast = res.getDimensionPixelOffset(R.dimen.default_velocity_fast);

    // Further configure it
    commonConfetti.getConfettiManager()
            .setVelocityX(velocityFast, velocityNormal)
            .setAccelerationX(-velocityNormal, velocitySlow)
            .setTargetVelocityX(0, velocitySlow / 2)
            .setVelocityY(velocityNormal, velocitySlow);

    return commonConfetti;
}

And calling the confetti like this:
getCommonConfetti().infinite().animate();

And parentContainer is a FrameLayout(parent) in my xml.

But code executes without any confetti on my screen. Why so ? Am I doing something wrong ?

Can't be displayed above dialog

Steps:

  1. Show Fragment Dialog
  2. Animate Confetti

Actual:
Confetti displayed below dialog since it's attached to decor view

Expected:
It should be customisable if effect should be above or below dialog

Canvas: trying to use a recycled bitmap

Hi,

I'm extending Confetto class to make my custom animation. This is all what I have:

@Override
protected void drawInternal(Canvas canvas, Matrix matrix, Paint paint, float x, float y,
                                float rotation, float percentAnimated) {

        float scaleX = ((rotation % 720) - 180) / 180.0f;
        if (scaleX > 1f) {
            scaleX = 1f - (scaleX - 1f);
        }
        float centerXDiff = (getWidth() * scaleX) / 2;

        if (scaleX < 0f) {
            matrix.preTranslate(x + Math.abs(centerXDiff), y);
        } else {
            matrix.preTranslate(x - Math.abs(centerXDiff), y);
        }

        matrix.preRotate(rotation, 0, bitmapCenterY);
        matrix.preScale(scaleX, 1f);

        canvas.drawBitmap(bitmap, matrix, paint);
    }

I cannot reproduce by myself, but I have a bunch of users having a fatal exception when last line "canvas.drawBitmap" gets called. What could be the problem? I checked your source code and couldn't find a place where you call bitmap.recycle().

This is the stacktrace:

Fatal Exception: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@1bafec58
       at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1225)
       at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:589)
       at MyCustomConfetto.drawInternal(MyCustomConfetto.java:57)
       at com.github.jinatonic.confetti.confetto.Confetto.getWidth(Confetto.java:342)
       at com.github.jinatonic.confetti.confetto.Confetto.getWidth(Confetto.java:332)
       at com.github.jinatonic.confetti.ConfettiView.onDraw(ConfettiView.java:132)

Add shape method

A .shape(intArrayOf()) should be added in CommonConfetti so it is easier to add shapes in one single line.

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.