adrianmcli / react-reveal-text

✨ A small react library for animating the revealing of text.
https://adrianmcli.github.io/react-reveal-text/
186 stars 14 forks source link

Animations not properly applied when updating text #3

Closed DougLilliequist closed 6 years ago

DougLilliequist commented 6 years ago

Heya!

First off! Awesome job with this component!

Is there a way to fix this issue however: whenever I fade out the text, updating the components children (or text), and reveal the text again, it seems like if the new word is longer than the previous, the animations are not being applied

Here is an image of it looks like:

screen shot 2018-02-01 at 14 00 44

And here is the code:

` import React, { Component } from 'react'

import ReactDOM from 'react-dom'

import View from '../view/index.js'

import { projectCopy } from './projectCopy.js'

import { TweenLite } from 'gsap'

import ReactRevealText from 'react-reveal-text'

export default class Projects extends View {

constructor(props) {

    super(props)

    this.initProjectCopy()

    this.state = {

        index: 0,

        isInteracting: false,

        revealCopy: true,

    }

}

componentDidMount() {

    this.initEvents()

}

componentWillUnmount() {

    this.removeEvents()

}

initProjectCopy() {

    this.projectCopy = projectCopy

}

initEvents() {

    window.addEventListener('mousewheel', this.loadProject.bind(this))

}

removeEvents() {

    window.removeEventListener('mousehwheel', this.loadProject.bind(this))

}

loadProject(e) {

    if (this.state.isInteracting === false) {

        this.setState(() => {

            return {isInteracting: true}

        })

        TweenLite.to(this, 3.0, {

            onStart: () => {

                this.setState({revealCopy: false})

            },

            onUpdate: () => {

                e.preventDefault()

            },

            onComplete: () => {

                this.setState({title: ' '})

                if (e.deltaY > 0) {

                    this.setState((prevState) => {

                        return {index: prevState.index += (this.state.index < this.projectCopy.length - 1) ? 1 : 0}

                    })

                } else {

                    this.setState((prevState) => {

                        return {index: prevState.index - (this.state.index > 0) ? 1 : 0}

                    })

                }

                this.refs['titleContainer'].props = {text: this.projectCopy[this.state.index].title}

                this.setState({revealCopy: true})

                this.setState({isInteracting: false})

            }

        })

    }

}

render() {

    return(

        <div className = "Project" ref = "projectContainer">

            <ReactRevealText className = "Title" ref = "titleContainer" show = {this.state.revealCopy} text = {this.projectCopy[this.state.index].title}/>

            <ReactRevealText className = "Description" ref = "descContainer" show = {this.state.revealCopy} text = {this.projectCopy[this.state.index].description}/>

            <ReactRevealText className = "Tech" ref = "techContainer" show = {this.state.revealCopy} text = {this.projectCopy[this.state.index].tech}/>

        </div>

    )

}

}

`

DougLilliequist commented 6 years ago

Ok, I worked one solution to my issue, which was to simply clone my child component, update it's props with show = false and it worked! However I'm quite new to react and to me it seems like a quite costly procedure, unless it's a lot more expensive to remove and apply new spans on the fly?

adrianmcli commented 6 years ago

This probably has something to do with the fact that shouldComponentUpdate() always returns false if the show prop hasn't changed. That means that the spans (and their styles) are not being reapplied when you change your text.

It may be a good idea to allow users to opt-in to this optimization. I welcome any PRs for this.

DougLilliequist commented 6 years ago

Okok! So If I just remove that condition, should the component then update with the new spans? And of curiosity, would it be more performant to update a components children(i,e the new spans) than unmounting and rendering a new component?

adrianmcli commented 6 years ago

Try the new version 0.1.1. I made additional checks under shouldComponentUpdate.

DougLilliequist commented 6 years ago

Tried it yesterday and It made my code much simpler, but both my old and new solution with your updated code is making my project hurt in chrome due to a huge composite layer / paint call. I did notice however when running my project in firefox, it runs super smooth!

Other than that, amazing job with this component!

adrianmcli commented 6 years ago

Yeah unfortunately, there's no other way to do this (without using SVG or Canvas). DOM element updates are necessary to apply the spans and that tends to be expensive.