javascript - 如何在 Flare React 包中实现类 Controller 选项

标签 javascript reactjs animation flare rive

更新:我在其底部添加了一个codesanbox,其中包含我需要完成的操作的更详细说明。

所以我不太明白类在 React 中是如何工作的,我是 React 新手,并且使用过一点 useState,但从来不知道如何处理类。我正在使用这个 React 包,它有一个示例,说明如何使用 Controller 使动画与 Flare 交互构建,现在称为 rive。 https://github.com/2d-inc/Flare-React#readme

我想要实现的是当我将鼠标悬停在生成的 Canvas 元素上时运行不同的动画或再次运行相同的动画。我可以在 flate(rive) 中创建第二个动画,它仍然会在同一个 .flr 文件中输出,然后我应该能够在 Controller 中引用它并在悬停时运行它,只是停留在如何执行该部分的问题上,或者甚至让这个 Controller 工作。需要注意的一件事是我可以让动画在没有 Controller 的情况下正常运行。

在文档中他们有这个示例代码

class PenguinController extends FlareComponent.Controller
{
    constructor()
    {
        super();
        this._MusicWalk = null;
        this._Walk = null;
        this._WalkTime = 0;
    }

    initialize(artboard)
    {
        this._MusicWalk = artboard.getAnimation("music_walk");
        this._Walk = artboard.getAnimation("walk");
    }

    advance(artboard, elapsed)
    {
        // advance the walk time
        this._WalkTime += elapsed;
        const { _MusicWalk: musicWalk, _Walk: walk, _WalkTime: walkTime } = this;

        // mix the two animations together by applying one and then the other (note that order matters).
        walk.apply(walkTime % walk.duration, artboard, 1.0);
        // if you want to slowly disable the head bobbing (musicWalk animation) you could ramp down the 
        // final argument (the mix argument) to 0.0 over some time. For now we're mixing at full strength.
        musicWalk.apply(walkTime % musicWalk.duration, artboard, 1.0);

        // keep rendering
        return true;
    }
}

首先什么是构造函数? super 是什么意思?那么他们在构造函数中定义了什么,是某种状态,我如何确定在这里定义什么?

对于初始化,我假设我将其与上面的状态匹配,并通过我在flare(rive)中命名的名称获取动画

我不太明白的高级部分是我们将动画设置为 this._WalkTime += elapsed; 动画运行多长时间?我想我理解了应用部分,它正在向动画应用持续时间。

接下来有这段代码

class MyComponent extends React.Component
{
    constructor()
    {
        this.state = { penguinController: new PenguinController() };
    }

    render()
    {
        return <FlareComponent controller={this.state.penguinController} /*... more properties here ...*/ />;
    }
}

这是我当前尝试的代码,我收到以下错误

类型错误:无法设置未定义的属性“状态”

import React from "react"
import PropTypes from "prop-types"
import { useStaticQuery, graphql } from "gatsby"
import FlareComponent from 'flare-react';
import styled from 'styled-components'
import Header from "./header"
import "../sass/index.scss"

const LogoWrapper = styled.div`
  width:200px;
  height:200px;
`

class AnimationController extends FlareComponent.Controller
{
    constructor()
    {
        super();
        this._MusicWalk = null;
    }

    initialize(artboard)
    {
        this._MusicWalk = artboard.getAnimation("Wispy Appear");
    }

    advance(artboard, elapsed)
    {

        const { _MusicWalk: musicWalk } = this;

        musicWalk.apply(musicWalk.duration, artboard, 1.0);

        // keep rendering
        return true;
    }
}

const Layout = ({ children }) => {
  const data = useStaticQuery(graphql`
    query SiteTitleQuery {
      site {
        siteMetadata {
          title
        }
      }
    }
  `)


        this.state = { AnimationController: new AnimationController() };


  return (
    <>
      <LogoWrapper>
        <FlareComponent width={200} height={200} animationName="Wispy Appear" controller={this.state.AnimationController} file="/wispy-2.flr"/>
      </LogoWrapper>

        <main className="main-wrapper">{children}</main>
        <footer>
          © {new Date().getFullYear()}, Built with
          {` `}
          <a href="https://www.gatsbyjs.org">Gatsby</a>
        </footer>
    </>
  )
}

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Layout

作为引用,有一个关于如何使动画交互的教程,但它是针对 flutter 的,但它对 api https://medium.com/rive/building-a-responsive-house-with-flare-flutter-31af823ba805 有一些见解。

更新

这是我在尝试阅读 es6 中的类后尝试的新代码,我仍然需要了解更多信息。

那么我该如何在点击、悬停或任何事件上运行第二个动画。动画现在运行一次,但我不知道谁使用 Controller ?

import React from "react"
import Img from 'gatsby-image'
import styled from "styled-components"
import FlareComponent from 'flare-react';
import Layout from "../components/layout"


const LogoWrapper = styled.div`
  width:200px;
  height:200px;
`

class wispyController extends FlareComponent.Controller
{
    constructor()
    {
        super();
        this._Animate = null;
    }

    initialize(artboard)
    {
        this._Animate = artboard.getAnimation("Wispy Appear");
    }

    advance(artboard, elapsed)
    {

        const { _Animate: animate } = this;
        animate.apply(5, artboard, 1.0);

        // keep rendering
        return true;
    }
}


class IndexPage extends React.Component  {

  constructor()
  {
      super();
      this.state = { wispyController: new wispyController() };
  }

  render(){
    const {data} = this.props;

    return(

      <Layout>

        <LogoWrapper>
          <FlareComponent width={200} height={200} animationName="Wispy Appear" controller={this.state.wispyController} file="/Wispy.flr"/>
        </LogoWrapper>



    {data.allSanityBlogPost.edges.map(({ node: post }) => (  
      <article key={post.id}>
        <h1>{post.name}</h1>
        <img src={post.imageGif.asset.url}/>
      </article>
    ))}


      </Layout>
    )

  }

}

export default IndexPage

export const query = graphql`
  query IndexQuery {
    allSanityBlogPost {
      edges {
        node {
          name
          id
          imageGif {
            asset {
              url
            }
          }
        }
      }
    }
  }
`

好的,希望有人可以在这里提供帮助,我制作了一个codesandbox,以便有人可以看到我想要实现的目标。有两个动画,在页面上您可以看到第一个动画有一个应该混合这两个动画的 Controller ,然后是其他两个动画。我想要发生的是第一个动画运行,然后第二个动画在悬停时运行。这是代码沙箱https://codesandbox.io/s/frosty-water-jnj9m

最佳答案

React 上下文中的类可以被认为是大多数面向对象编程语言中的类,它们是创建对象的蓝图。为了让语言知道我们创建它时如何以及要做什么,它需要一个构造函数方法。此构造函数方法正在调用一个名为 super() 的特殊方法,以便它调用其所扩展的类的构造函数,在本例中为 FlareComponent.Controller

将调用 advance 方法来添加类(class)跟踪的捕获步行时间。

问题之一是您尝试直接设置组件的状态,而不是使用 setState https://reactjs.org/docs/react-component.html

我强烈建议您在继续之前先温习一下 React 基础知识,这将真正帮助您获得所需的适当基础。

关于javascript - 如何在 Flare React 包中实现类 Controller 选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59737493/

相关文章:

javascript - 为什么这个对象没有被正确解析?

javascript - 在 ExtJS Grid 中设置日期过滤器的值

javascript - 删除输入值时不会触发 onChange

javascript - 如何在 ReactJS 中使用带有钩子(Hook)的复选框作为单选按钮?

android - 在android Translate-Animation中如何在另一个view2上方翻译view1,两个 View 以不同的布局退出

c# - 使用 WPF C# 同时对两个 UIElement 进行动画处理

javascript - React 上的缩放模块 d3 出现问题

javascript - 将 React 函数转换为 React 类

html - 创建一个在 X 秒后开始的 CSS3 动画

javascript - Gruntfile Jade 任务编译奇怪的模板