Quantcast
Channel: Active questions tagged javascript - Stack Overflow
Viewing all articles
Browse latest Browse all 138163

How to implement a class controller option in Flare React package

$
0
0

So I don't quite understand how classes work in React, I am new to react and have used useState a little bit, but never have know what to do with a class. I am using this react package that has an example of how to use a controller to make you animation interactive built with flare now called rive. https://github.com/2d-inc/Flare-React#readme

What I want to achieve is to either run a different animation, or the same animation again when I hover over canvas element that is generated. I can create a second animation in flate(rive) that would still output in the same .flr file and I should then be able to reference it in the controller and run it on hover, just stuck on how to even do that part, or even get this controller to work. One thing to note is I can get the animation to run fine without the controller.

In the docs they have this example code

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;
    }
}

First of all what is a constructor? what does super mean? then what are they defining in the constructor, is that some state, how do I determine what to define here?

For the initialized I assume I match it to the state above, and get the animation by the name I named it in flare(rive)

The advance part I don't really understand are we setting the animation with this._WalkTime += elapsed; to how long the animation runs? I think I understand the apply section, it is applying a duration to the animation.

Next it has this code

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

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

Here is my attempted code currently I get the following error

TypeError: Cannot set property 'state' of undefined

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

For reference there is a a tutorial on how to make an animation interactive but it's for flutter, but it has some insights into there api https://medium.com/rive/building-a-responsive-house-with-flare-flutter-31af823ba805

Update

Here is my new attempted code after trying to read up on classes in es6, I still need to learn more.

So how do I go about running a second animation on click or hover or any event. The animation runs once now, but I don't know whow to use the 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
            }
          }
        }
      }
    }
  }
`

Viewing all articles
Browse latest Browse all 138163

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>