在Scroll上触发Lottie动画

时间:2018-04-23 17:54:28

标签: fullpage.js lottie bodymovin

我目前正在使用整页js和lottie动画构建网站。现在我试图在用户滚动到带动画的部分时触发动画。这是我试过的: (请注意,我对js很新)

$(document).ready(function($) {'use strict';

$('#fullpage').fullpage({
sectionsColor: ['white', '#004E8A', 'white','#004E8A', 'white', '#004E8A', 
'white','#004E8A', 'white'],
anchors:['startseite','pers_vermittler','team','konzept','rechner','mod_portfolio','sicherheit','absatz'],

onLeave: function(index, nextIndex, direction) {
    if( index == 3 && direction == 'down' ) {
    lottie.play('k2an');
  }

(在正文部分的末尾 - >;)

<script>
var params = {
    container: document.getElementById('k2an'),
    renderer: 'svg',
    loop: true,
    autoplay: false,
    path: 'k2an.json',
};

anim = lottie.loadAnimation(params);

2 个答案:

答案 0 :(得分:0)

您应该使用fullPage.js callbacks来启动JS动画。

参见示例:

$('#fullpage').fullpage({
    anchors: ['firstPage', 'secondPage', 'thirdPage', 'fourthPage', 'lastPage'],

    afterLoad: function(anchorLink, index){
        var loadedSection = $(this);

        //using index
        if(index == 3){
            alert("Section 3 ended loading");
        }

        //using anchorLink
        if(anchorLink == 'secondSlide'){
            alert("Section 2 ended loading");
        }
    }
});

您也可以使用my video tutorial检查fullPage.js state classes如何创建动画。

答案 1 :(得分:-1)

现在我正在几个生产网站上使用这种方法。它会在用户滚动时播放动画

我基本上检查了视口中有多少动画对象框可见,计算动画的总长度(以帧为单位),然后将百分比投影到i gotoAndStop()的框架中。

&#13;
&#13;
#include "stdafx.h"
#include <stdlib.h>
#include <string>
#include <iostream>
using namespace std;

extern "C"{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libavutil/pixfmt.h"
}

int extraDataSize;
static const int MaxExtraDataSize = 1024;
uint8_t extraDataBuffer[MaxExtraDataSize];

void AddExtraData(uint8_t* data, int size)
{
    auto newSize = extraDataSize + size;
    if (newSize > MaxExtraDataSize){
        throw "extradata exceeds size limit";
    }
    memcpy(extraDataBuffer + extraDataSize, data, size);
    extraDataSize = newSize;
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::string strFramesPath("g:\\frames\\");

    AVCodec* avCodec;
    AVCodecContext* avCodecContext;
    AVFrame* avFrame;
    AVCodecID codecId = AV_CODEC_ID_H264;
    unsigned char sprops_part_1[9] = { 0x27, 0x42, 0x80, 0x1f, 0xda, 0x02, 0xd0, 0x49, 0x10 };
    unsigned char sprops_part_2[4] = { 0x28, 0xce, 0x3c, 0x80 };

    av_register_all();
    avcodec_register_all();
    avCodec = avcodec_find_decoder(codecId);
    avCodecContext = avcodec_alloc_context3(avCodec);
    if (!avCodecContext)
    {
        cout << "avcodec_alloc_context3 failed." << endl;
        return 0;
    }
    uint8_t startCode[] = { 0x00, 0x00, 0x01 };

    // sprops
    {
        // sprops 1
        AddExtraData(startCode, sizeof(startCode));
        AddExtraData(sprops_part_1, 9);
        // sprops 2
        AddExtraData(startCode, sizeof(startCode));
        AddExtraData(sprops_part_2, 4);

        avCodecContext->extradata = extraDataBuffer;
        avCodecContext->extradata_size = extraDataSize;
    }

    AddExtraData(startCode, sizeof(startCode));
    avCodecContext->flags = 0;
    if (avcodec_open2(avCodecContext, avCodec, NULL) < 0)
    {
        cout << "failed to open codec" << endl;
        return 0;
    }
    avFrame = av_frame_alloc();
    if (!avFrame)
    {
        cout << "failed to alloc frame" << endl;
        return 0;
    }

    void *buffer = malloc(100 * 1024);  // 100 KB buffer - all frames fit in this buffer
    for (int nFrameIndex = 0; nFrameIndex < 257; nFrameIndex++)
    {
        std::string strFilename = std::string("g:\\frames\\" + std::to_string(nFrameIndex));
        FILE* f = fopen(strFilename.c_str(), "rb");
        fseek(f, 0, SEEK_END);
        long nFileSize = ftell(f);
        fseek(f, 0, SEEK_SET);
        size_t nReadSize = fread(buffer, 1, nFileSize, f);
        // cout << strFilename << endl;
        if (nReadSize != nFileSize)
        {
            cout << "Error reading file data" << endl;
            continue;
        }
        AVPacket avpkt;
        avpkt.data = (uint8_t*)buffer;
        avpkt.size = nReadSize;

        while (avpkt.size > 0)
        {
            int got_frame = 0;
            auto len = avcodec_decode_video2(avCodecContext, avFrame, &got_frame, &avpkt);
            if (len < 0) {
                //TODO: log error
                cout << "Error decoding - error code: " << len << endl;
                break;
            }
            if (got_frame)
            {
                cout << "* Got 1 Decoded Frame" << endl;
            }
            avpkt.size -= len;
            avpkt.data += len;
        }
    }

    getchar();
    return 0;
}
&#13;
&#13;
&#13;

如果你想只启动动画并让它运行(独立于进一步的用户滚动行为),只需使用jquery inview插件,在动画上禁用自动播放并触发播放( )曾经这样:

&#13;
&#13;
var anim = <YOUR LOTTIE ANIMATION OBJECT>

// play around with these
var speed = 1; // speed of animation
var scrollOffset = 0; // start animation sooner / later

function scrollHandler() {
            if (!anim.isLoaded) return;
            p = percentageSeen(e) / 100 - (scrollOffset || 0);
            if (p <= 0 || p >= 1) return

            var length = anim.totalFrames / anim.frameModifier;
            var pos = length * p * (speed || 1);
            anim.goToAndStop(pos);
}

$(window).on('scroll', scrollHandler);




/**
 * returns percentage of scrolling element through viewport
 * 0% until element-middle is at bottom of viewport
 * 100% if element-middle is at top of viewport
 *
 * @param id
 * @returns {number}
 */
function percentageSeen(idOrElement) {
    var $element;

    if (typeof idOrElement === 'object') {
        $element = idOrElement;
    } else {
        $element = $('#' + id);
        if (!$element[0]) return 0;
    }

    var $win = $(window), viewportHeight = $(window).height(),
        scrollTop = $win.scrollTop(),
        elementOffsetTop = $element.offset().top,
        elementHeight = $element.height();


    if (elementOffsetTop > (scrollTop + viewportHeight)) {
        return 0;
    } else if ((elementOffsetTop + elementHeight) < scrollTop) {
        return 100;
    } else {
        var distance = (scrollTop + viewportHeight) - elementOffsetTop - (elementHeight / 2);
        if (distance < 0) return 0;
        var percentage = distance / (viewportHeight / 100);
        if (percentage > 100) return 100;
        return percentage;
    }
}
&#13;
&#13;
&#13;