zoukankan      html  css  js  c++  java
  • hooks 与 animejs

    hooks 与 animejs

    本文写于 2020 年 1 月 13 日

    animejs 是现如今非常不错的一个 js 动画库。我们将其与 React Hooks 融合,使它更方便的在 React 中使用。

    最终效果:

    const Animate: React.FC = () => {
      const { animateTargetRef, animationRef } = useAnime({
        translateX: 300,
        loop: true,
        duration: 2000,
        autoplay: false,
      });
    
      useEffect(() => {
        setTimeout(() => {
          animationRef.current?.play?.();
        }, 3000);
      }, [animationRef]);
    
      return (
        <div
          ref={animateTargetRef}
          style={{  '100px', height: '100px', backgroundColor: 'black' }}
        />
      );
    };
    

    首先看看 animejs 在一般的 JS 和 HTML 中如何使用:

    <div class="xxx"></div>
    
    import anime from 'animejs';
    
    const animation = anime({
      translateX: 300,
      loop: true,
      duration: 2000,
      autoplay: false,
      targets: '.xxx',
    });
    
    animation.play();
    

    但是在 React 中,我们不想要到处写这些玩意儿。我们喜欢 hooks!

    所以我们可以封装一个 useAnime hook。

    第一步,我们可以引入 AnimeParams,让我们的 hook 拥有代码提示:

    import anime, { AnimeParams } from 'animejs';
    
    export const useAnime = (props: AnimeParams) => {
      anime(props);
    };
    

    然后我们通过 useRef 将 anime 的 targets 绑定,并且暴露出去,供其他地方使用。

    //...
    const animateTargetRef = useRef<any>(null);
    
    useLayoutEffect(() => {
      if (!animationTargetRef.current) {
        console.warn('please bind animation target ref');
        return;
      }
      animate({
        ...props,
        targets: [animationTargetRef.current],
      });
    }, [props]);
    
    return { animateTargetRef };
    //...
    

    通过观察发现,animate 返回的是 AnimeInstance 类型,我们从 animejs 中导入:

    import anime, { AnimeParams, AnimeInstance } from 'animejs';
    
    // ...
    
    const animationRef = useRef<AnimeInstance>();
    
    // ...
    animationRef.current = animate({
      ...props,
      targets: [animationTargetRef.current],
    });
    // ...
    
    return { animateTargetRef, animationRef };
    

    这样就轻松完成了 useAnime 的封装。

    完整代码:

    import anime, { AnimeParams, AnimeInstance } from 'animejs';
    import { useRef, useLayoutEffect } from 'react';
    
    export const useAnime = (props: AnimeParams = {}) => {
      const animateTargetRef = useRef<any>();
      const animationRef = useRef<AnimeInstance>();
    
      useLayoutEffect(() => {
        if (!animateTargetRef.current) {
          console.warn('please bind the anime ref while useAnime');
          return;
        }
        animationRef.current = anime({
          ...props,
          targets: [animateTargetRef.current],
        });
      }, [props]);
    
      return { animateTargetRef, animationRef };
    };
    

    (完)

  • 相关阅读:
    从零开始在虚拟机中搭建一个4个节点的CentOS集群(三)-----将一台虚拟机复制成4台虚拟机
    从零开始在虚拟机中搭建一个4个节点的CentOS集群(二)-----在虚拟机中安装Java和Perl
    java后台访问接口
    java文件名更改一直是false,看看是否是文件打开没有关
    java后台调用url无协议
    MyEclipse怎么设置个性化代码注释模板
    sql参数化查询in的参数
    mongodb索引
    oracle分配权限:一个用户访问另一个用户的表
    spring读写分离
  • 原文地址:https://www.cnblogs.com/xhyccc/p/14274343.html
Copyright © 2011-2022 走看看