New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

animot-presenter

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

animot-presenter

Embed animated presentations anywhere. Works with vanilla JS, React, Vue, Angular, Svelte, and any frontend framework. Morphing animations, code highlighting, charts, particles, and more.

latest
Source
npmnpm
Version
0.2.9
Version published
Maintainers
1
Created
Source

animot-presenter

Embed animated presentations anywhere. A single <animot-presenter> tag that plays Animot animation JSON files with morphing transitions, code syntax highlighting, charts, particles, and more.

Works with any framework: vanilla HTML/JS, React, Vue, Angular, Svelte, or any frontend stack.

Install

npm install animot-presenter

CDN (for vanilla HTML or quick prototyping)

<link rel="stylesheet" href="https://unpkg.com/animot-presenter/dist/cdn/animot-presenter.css">
<script src="https://unpkg.com/animot-presenter/dist/cdn/animot-presenter.min.js"></script>

Or use the ES module version:

<link rel="stylesheet" href="https://unpkg.com/animot-presenter/dist/cdn/animot-presenter.css">
<script type="module" src="https://unpkg.com/animot-presenter/dist/cdn/animot-presenter.esm.js"></script>

Quick Start

<animot-presenter src="/my-animation.json" autoplay loop controls></animot-presenter>

That's it. The component loads the JSON, renders the animation canvas, and handles everything — morphing, transitions, code highlighting, keyboard navigation.

Usage by Framework

Vanilla HTML / JavaScript

<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/animot-presenter/dist/cdn/animot-presenter.min.js"></script>
  <style>
    /* Size the presenter however you want */
    .hero-animation {
      width: 100%;
      height: 500px;
    }
  </style>
</head>
<body>
  <animot-presenter
    class="hero-animation"
    src="/animations/hero.json"
    autoplay
    loop
    controls
  ></animot-presenter>

  <script>
    const presenter = document.querySelector('animot-presenter');

    // Listen for events
    presenter.addEventListener('slidechange', (e) => {
      console.log(`Slide ${e.detail.index + 1} of ${e.detail.total}`);
    });

    presenter.addEventListener('complete', () => {
      console.log('Animation finished');
    });

    // Load data programmatically
    fetch('/animations/demo.json')
      .then(res => res.json())
      .then(data => {
        presenter.data = data;
      });

    // Control programmatically
    presenter.next();
    presenter.prev();
  </script>
</body>
</html>

Svelte 5

npm install animot-presenter
<script>
  import { browser } from '$app/environment';
  import { AnimotPresenter } from 'animot-presenter';
</script>

<!-- Wrap with {#if browser} in SvelteKit to skip SSR -->
<div style="width: 100%; height: 500px;">
  {#if browser}
    <AnimotPresenter
      src="/animations/hero.json"
      autoplay
      loop
      controls
      onslidechange={(index, total) => console.log(`${index + 1}/${total}`)}
    />
  {/if}
</div>

SvelteKit SSR: The component uses browser APIs (canvas, ResizeObserver) and cannot be server-rendered. Always wrap with {#if browser} in SvelteKit, or use ssr: false in your +page.ts.

React

npm install animot-presenter
// Import once to register the custom element
import 'animot-presenter/element';
import { useEffect, useRef } from 'react';

function HeroAnimation() {
  const ref = useRef(null);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;

    const handleSlideChange = (e) => {
      console.log(`Slide ${e.detail.index + 1} of ${e.detail.total}`);
    };

    el.addEventListener('slidechange', handleSlideChange);
    return () => el.removeEventListener('slidechange', handleSlideChange);
  }, []);

  return (
    <animot-presenter
      ref={ref}
      src="/animations/hero.json"
      autoplay
      loop
      controls
      style={{ width: '100%', height: '500px', display: 'block' }}
    />
  );
}

// With programmatic data
function ProgrammaticDemo({ data }) {
  const ref = useRef(null);

  useEffect(() => {
    if (ref.current && data) {
      ref.current.data = data;
    }
  }, [data]);

  return (
    <animot-presenter
      ref={ref}
      controls
      arrows
      style={{ width: '100%', height: '400px', display: 'block' }}
    />
  );
}

TypeScript: Add this to your react-app-env.d.ts or a global .d.ts file:

declare namespace JSX {
  interface IntrinsicElements {
    'animot-presenter': React.DetailedHTMLProps<
      React.HTMLAttributes<HTMLElement> & {
        src?: string;
        autoplay?: boolean;
        loop?: boolean;
        controls?: boolean;
        arrows?: boolean;
        progress?: boolean;
        keyboard?: boolean;
        duration?: number;
        'start-slide'?: number;
      },
      HTMLElement
    >;
  }
}

Vue 3

npm install animot-presenter
<script setup>
import 'animot-presenter/element';
import { ref, onMounted } from 'vue';

const presenterRef = ref(null);
const animationData = ref(null);

function onSlideChange(e) {
  console.log(`Slide ${e.detail.index + 1} of ${e.detail.total}`);
}

// Load data programmatically
onMounted(async () => {
  const res = await fetch('/animations/demo.json');
  animationData.value = await res.json();
  if (presenterRef.value) {
    presenterRef.value.data = animationData.value;
  }
});
</script>

<template>
  <!-- Option A: Load from URL -->
  <animot-presenter
    src="/animations/hero.json"
    autoplay
    loop
    controls
    style="width: 100%; height: 500px; display: block"
    @slidechange="onSlideChange"
  />

  <!-- Option B: Programmatic data -->
  <animot-presenter
    ref="presenterRef"
    controls
    arrows
    style="width: 800px; height: 450px; display: block"
  />
</template>

Important: Tell Vue to treat animot-presenter as a custom element. In vite.config.ts:

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag) => tag === 'animot-presenter'
        }
      }
    })
  ]
});

Angular

npm install animot-presenter

1. Register the custom element in main.ts:

import 'animot-presenter/element';

2. Allow custom elements in your module or standalone component:

// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  // ...
})
export class AppModule {}

Or in a standalone component:

@Component({
  selector: 'app-hero',
  standalone: true,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <animot-presenter
      src="/animations/hero.json"
      autoplay
      loop
      controls
      style="width: 100%; height: 500px; display: block"
      (slidechange)="onSlideChange($event)"
      (complete)="onComplete()"
    ></animot-presenter>
  `
})
export class HeroComponent {
  onSlideChange(event: CustomEvent) {
    console.log(`Slide ${event.detail.index + 1} of ${event.detail.total}`);
  }

  onComplete() {
    console.log('Animation finished');
  }
}

3. Programmatic control:

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-demo',
  standalone: true,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `
    <animot-presenter #presenter controls arrows
      style="width: 100%; height: 400px; display: block">
    </animot-presenter>
    <button (click)="loadAnimation()">Load</button>
  `
})
export class DemoComponent implements AfterViewInit {
  @ViewChild('presenter') presenterRef!: ElementRef;

  async loadAnimation() {
    const res = await fetch('/animations/demo.json');
    const data = await res.json();
    this.presenterRef.nativeElement.data = data;
  }
}

Props / Attributes

AttributeTypeDefaultDescription
srcstringURL to an Animot JSON file
dataobjectInline JSON object (JS property only)
autoplaybooleanfalseAuto-advance slides
loopbooleanfalseLoop back to first slide after last
controlsbooleantrueShow prev/next/play controls
arrowsbooleanfalseShow left/right carousel arrows
progressbooleantrueShow progress bar at bottom
keyboardbooleantrueEnable arrow key navigation
durationnumberOverride all transition durations (ms)
start-slidenumber0Initial slide index

Note: data can only be set via JavaScript property, not as an HTML attribute.

Events

EventDetailDescription
slidechange{ index: number, total: number }Fired when slide changes
completeFired when last slide is reached
// Vanilla JS
presenter.addEventListener('slidechange', (e) => {
  console.log(e.detail.index, e.detail.total);
});

// Svelte
<AnimotPresenter onslidechange={(i, t) => ...} oncomplete={() => ...} />

// Vue
<animot-presenter @slidechange="handler" @complete="handler" />

// Angular
<animot-presenter (slidechange)="handler($event)" (complete)="handler()" />

Styling

The presenter fills its parent container. Control the size by styling the parent:

/* Full page */
animot-presenter {
  display: block;
  width: 100vw;
  height: 100vh;
}

/* Hero section */
animot-presenter {
  display: block;
  width: 100%;
  height: 500px;
}

/* Fixed size card */
animot-presenter {
  display: block;
  width: 400px;
  height: 225px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.2);
}

Customizing Controls

Override the built-in styles using CSS specificity:

/* Custom control bar background */
animot-presenter .animot-controls {
  background: rgba(30, 30, 30, 0.9);
  border-radius: 20px;
  padding: 6px 12px;
}

/* Custom button style */
animot-presenter .animot-controls button {
  background: transparent;
  border-radius: 50%;
}

animot-presenter .animot-controls button:hover {
  background: rgba(255, 255, 255, 0.15);
}

/* Custom progress bar */
animot-presenter .animot-progress-fill {
  background: #3b82f6;
}

/* Custom arrow buttons */
animot-presenter .animot-arrow {
  background: rgba(0, 0, 0, 0.6);
  width: 48px;
  height: 48px;
}

/* Always show controls (no hover needed) */
animot-presenter .animot-controls,
animot-presenter .animot-arrow,
animot-presenter .animot-progress-bar {
  opacity: 1 !important;
}

/* Hide controls entirely via CSS */
animot-presenter .animot-controls { display: none; }

Tailwind CSS

<animot-presenter
  class="w-full h-[500px] rounded-xl overflow-hidden shadow-2xl"
  src="/animation.json"
  autoplay
  loop
></animot-presenter>

Features

  • Morphing animations — Elements with the same ID across slides smoothly morph position, size, rotation, color, opacity, border radius, and CSS filters (blur, brightness, contrast, saturate, grayscale)
  • Code highlighting — Syntax highlighting via Shiki with typewriter, highlight-changes, and instant animation modes
  • Shape morphing — Rectangles, circles, triangles, stars, hexagons with smooth transitions
  • Charts — Animated bar, line, area, pie, and donut charts
  • Counters — Animated number counting with formatting
  • Particles — Canvas-based particle backgrounds with configurable shapes and connections
  • Confetti — Burst, continuous, fireworks, and snow confetti effects
  • Floating animations — Gentle floating motion for elements (vertical, horizontal, or both)
  • Transitions — Fade, slide, zoom, flip, and morphing (none) transition types
  • Responsive — Automatically scales to fit any container size
  • Keyboard navigation — Arrow keys, spacebar, Home/End
  • CSS filters — Blur, brightness, contrast, saturate, and grayscale on any element, animated across slides
  • Property sequencing — Fine-grained control over which properties animate first (including filters via the blur property sequence)

JSON Schema

Animot JSON files follow this structure:

{
  "schemaVersion": 1,
  "id": "unique-id",
  "name": "My Animation",
  "slides": [
    {
      "id": "slide-1",
      "name": "Intro",
      "canvas": {
        "width": 1920,
        "height": 1080,
        "background": {
          "type": "gradient",
          "gradient": { "type": "linear", "angle": 135, "colors": ["#1a1a2e", "#16213e"] }
        },
        "elements": [
          {
            "id": "title",
            "type": "text",
            "content": "Hello World",
            "position": { "x": 100, "y": 200 },
            "size": { "width": 600, "height": 80 },
            "fontSize": 48,
            "fontWeight": 700,
            "color": "#ffffff",
            "rotation": 0,
            "visible": true,
            "zIndex": 1,
            "blur": 0,
            "brightness": 100,
            "contrast": 100,
            "saturate": 100,
            "grayscale": 0
          }
        ]
      },
      "transition": { "type": "fade", "duration": 500, "easing": "ease-in-out" },
      "duration": 3000
    }
  ],
  "settings": {
    "defaultCanvasWidth": 1920,
    "defaultCanvasHeight": 1080,
    "defaultTransition": { "type": "fade", "duration": 500, "easing": "ease-in-out" },
    "defaultSlideDuration": 3000
  }
}

Create animations visually at animot.io and export as JSON.

Editing the JSON

You can edit the exported JSON file directly. For example, image elements use a src field that accepts any valid image source:

{
  "id": "logo",
  "type": "image",
  "src": "data:image/png;base64,iVBORw0KGgo..."
}

You can replace the base64 data URL with a remote or local URL:

// Remote URL
"src": "https://example.com/images/logo.png"

// Relative path (served from your project)
"src": "/images/logo.png"

// Another relative path
"src": "./assets/hero-bg.jpg"

This lets you keep your JSON files lightweight by hosting images separately instead of embedding them as base64. The same applies to text elements with backgroundImage and background image fields.

CSS Filters

All element types support CSS filter properties that animate smoothly between slides:

{
  "id": "hero-image",
  "type": "image",
  "blur": 5,
  "brightness": 120,
  "contrast": 110,
  "saturate": 80,
  "grayscale": 0
}
PropertyRangeDefaultDescription
blur0–200Gaussian blur in pixels
brightness0–200100Brightness percentage (100 = normal)
contrast0–200100Contrast percentage (100 = normal)
saturate0–200100Saturation percentage (100 = normal)
grayscale0–1000Grayscale percentage (0 = none)

Set different filter values on the same element across slides to create smooth animated transitions (e.g., blur 10 on slide 1 to blur 0 on slide 2 for a reveal effect). Use the blur property sequence in animationConfig.propertySequences to control filter animation timing independently.

Note: Remote URLs must allow cross-origin requests (CORS) if served from a different domain.

Bundle Size

BuildRawGzipped
CDN (IIFE)~5.0 MB~850 KB
CDN (ESM)~5.2 MB~870 KB
Svelte (tree-shakeable)~56 KB

The CDN bundle includes Shiki for code syntax highlighting with 70 web-focused languages (see list below). The npm Svelte package is much smaller since Shiki is loaded lazily at runtime with all 500+ languages available.

CDN supported languages

The CDN bundle includes these languages for code highlighting:

angular-html, angular-ts, astro, bash, blade, c, c++, coffee, cpp, css, glsl, gql, graphql, haml, handlebars, html, http, imba, java, javascript, jinja, jison, json, json5, jsonc, jsonl, js, jsx, julia, less, lit, markdown, marko, mdc, mdx, php, postcss, pug, python, r, regex, sass, scss, sh, shell, sql, stylus, svelte, ts, tsx, typescript, vue, wasm, wgsl, xml, yaml, yml, zsh

npm install gives you all 500+ Shiki languages. The CDN bundle uses the lighter shiki/bundle/web with 70 common web/programming languages. If your code blocks use an unsupported language, it falls back to JavaScript highlighting.

Browser Support

Works in all modern browsers that support Custom Elements v1:

  • Chrome 67+
  • Firefox 63+
  • Safari 10.1+
  • Edge 79+

License

Business Source License 1.1 (BUSL-1.1)

  • Free for non-commercial and personal use
  • Commercial use requires a paid license — contact support@beeblock.com.br
  • After the change date (4 years from each release), the code converts to Apache-2.0

Keywords

svelte

FAQs

Package last updated on 22 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts