Enable Dark Mode!
how-to-create-a-custom-effect-in-odoo-17.jpg
By: Aswin AK

How to Create a Custom Effect in Odoo 17

Technical Odoo 17

Odoo 17's effect system allows developers to create engaging visual feedback for user actions. This blog post demonstrates how to implement a custom firework effect using Odoo's OWL framework, JavaScript, and SCSS. The firework effect displays an animated burst of particles to celebrate events like successful form submissions or milestone achievements.

Prerequisites

* Basic understanding of Odoo 17 module development.

* Familiarity with JavaScript, OWL framework, and SCSS.

* Odoo development environment configured.

Step 1: Setting Up the Module Structure

Create a custom Odoo module with the following structure:

custom_firework_effect/
+-- static/
¦   +-- src/
¦   ¦   +-- js/
¦   ¦   ¦   +-- effect.js
¦   ¦   ¦   +-- firework_effect.js
¦   ¦   +-- scss/
¦   ¦   ¦   +-- firework_effect.scss
¦   ¦   +-- xml/
¦   ¦   ¦   +-- templates.xml
+-- __manifest__.py

Update __manifest__.py to include dependencies and assets:

{
    'name': "Custom Firework Effect",
    'depends': ['web'],
    'assets': {
        'web.assets_backend': [
            'custom_firework_effect/static/src/js/effect.js',
            'custom_firework_effect/static/src/js/firework_effect.js',
            'custom_firework_effect/static/src/scss/firework_effect.scss',
            'custom_firework_effect/static/src/xml/templates.xml',
        ],
    },
}

Step 2: Registering the Firework Effect

Define the firework effect in effect.js to register it in Odoo's effect registry.

/** @odoo-module **/
import { registry } from "@web/core/registry";
import { FireworkEffect } from "./firework_effect";
const effectRegistry = registry.category("effects");
function fireworkEffect(env, params = {}) {
 const message = params.message || "Congratulations!";
 const duration = params.duration || 3000;
if (env.services.user.showEffect) {
    return {
        Component: FireworkEffect,
        props: { message, duration },
    };
}
env.services.notification.add(message, { type: "success", title: "Success" });
}
effectRegistry.add("firework_effect", fireworkEffect);

This code:

* Imports the registry and FireworkEffect component.

* Defines a fireworkEffect function that accepts a message and duration.

* Returns the FireworkEffect component with props or falls back to a notification.

* Registers the effect as firework_effect.

Step 3: Creating the Firework Effect Component

The FireworkEffect component, defined in firework_effect.js, manages the particle animation and message display.

/** @odoo-module **/
import { Component, useState, useEffect } from "@odoo/owl";
import { browser } from "@web/core/browser/browser";
export class FireworkEffect extends Component {
    setup() {
        this.state = useState({
            particles: [],
            isAnimating: true,
        });
        this.particleCount = 30;
        this.duration = this.props.duration || 3000;
        useEffect(() => {
            // Generate particles
            const particles = Array.from({ length: this.particleCount }, () => ({
                x: Math.random() * 100,
                y: Math.random() * 100,
                angle: Math.random() * 360,
                speed: Math.random() * 5 + 2,
                color: `hsl(${Math.random() * 360}, 70%, 50%)`,
            }));
            this.state.particles = particles;
            // Animate particles
            const animationInterval = browser.setInterval(() => {
                this.state.particles = this.state.particles.map(particle => ({
                    ...particle,
                    x: particle.x + Math.cos(particle.angle * Math.PI / 180) * particle.speed,
                    y: particle.y + Math.sin(particle.angle * Math.PI / 180) * particle.speed,
                    speed: particle.speed * 0.98, // Slow down particles
                }));
            }, 30);
            // Close effect after duration
            const closeTimeout = browser.setTimeout(() => {
                this.state.isAnimating = false;
                browser.clearInterval(animationInterval);
                this.props.close();
            }, this.duration);
            return () => {
                browser.clearInterval(animationInterval);
                browser.clearTimeout(closeTimeout);
            };
        }, () => []);
    }
}
FireworkEffect.template = "custom_firework_effect.FireworkEffect";
FireworkEffect.props = {
    close: Function,
    message: String,
    duration: { type: Number, optional: true },
};

Key features:

* Generates random particles with position, angle, speed, and color.

* Animates particles using a setInterval loop.

* Closes the effect after the specified duration.

* Uses OWL's useState and useEffect for state and lifecycle management.

Step 4: Defining the Template

The template, defined in templates.xml, renders the firework particles and message.

<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
    <t t-name="custom_firework_effect.FireworkEffect">
        <div class="o_firework_effect" t-att-class="{ 'o_animating': state.isAnimating }">
            <div class="o_firework_container">
                <div class="o_firework_message"><t t-esc="props.message"/></div>
                <t t-foreach="state.particles" t-as="particle" t-key="particle_index">
                    <div class="o_firework_particle"
                         t-att-style="'transform: translate(' + particle.x + 'vw, ' + particle.y + 'vh); background-color: ' + particle.color + ';'"/>
                </t>
            </div>
        </div>
    </t>
</templates>

This template:

* Renders a container with a centered message.

* Dynamically creates particle elements with position and color styles.

* Applies an animation class for fade-in/out effects.

Step 5: Styling the Firework Effect

Style the firework effect in firework_effect.scss for visual appeal.

.o_firework_effect {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 1200;
    display: flex;
    justify-content: center;
    align-items: center;
    background: rgba(0, 0, 0, 0.5);
    opacity: 0;
    transition: opacity 0.5s ease;
    &.o_animating {
        opacity: 1;
    }
}
.o_firework_container {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
.o_firework_message {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 24px;
    font-weight: bold;
    color: #fff;
    text-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
    z-index: 1;
}
.o_firework_particle {
    position: absolute;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    opacity: 0.8;
    transition: transform 0.1s linear, opacity 0.5s ease;
}

The SCSS:

* Positions the effect full-screen with a semi-transparent background.

* Styles the message to be centered and prominent.

* Defines particles as small, colored circles with dynamic positioning.

* Applies a fade-in/out transition for the animation.

Step 6: Using the Firework Effect

Trigger the effect from any Odoo service or component using:

In Js:

this.env.services.effect.add({
    message: "Task Completed Successfully!",
    type: "firework_effect",
    duration: 4000,
});

In Python:

return {
            'effect': {
                'type': 'firework_effect',
                'message': _("Task Completed Successfully!"),
                'duration': 4000,
            }
        }

This displays a firework animation with the specified message for 4 seconds.

Conclusion

Creating a custom firework effect in Odoo 17 involves registering an effect, building an OWL component with particle animations, defining a template, and styling it with SCSS. This effect adds a celebratory touch to user interactions. You can extend this approach to create other visual effects like confetti, sparkles, or progress animations to enhance the Odoo user experience.

To read more about How to Create a Rainbow Man Effect in Odoo 17, refer to our blog How to Create a Rainbow Man Effect in Odoo 17.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message