Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 基于动作的反应/重演动画_Javascript_Reactjs_Animation_Redux - Fatal编程技术网

Javascript 基于动作的反应/重演动画

Javascript 基于动作的反应/重演动画,javascript,reactjs,animation,redux,Javascript,Reactjs,Animation,Redux,差不多已经完成了我的第一个React+Redux应用程序,现在我想将动画应用到应用程序的各个部分。看看现有的解决方案,我发现没有什么比我想要的更接近的了。整个reactcstransitiongroup似乎是处理动画的一种侵入性和幼稚的方式。动画关注点从要设置动画的组件中流出,而您无法了解应用程序中发生的任何事情。从我的初步分析,我提出了以下的要求:我认为一个好的动画API: 父组件应该不知道子组件如何淡入/淡出(可能除了交错动画) 动画应与React集成,以便在移除组件之前允许组件淡出(或以

差不多已经完成了我的第一个React+Redux应用程序,现在我想将动画应用到应用程序的各个部分。看看现有的解决方案,我发现没有什么比我想要的更接近的了。整个
reactcstransitiongroup
似乎是处理动画的一种侵入性和幼稚的方式。动画关注点从要设置动画的组件中流出,而您无法了解应用程序中发生的任何事情。从我的初步分析,我提出了以下的要求:我认为一个好的动画API:

  • 父组件应该不知道子组件如何淡入/淡出(可能除了交错动画)
  • 动画应与React集成,以便在移除组件之前允许组件淡出(或以其他方式完成其动画)
  • 应该可以在不修改组件的情况下将动画应用于组件。组件的样式可以与动画兼容,但不应存在与动画相关的道具、状态、上下文或组件,动画也不应规定如何创建组件
  • 应该可以基于动作和应用程序状态执行动画-换句话说,当我拥有所发生事情的完整语义上下文时。例如,我可能会在创建某个对象时淡入组件,但在页面加载该项目时不会淡入。或者,我可以根据用户的设置选择适当的淡出动画
  • 应该可以为组件排队或组合动画
  • 应该可以将动画与父组件排队。例如,如果一个零部件有两个子零部件,打开其中一个子零部件将首先触发另一个子零部件关闭,然后再打开其自身
排队动画的细节可以由现有的动画库来处理,但是应该可以将其与react和redux系统结合起来

我尝试过的一种方法是创建这样一个装饰器函数(它是TypeScript,但我认为这与问题无关):

导出功能向下滑动(组件:T){
返回类FadesUp扩展React.Component{
私有选项={持续时间:0.3};
公共组件willenter(回调){
const el=findDOMNode(this).childNodes[0]作为元素;
如果(!el.classList.contains(“动画元素”)){
el.classList.add(“动画元素”);
}
TweenLite.set(el,{y:-el.clientHeight});
to(el,this.options.duration,{y:0,ease:Cubic.easeIn,onComplete:callback});
}
公共组件将离开(回调){
const el=findDOMNode(this).childNodes[0]作为元素;
如果(!el.classList.contains(“动画元素”)){
el.classList.add(“动画元素”);
}
to(el,this.options.duration,{y:-el.clientHeight,ease:Cubic.easeIn,onComplete:callback});
}
公开渲染(){
const Comp=任何组件;
返回;
}
}如有的话;
}
…可以这样应用

@popIn
export class Term extends React.PureComponent<ITermStateProps & ITermDispatchProps, void> {
    public render(): JSX.Element {
        const { term, isSelected, onSelectTerm } = this.props;
        return <ListItem rightIcon={<PendingReviewIndicator termId={term.id} />} style={isSelected ? { backgroundColor: "#ddd" } : {}} onClick={onSelectTerm}>{term.canonicalName}</ListItem>;
    }
}
@popIn
导出类术语扩展了React.PureComponent{
public render():JSX.Element{
const{term,isSelected,onSelectTerm}=this.props;
返回{term.canonicalName};
}
}
不幸的是,它要求将组件定义为一个类,但它确实允许在不修改组件的情况下以声明方式向组件添加动画。我喜欢这种方法,但讨厌将组件包装在一个转换组中,也不满足任何其他需求

我对React和Redux的内部和扩展点了解不够,无法很好地理解如何实现这一点。我认为thunk actions是管理动画流的好地方,但我不想将动作组件发送到动作中。相反,我希望能够检索操作或类似操作的源组件。另一个角度可以是一个专门的减速器,它同时传入动作和源组件,允许您以某种方式匹配它们并安排动画

所以我想我想要的是以下一个或多个:

  • 连接到React和/或Redux的方法,最好不要破坏性能或违反库的基本假设
  • 是否有任何现有库可以解决部分或所有这些问题,并且易于集成到应用程序中
  • 通过使用普通动画工具或很好地集成到普通构建块中来实现所有或大部分这些目标的技术或方法

我希望我对一切都理解正确……处理React+Redux意味着,在最好的情况下,您的组件是纯功能的。因此,应设置动画的组件(IMHO)应至少采用一个参数:
p
,该参数表示动画的状态
p
应该在区间
[0,1]
中,0代表开始,1代表结束,中间的所有内容代表当前进度

const Accordion = ({p}) => {
  return (
    …list of items, each getting p
  );
}
所以问题是,在动画开始之后,直到动画结束,在某个事件触发该过程之后,如何随时间分配动作(什么是异步的)

在这里很方便,因为它可以»处理«分派的动作,将它们转换为另一个动作,或转换为多个

//middleware/animatror.js

const animator = store => next => action => {
  if (action.type === 'animator/start') {

    //retrieve animation settings 
    const { duration, start, … } = action.payload;

    animationEngine.add({
      dispatch,
      action: {
       progress: () => { … },
       start: () => { … },
       end: () => { … }
      }
    })
  } else {
    return next(action);
  }
}

export default animator;
其中
animationEngine
AnimatoreEngine
的一个实例,该对象侦听
window.requestAnimationFrame<
//middleware/animatror.js

const animator = store => next => action => {
  if (action.type === 'animator/start') {

    //retrieve animation settings 
    const { duration, start, … } = action.payload;

    animationEngine.add({
      dispatch,
      action: {
       progress: () => { … },
       start: () => { … },
       end: () => { … }
      }
    })
  } else {
    return next(action);
  }
}

export default animator;
const createAnimationMiddleware = () => {
  const animatoreEngine = new AnimatorEngine;

  return const animator = store => next => action => { … }

}

export default createAnimationMiddleware;

//store.js
const animatorMiddleware = createAnimationMiddleware();

…

const store = createStore(
  …,
 applyMiddleware(animatorMiddleware, …)
)
const modulesOnSuccessAction => data {
  return {
    type: 'modules/listing-success',
    payload: { data }
  }
}

const modulesgetListing = id => dispatch({
  type: `get:/listing/${id}`,
  payload: {
    actions: {
      start: () => {},
      …
      success: data => modulesOnSuccessAction(data)
    }
  }
});

export { getListing }