We all love celebrating! And no celebration is complete without some Confetti in it. In Summer’19, Salesforce introduced Confetti celebration in Lightning Path.
https://releasenotes.docs.salesforce.com/en-us/summer19/release-notes/rn_sales_features_core_path.htm

But what if I tell you we can toss this confetti at a lot more places than just Lighnting Path? Sounds exciting, right?

But how do we do that?

Well, there is a JavaScript file which you can use in your Lightning Component as static resource and spread some love with that Confetti in your Salesforce org.
Link: https://cdn.jsdelivr.net/npm/canvas-confetti@0.2.1/dist/confetti.browser.min.js

I created a Lightning component to demo few of the confetti effects that we can do with this JavaScript file.

Code

showConfettiCMP.cmp

<aura:component implements="lightning:availableForFlowScreens,force:lightningQuickAction">
    
    <aura:attribute name="colors" type="String[]" default="['#610B0B','#FFFF00','#FF00BF','#0040FF','#585858','#00FFBF','#FE642E','#FFBF00','#0101DF','#FF8000','#00FF00','#FF0040','#A901DB','#0B0B3B','#FF0000']"/>
    
    <ltng:require scripts="{!$Resource.Confetti}"/>
    
    <div class="slds-align_absolute-center">
        <lightning:layout horizontalAlign="spread" verticalAlign="stretch" multipleRows="true" >
            <lightning:layoutItem class="slds-align_absolute-center" size="6" smallDeviceSize="6" mediumDeviceSize="6" largeDeviceSize="6"  flexibility="auto" padding="around-small">
                <lightning:button variant="brand" class="buttonBox" label="Basic Cannon" onclick="{!c.basicCannon}"/>
            </lightning:layoutItem>
            <lightning:layoutItem class="slds-align_absolute-center" size="6" smallDeviceSize="6" mediumDeviceSize="6" largeDeviceSize="6" flexibility="auto" padding="around-small">
                <lightning:button variant="brand" class="buttonBox" label="Fireworks" onclick="{!c.fireworks}"/>
            </lightning:layoutItem>
            <lightning:layoutItem class="slds-align_absolute-center" size="6" smallDeviceSize="6" mediumDeviceSize="6" largeDeviceSize="6" flexibility="auto" padding="around-small">
                <lightning:button variant="brand" class="buttonBox" label="Confetti Shower" onclick="{!c.confettiShower}"/>
            </lightning:layoutItem>
            <lightning:layoutItem class="slds-align_absolute-center" size="6" smallDeviceSize="6" mediumDeviceSize="6" largeDeviceSize="6" flexibility="auto" padding="around-small">
                <lightning:button variant="brand" class="buttonBox" label="Winner Celebration" onclick="{!c.winnerCelebration}"/>
            </lightning:layoutItem>
            <lightning:layoutItem class="slds-align_absolute-center" size="6" smallDeviceSize="6" mediumDeviceSize="6" largeDeviceSize="6" flexibility="auto" padding="around-small">
                <lightning:button variant="brand" class="buttonBox" label="Burst Mode" onclick="{!c.busrtMode}"/>
            </lightning:layoutItem>
            <lightning:layoutItem class="slds-align_absolute-center" size="6" smallDeviceSize="6" mediumDeviceSize="6" largeDeviceSize="6" flexibility="auto" padding="around-small">
                <lightning:button variant="brand" class="buttonBox" label="Canvas Confetti" onclick="{!c.canvasConfetti}"/>
            </lightning:layoutItem>
        </lightning:layout>
    </div>
    <br/>
        
    <canvas id="customCanvas" aura:id="customCanvas" class="canvasCss">
    </canvas>
       
</aura:component>

showConfettiCMPController.js

({
    basicCannon : function(component, event, helper) {
        confetti({
            particleCount: 200,
            startVelocity: 60,
            spread: 150,
            origin: {
                y: 0.9
            },
            colors : component.get("v.colors")
        });
    },
    
    fireworks : function(component, event, helper){
        var end = Date.now() + (15 * 100);
        
        var interval = setInterval(function() {
            if (Date.now() > end) {
                return clearInterval(interval);
            }
            
            confetti({
                particleCount : 450,
                startVelocity: 30,
                spread: 360,
                ticks: 60,
                origin: {
                    x: Math.random(),
                    // since they fall down, start a bit higher than random
                    y: Math.random() - 0.2
                },
                colors : component.get("v.colors")
            });
        }, 200);
    },
    
    confettiShower : function(component, event, helper){
        var end = Date.now() + (15 * 100);
        
        (function frame() {
            confetti({
                particleCount: 10,
                startVelocity: 0,
                ticks: 300,
                origin: {
                    x: Math.random(),
                    // since they fall down, start a bit higher than random
                    y: 0
                },
                colors: component.get("v.colors")
            });
            
            if (Date.now() < end) {
                requestAnimationFrame(frame);
            }
        }());
    },
    
    winnerCelebration : function(component, event, helper) {
        var end = Date.now() + (15 * 100);
        
        (function frame() {
            confetti({
                particleCount: 10,
                angle: 60,
                spread: 25,
                origin: {
                    x: 0,
                    y : 0.65
                },
                colors: component.get("v.colors")
            });
            confetti({
                particleCount: 10,
                angle: 120,
                spread: 25,
                origin: {
                    x: 1,
                    y : 0.65
                },
                colors: component.get("v.colors")
            });
            
            if (Date.now() < end) {
                requestAnimationFrame(frame);
            }
        }());
    },
    
    canvasConfetti : function(component, event, helper){
        debugger;
        var canvas =  document.getElementById("customCanvas"); //component.find("customCanvas");
        
        
        // save this function... we'll save it to the canvas itself for
        // the purpose of this demo
        canvas.confetti = canvas.confetti || confetti.create(canvas, {
            resize: true
        });
        
        canvas.confetti({
            spread: 70,
            origin: {
                y: 1.2
            },
            colors : component.get("v.colors")
        });
    },
    
    busrtMode : function(component, event, helper){
        
        var end = Date.now() + (15 * 75);
        
        // go Buckeyes!
        var colors = ['#610B0B','#FFFF00','#FF00BF','#0040FF','#585858','#00FFBF','#FE642E','#FFBF00','#0101DF','#FF8000','#00FF00','#FF0040','#A901DB','#0B0B3B','#FF0000'];
        
        (function frame() {
            confetti({
                particleCount: 7,
                startVelocity: 25,
                angle: 335,
                spread: 10,
                origin: {
                    x: 0,
                    y: 0,
                },
                colors: colors
            }); 
            confetti({
                particleCount: 7,
                startVelocity: 25,
                angle: 205,
                spread: 10,
                origin: {
                    x: 1,
                    y: 0,
                },
                colors: colors
            });
            
            confetti({
                particleCount: 7,
                startVelocity: 35,
                angle: 140,
                spread: 30,
                origin: {
                    x: 1,
                    y: 1,
                },
                colors: colors
            });
            
            confetti({
                particleCount: 7,
                startVelocity: 35,
                angle: 40,
                spread: 30,
                origin: {
                    x: 0,
                    y: 1,
                },
                colors: colors
            });
            
            if (Date.now() < end) {
                requestAnimationFrame(frame);
            }
        }());
    }
})

showConfettiCMP.css

.THIS .buttonBox{
    position:relative;
    display: inline-block;
    width: 100%;
    max-width : 200px;
    height: 100px;
    padding: 1px !important;
    border: 1px solid #d8dde6; 
}

.THIS .selected{
    border: 3px solid rgb(0, 112, 210);
}

.THIS.canvasCss{
    background-color: black;
    width : 100%;
    height : 250px;
}

Demo

For you guys, I created a small component and bundled it as an unmanaged package which you can use in directly in your flows for the Confetti effect. To extend the usability, you can add other interfaces in the component and use it accordingly.

Package: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6F000004DGGL&isdtp=p1

How would it look in flows?

Also, I have something interesting for you to play with. Consider giving this a try too!
https://www.kirilv.com/canvas-confetti/

Thank you for being an awesome reader! If you haven’t already, please subscribe to this blog for receiving all the latest updates straight into your inbox.  🙂