如何在nextjs中使用react-bodymovin

时间:2019-01-28 04:20:31

标签: reactjs animation next.js bodymovin

react-bodymovin非常适合我的reactjs应用程序,但是当迁移到nextjs时,它不起作用。我收到以下错误:

ReferenceError: window is not defined
    at Object.<anonymous> (/Users/xyz/work/web/dict/next/node_modules/bodymovin/build/player/bodymovin_light.min.js:1:226)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/xyz/work/web/dict/next/node_modules/react-bodymovin/lib/ReactBodymovin.js:2:17)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)

Justa导入库bodymovin,将导致上述所有问题

import React, { Component } from 'react';
import Router from 'next/router';
import Layout from '../components/Layout';
import SuggestionList from '../components/SuggestionList';
import dict from '../api/dict';
import ReactBodymovin from 'react-bodymovin';

如果我按以下方式禁用,则可以使用

import React, { Component } from 'react';
import Router from 'next/router';
import Layout from '../components/Layout';
import SuggestionList from '../components/SuggestionList';
import dict from '../api/dict';
//import ReactBodymovin from 'react-bodymovin';

1 个答案:

答案 0 :(得分:1)

您的问题很可能是由于使用的是不带有服务器端渲染错误修复程序的旧版bodymovin / lottie,因此未找到窗口,因为在服务器端编译时不存在该窗口。

此处的其他信息:https://github.com/zeit/next.js/wiki/FAQ#i-use-a-library-which-throws-window-is-undefined

要解决此问题:

1)在依赖项中添加正确的第三方:“ react-lottie”:“ ^ 1.2.3”

Lottie Web指定了a SSR bugfix,应更新react-lottie以避免窗口问题。

https://github.com/chenqingspring/react-lottie/issues/17

2)将以下文件放入./pages/lottie.js

import React from "react";
import Lottie from "react-lottie";
import * as animationData from "../animations/loading-spinner-black.json";

export default class LottieControl extends React.Component {
constructor(props) {
    super(props);
    this.state = { isStopped: false, isPaused: false };
}

render() {
    const buttonStyle = {
    display: "block",
    margin: "10px auto"
    };

    console.log(animationData);

    const defaultOptions = {
    loop: true,
    autoplay: true,
    animationData: animationData.default,
    rendererSettings: {
        preserveAspectRatio: "xMidYMid slice"
    }
    };

    return (
    <div>
        <Lottie
        options={defaultOptions}
        height={400}
        width={400}
        isStopped={this.state.isStopped}
        isPaused={this.state.isPaused}
        />
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isStopped: true })}
        >
        stop
        </button>
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isStopped: false })}
        >
        play
        </button>
        <button
        style={buttonStyle}
        onClick={() => this.setState({ isPaused: !this.state.isPaused })}
        >
        pause
        </button>
    </div>
    );
}
}

3)将以下文件放入./animations/loading-spinner-black.json

{"v":"5.1.8","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":100,"h":100,"nm":"Spinner","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"spinner Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2},"a":{"a":0,"k":[160,284,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,19.812],[19.882,0],[0,-19.882],[-19.882,0]],"o":[[0,-19.882],[-19.882,0],[0,19.882],[19.882,0]],"v":[[36,0],[0,-36],[-36,0],[0,36]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[100],"e":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"n":["0p833_1_0p167_0"],"t":29,"s":[0],"e":[0]},{"t":51.0000020772726}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"n":["0p833_0p833_0p333_0"],"t":20,"s":[100],"e":[1]},{"t":60.0000024438501}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[160,284],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_1_0p167_0p167"],"t":0,"s":[-90],"e":[270]},{"t":59.0000024031193}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60.0000024438501,"st":0,"bm":0}],"markers":[]}

4)“ npm run dev”并转到http://localhost:3000/lottie,您应该会看到带有控件的黑色旋转动画

或者,如果您不能更改依赖关系并通过process.cient强制使用客户端代码执行,则可以忽略上述内容。查看更多详细信息here

希望这会有所帮助。如果您还有其他问题,请告诉我,如有需要,我可以举一个实际的例子。