在没有 react-transition-group 和 ref 的情况下使用 gsap 对动画进行反应
react animation with gsap without react-transition-group and ref
我对 GSAP 和 React 有疑问,正如我从一些教程中读到的那样,它们都使用 react-transition-group 并且其中许多使用 ref 作为 GSAP 的替代选择器,但是,如果我在中使用 ref在我的例子中,整个页面都会被动画化,我只想让一个元素动画化,所以我使用了 id 选择器,它像这样工作得很好
import React from 'react';
import { TweenMax } from 'gsap';
import uuid from 'uuid';
import '../styles/homePage.css';
class HomePage extends React.Component{
startAnimation=(pic)=>{
TweenMax.from(`#${pic.id}`, 1, {
opacity: 0,
x: -100,
y: -100
});
}
render(){
const PicsNum = 15;
let pics = [];
let pic = {};
for (let i = 5; i <= PicsNum; i++) {
const picPath = `/pictures/testingPics/${i}.jpg`
pic={id:`a${uuid()}`, picPath}
pics.push(pic)
}
const renderPics = pics.map((p, i) => (
<div
key={i}
className='img-container'
>
<img src={p.picPath} className='pic' id={p.id}/>
<button onClick={()=>{this.startAnimation(p)}}>click</button>
</div>
))
return (
<div className='pics'>
{renderPics}
</div>
)
}
}
export default HomePage;
有人能告诉我为什么要使用 react-transition-group 吗?如果我想像现在这样使用没有它的动画会出什么问题?非常感谢
所以,您在这里所做的对于简单的动画来说绝对没问题。只有当你的逻辑和动画开始变得越来越复杂时,你才会发现它有缺点。
随着逻辑/动画的复杂性增加,您可能会遇到的主要问题是您现在实际上是在使用两个不同的库来定位 dom。 React 想要完全控制 dom 所以它可以做它的事情。然而,GSAP 现在也在 dom 中寻找一个元素并控制它的状态,并且 React 不知道所以现在事情可能会不同步。当用户已经触发淡出时,React 可能会重新渲染该组件,将不透明度重置为 1。
React-transition-group 可以是一个有用的工具,可以简化动画组件的进出工作,但这不是唯一的方法,也不是反应动画的全部和结束,所以不要觉得您 有 使用它。也许只是研究一下简化代码的方法,你必须为每个你想要动画的组件编写代码。 (它为您提供了动画进出的特定生活方式,以及用于移除组件 post 动画的回调,这是组件转换的大部分样板)。
在第一个问题中,我提到 Transition-group 在这里很有用,因为你所有的动画代码都包含在它提供的助手中,所以 React 知道:1)你的动画......不要做任何事情直到你已经完成了... 2) 现在你已经完成了,我又回来了。
但是还有过渡组之外的其他选项来处理dom控制的这种二分法:
您可以尝试变得超级聪明并对其进行声明...使用 refs 访问元素并将它们传递给由 state/props 触发和控制的 gsap 动画。
但是有一些出色的库可以消除所有担心状态和动画以及诸如 https://github.com/azazdeaz/react-gsap-enhancer
之类的麻烦
这是一个很棒的高阶组件,它只是确保 gsap 对元素所做的任何更改在反应重新渲染和状态更改中得到注意和保留。
老实说,这有点神奇,让使用 React 和 GSAP 成为一种绝对的乐趣。
同时回答你关于 'Why refs' 的问题而不是有用的 'just pass a string of the ID to the gsap function':
这里没有对错之分。 React 中的 ref 将在内存中存储指向该 Dom 元素的指针。使其成为方便的查找。它的主要优点是对该元素的引用不会在重新渲染时过期。如果您使用 GetElementById 手动 select 一个元素,并且该 Dom 节点被 react 重新渲染替换,那么您的变量引用将变为未定义,您将不得不再次调用 GetElementById。 GetElementById 在性能方面非常便宜,它与性能无关,只是避免在每次重新渲染后必须 'find' 对 Dom 元素的新引用的样板。
我对 GSAP 和 React 有疑问,正如我从一些教程中读到的那样,它们都使用 react-transition-group 并且其中许多使用 ref 作为 GSAP 的替代选择器,但是,如果我在中使用 ref在我的例子中,整个页面都会被动画化,我只想让一个元素动画化,所以我使用了 id 选择器,它像这样工作得很好
import React from 'react';
import { TweenMax } from 'gsap';
import uuid from 'uuid';
import '../styles/homePage.css';
class HomePage extends React.Component{
startAnimation=(pic)=>{
TweenMax.from(`#${pic.id}`, 1, {
opacity: 0,
x: -100,
y: -100
});
}
render(){
const PicsNum = 15;
let pics = [];
let pic = {};
for (let i = 5; i <= PicsNum; i++) {
const picPath = `/pictures/testingPics/${i}.jpg`
pic={id:`a${uuid()}`, picPath}
pics.push(pic)
}
const renderPics = pics.map((p, i) => (
<div
key={i}
className='img-container'
>
<img src={p.picPath} className='pic' id={p.id}/>
<button onClick={()=>{this.startAnimation(p)}}>click</button>
</div>
))
return (
<div className='pics'>
{renderPics}
</div>
)
}
}
export default HomePage;
有人能告诉我为什么要使用 react-transition-group 吗?如果我想像现在这样使用没有它的动画会出什么问题?非常感谢
所以,您在这里所做的对于简单的动画来说绝对没问题。只有当你的逻辑和动画开始变得越来越复杂时,你才会发现它有缺点。
随着逻辑/动画的复杂性增加,您可能会遇到的主要问题是您现在实际上是在使用两个不同的库来定位 dom。 React 想要完全控制 dom 所以它可以做它的事情。然而,GSAP 现在也在 dom 中寻找一个元素并控制它的状态,并且 React 不知道所以现在事情可能会不同步。当用户已经触发淡出时,React 可能会重新渲染该组件,将不透明度重置为 1。
React-transition-group 可以是一个有用的工具,可以简化动画组件的进出工作,但这不是唯一的方法,也不是反应动画的全部和结束,所以不要觉得您 有 使用它。也许只是研究一下简化代码的方法,你必须为每个你想要动画的组件编写代码。 (它为您提供了动画进出的特定生活方式,以及用于移除组件 post 动画的回调,这是组件转换的大部分样板)。
在第一个问题中,我提到 Transition-group 在这里很有用,因为你所有的动画代码都包含在它提供的助手中,所以 React 知道:1)你的动画......不要做任何事情直到你已经完成了... 2) 现在你已经完成了,我又回来了。
但是还有过渡组之外的其他选项来处理dom控制的这种二分法:
您可以尝试变得超级聪明并对其进行声明...使用 refs 访问元素并将它们传递给由 state/props 触发和控制的 gsap 动画。
但是有一些出色的库可以消除所有担心状态和动画以及诸如 https://github.com/azazdeaz/react-gsap-enhancer
之类的麻烦这是一个很棒的高阶组件,它只是确保 gsap 对元素所做的任何更改在反应重新渲染和状态更改中得到注意和保留。
老实说,这有点神奇,让使用 React 和 GSAP 成为一种绝对的乐趣。
同时回答你关于 'Why refs' 的问题而不是有用的 'just pass a string of the ID to the gsap function':
这里没有对错之分。 React 中的 ref 将在内存中存储指向该 Dom 元素的指针。使其成为方便的查找。它的主要优点是对该元素的引用不会在重新渲染时过期。如果您使用 GetElementById 手动 select 一个元素,并且该 Dom 节点被 react 重新渲染替换,那么您的变量引用将变为未定义,您将不得不再次调用 GetElementById。 GetElementById 在性能方面非常便宜,它与性能无关,只是避免在每次重新渲染后必须 'find' 对 Dom 元素的新引用的样板。