• hooks 与 animejs


    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 的封装。

    https://www.houdianzi.com/ logo设计公司

    完整代码:

    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 };
    };
  • 相关阅读:
    创建对象的模式
    linux下安装node v12.16.3
    es6知识点总结
    在阿里云上部署的node服务器不能通过公网IP访问
    angular 1 input中选中状态绑定
    让一个元素水平垂直居中
    语录收集
    跨域
    事件循环
    git的常用命令
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/15149658.html
Copyright © 2020-2023  润新知