Giter VIP home page Giter VIP logo

astro-lottie's Introduction

Astro Lottie

Use Lottie animations within your Astro website.

Installation

astro-integration-lottie requires lottie-web to be installed as well.

npm i astro-integration-lottie lottie-web
# or
pnpm add astro-integration-lottie lottie-web
# or
yarn add astro-integration-lottie lottie-web

Usage

Integration

Required first step: add the integration to your astro.config file.

import { defineConfig } from "astro/config";
import lottie from "astro-integration-lottie";

export default defineConfig({
  integrations: [
    lottie(), // <-- add integration
  ]
});

Type support

This integration defines the astroLottie global object to interact with your animations inside a page. Details on the dedicated section. You can have full type info of the astroLottie object with an environment reference.

Create an env.d.ts or, if you already have one, add the following line:

/// <reference types="astro-integration-lottie/env" />

Component

Inside your astro page or component, you can import the Lottie component. It supports props autocompletion and type checking.

---
import LottieAnimation from "astro-integration-lottie/Lottie.astro";
---
<div class="container">
    <LottieAnimation src="assets/animation.json" autoplay="visible" />
</div>

Styling, sizing and constraints

You can use a parent div as a container to set the size and set additional styling (background, ...).

You can either use the style attribute or reference a css class.

<!-- with css class -->
<div class="container">
    <LottieAnimation src="assets/animation.json" autoplay="visible" />
</div>


<!-- or style -->
<div style="width: 200px; height: 150px;">
    <LottieAnimation src="assets/animation.json" autoplay="visible" />
</div>

How Astro Lottie works

Player loading

The lottie player is not bundled within your page. It's asynchronously fetched only when a page contains at least one lottie animation.

This package allows to load two players:

  • light: small player with only svg rendering
  • full: all featured player, with all capabilities

You can read more about lottie players in the Lottie repository.

When a page contains multiple animations with different players specified, the greater player will be loaded. So to load the light player, all animation musts set the player="light" (or no player at all, as the default one is the "light").

The lottie player is locally saved in the public folder (it's handled under the hood by astro/vite) so no external request is sent.

Animation loading

The lottie animations are not bundled in your page. They're asynchronously fetched when the page loading ends, when a small loader script is run.

The loader will

  • check if the page has any lottie animations
  • fetch the lottie player
  • download the animations (if one is used multiple times, it's downloaded once)
  • setup each the animation on the page
  • if the autoplay is true, the animation is started right away, otherwise the animation will play only when it's visible and paused when it exits the screen. This is achieved thanks to IntersectionObserver, with a visibility filter 0.01.
  • raise a document event astro-lottie-loaded when all animations are loaded and ready

Accessing the Lottie Player

This plugin registers a astroLottie global object for the page.

const astroLottie = window.astroLottie;
if (!astroLottie) {
  // lottie is not registered! Either ...
  // - no lottie animation is present on this page
  // - lottie library failed to load  
} else {
  const animation = astroLottie.getAnimation("my-animation");
  animation.player.play();
}

The AstroLottie has two features:

  • getting a specific animation by a key
  • getting all animations present in the page

The full specification is:

export type AstroLottie = {
    /**
     * Get a LottieAnimation by the configured id
     */
    getAnimation(id: string): LottieAnimation | undefined

    /**
     * Get a LottieAnimation from the hosting element container
     */
    getAnimation(from: { container: HTMLElement }): LottieAnimation | undefined

    /**
     * Get a LottieAnimation from the hosting element container
     */
    getAnimation(from: { elementId: string }): LottieAnimation | undefined

    /**
     * Get all the LottieAnimation for the current page
     */
    getAllAnimations(): LottieAnimation[]
}

A LottieAnimation represents a single animation registered for the current page and is defined with:

export type LottieAnimation = Readonly<{
    id: string                        // the specified id es: <Lottie id="my-animation" />
    config: LottieAnimationConfig     // the full lottie configuration of the Lottie element
    container: HTMLElement            // the hosting dom element container
    isLoaded: boolean                 // specify if the animation is successfully loaded
    player?: AnimationItem            // this is the real Lottie player. It's defined when isLoaded is true
}>

The player property is the Lottie player, typed by the Lottie library itself. You can checkout Lottie repository for the documentation.

For example if you need to start an animation on demand when a button is clicked.

document.querySelector("#play-button").addEventListener("click", () => {
  const animation = astroLottie.getAnimation("my-animation");
  if (animation && animation.isLoaded) {
    animation.player.play();
  }
});

Animation ready event

The loader emit a document event astro-lottie-loaded when all animations are loaded and ready. The details property of the event, is the astroLottie global object.

document.addEventListener("astro-lottie-loaded", e => {
  const astroLottie = e.details;
  const animations = astroLottie.getAllAnimations();
});

Reference

LottieAnimationConfig --> the Lottie component Props

property type usage description
id string optional used to access the relative lottie player via javascript
src string required the public path from where the animation will be downloaded
player "light" | "full" optional("light") which lottie player to load
loop boolean optional(true) play the animation on loop
autoplay true | "visible" optional("visible") starts the animation as soon it loads or only when it's visible on the page
visibleThreshold number optional(0) Range[0-1] for the visibility to start the animation: 1 means 100% visible, 0 means that just 1px will make the animation play. When multiple animations on the same page use different thresholds, the minimum will be used for all

Types

This package is built in typescript so it has full typings support.

License

MIT © Giuseppe La Torre

astro-lottie's People

Contributors

giuseppelt avatar

Stargazers

 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

astro-lottie's Issues

Cannot read properties of undefined (reading 'default')

I get the following error when trying to integrate this package into an empty astro project.

Astro version: 2.0.15

 error   Cannot read properties of undefined (reading 'default')
  File:
    C:\...\node_modules\vite\dist\node\chunks\dep-ca21228b.js:52420:9
  Code:
    52419 |         const initModule = new AsyncFunction(`global`, ssrModuleExportsKey, ssrImportMetaKey, ssrImportKey, ssrDynamicImportKey, ssrExportAllKey, '"use strict";' + result.code + `\n//# sourceURL=${mod.url}`);
    > 52420 |         await initModule(context.global, ssrModule, ssrImportMeta, ssrImport, ssrDynamicImport, ssrExportAll);
            |         ^
      52421 |     }
      52422 |     catch (e) {
      52423 |         mod.ssrError = e;
  Stacktrace:
TypeError: Cannot read properties of undefined (reading 'default')
    at eval (C:\...\astro.config.mjs:10:27)
    at async instantiateModule (file:///C:/.../node_modules/vite/dist/node/chunks/dep-ca21228b.js:52420:9)

Need to add information about setting height and width of component in docs

I was implementing lottie in my recent astro project. I experienced difficulty in implementing it as docs does not tell us how to set height and width of the component.

I first thought it would work on its own and set width and height. I tried it like this.

<LottieAnimation src="assets/lottie/anim_listening_music.json" autoplay="true"/>

However, I realized I need to put this component in another div and set styling on it. So, I solved the problem by doing below.

<div style="width: 200px; height: 200px">
    <LottieAnimation src="assets/lottie/anim_listening_music.json" autoplay="true"/>
</div>

Documentation does not talk about this. And example is also not enough to know this.

It is my recommendation to either put height and width props in component itself or just update the docs and examples, so that it becomes straight forward for people to work with it without going into problem.

NOTE: setting style on component also does not work.

How do I get access to control the animation properties

Hey so I'm using this plugin as having issues using lottie-web in an astro component.

Your library does not allow me access the methods such as play and pause is that correct? (I am using this for a mobile menu animation)

If so how could I go about doing this.

Support for astro view transitions

I've been struggling with using this package and astro view transitions, after changing routes for the first time the animations disappear.
At first, I just started calling loadLottie on the astro:after-swap event. But after I added a lottie animation on the header (which is present on all routes) the header animation starts getting duplicated when loadLottie is called.

Right now I got it working with a workaround by clearing the children of the containers before loading the animations on loadLottie.

Is there a better solution for this?

Also, thanks for the work on the package.

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.