• Jump To … +
    ./demo/modules/canvas-minimap.js ./demo/modules/canvas-scene-editor.js ./demo/modules/dom-entity-editor.js ./demo/modules/entity-copy-paste.js ./demo/modules/entity-manipulation-gui.js ./demo/modules/entity-navigation.js ./demo/modules/entity-ring-builder.js ./demo/modules/london-crime-graphic.js ./demo/modules/london-crime-lines.js ./demo/modules/london-crime-stacked-bars.js ./demo/modules/lottie-loader.js ./demo/modules/simple-chart-frame-tests.js ./demo/modules/simple-chart-frame.js ./demo/modules/simple-graph-lines.js ./demo/modules/simple-graph-stacked-bars.js ./demo/modules/wikipedia-views-spiral-chart.js ./demo/snippets/animated-highlight-gradient-text-snippet.js ./demo/snippets/animated-hover-gradient-snippet.js ./demo/snippets/animated-word-gradient-snippet.js ./demo/snippets/before-after-slider-infographic.js ./demo/snippets/bubbles-text-snippet.js ./demo/snippets/green-box-snippet.js ./demo/snippets/jazzy-button-snippet.js ./demo/snippets/page-performance-snippet-test.js ./demo/snippets/page-performance-snippet.js ./demo/snippets/pan-image-snippet.js ./demo/snippets/placeholder-effect-snippet.js ./demo/snippets/ripple-effect-snippet.js ./demo/snippets/risograph-text-gradient-snippet.js ./demo/snippets/spotlight-text-snippet-test.js ./demo/snippets/spotlight-text-snippet.js ./demo/snippets/swirling-stripes-text-snippet.js ./demo/snippets/text-snippet-helper.js ./demo/snippets/word-highlighter-snippet.js ./demo/snippets/worley-text-gradient-snippet.js
  • §

    Demo Modules 004

    Factory function to load, play and expose a Lottie animation as an asset for use by Scrawl-canvas Picture entitys and Pattern styles

    Related files:

    • Lottie loader - main module

    Import the Scrawl-canvas object

    • There’s various ways to do this. See Demo DOM-001 for more details
    import * as scrawl from '../../source/scrawl.js';
  • §

    The Lottie animation loader function

    This factory takes a single items Javascript Object argument (to match the functionality of built-in Scrawl-canvas factories). Two of the attributes of this argument object are required, the others will fall back on default values. These attrributes are:

    • name (required) - String - unique name value
    • src (required) - String - path to the lottie.json animation file
    • width - Number - width of the animation; default 1000
    • bodymovinLibrary - String - CDN path at which the Bodymovin library can be obtained; default: https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.8.1/lottie.min.js

    The factory returns a Promise which resolves to an object which contains handles to the RawAsset Object, the Bodymovin controller Object, and a kill function which will remove all objects and DOM infrastructure when invoked.

    export default function (items) {
    
        let { src, bodymovinLibrary, width, name, loop, autoplay } = items;
    
        if (!src || !name) return false;
    
        if (loop == null) loop = false;
        if (autoplay == null) autoplay = false;
        if (!width) width = 1000;
    
        if (!bodymovinLibrary) bodymovinLibrary = 'https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.8.1/lottie.min.js';
    
        const doWork = function () {
    
            const hold = document.createElement('div');
            hold.style.height = '0';
            hold.style.overflow = 'hidden';
    
            const container = document.createElement('div');
            container.style.width = `${width}px`;
            container.id = name;
    
            hold.appendChild(container);
            document.body.appendChild(hold);
  • §

    @ts-expect-error

            const controller = bodymovin.loadAnimation({
                container,
                path: src,
                renderer: 'canvas',
                loop: true,
                autoplay: true,
                name,
            });
    
            const asset = scrawl.makeRawAsset({
    
                name: `${name}-asset`,
    
                userAttributes: [{
                    key: 'lottie', 
                    defaultValue: controller,
                    setter: () => {},
                },{
                    key: 'lottieCanvas', 
                    defaultValue: null,
                    setter: () => {},
                },{
                    key: 'canvasWidth', 
                    defaultValue: 0,
                    setter: () => {},
                },{
                    key: 'canvasHeight', 
                    defaultValue: 0,
                    setter: () => {},
                },{
                    key: 'trigger', 
                    defaultValue: false,
                    setter: function (item) { this.dirtyData = item },
                }],
    
                updateSource: function (assetWrapper) {
    
                    let { element, engine, canvasWidth, canvasHeight, lottieCanvas } = assetWrapper;
    
                    if (!lottieCanvas) {
    
                        const c = container.querySelector('canvas');
    
                        if (c) {
    
                            lottieCanvas = this.lottieCanvas = c;
                            canvasWidth = this.canvasWidth = c.width;
                            canvasHeight = this.canvasHeight = c.height;
                        }
                    }
    
                    if (lottieCanvas) {
    
                        element.width = canvasWidth;
                        element.height = canvasHeight;
    
                        engine.drawImage(lottieCanvas, 0, 0, canvasWidth, canvasHeight);
                    }
                },
            });
            return {
                asset,
                controller,
                kill: () => {
                    asset.kill();
                    controller.destroy();
                    hold.remove();
                },
            }
        };
  • §

    @ts-expect-error

        if (!window.bodymovin) {
    
            return new Promise(resolve => {
    
                const script = document.createElement('script');
                script.src = bodymovinLibrary;
                script.type = 'text/javascript';
    
                script.onload = function () {
                    resolve(doWork());
                };
    
                document.body.appendChild(script);
            });
        }
        return Promise.resolve(doWork());
    };