前言:
今天同学们对“css动画停止”大概比较重视,咱们都需要了解一些“css动画停止”的相关知识。那么小编在网络上汇集了一些对于“css动画停止””的相关资讯,希望同学们能喜欢,朋友们一起来学习一下吧!手写一个 React 动画组件
Unity全流程开发热门游戏BallSort,助力迈入游戏领域
download:
但是假如当前动画除了展现还需求其他交互,以至是一个组件需求动画效果,运用图片格式就不合理了。于是我写一个极端简单的 css 动画库 rc-css-animate。这里直接运用 animate.css 作为 css 动画的依赖库。 animate.css 不但提供了很多交互动画款式类,也提供了动画运转速度,延迟,以及反复次数等款式类。
能够看到,默许的 animate.css 构建动画都需求携带前缀 “animate__”。
An animated element
当然,该库是对 css 动画停止了一层封装,仍然支持其他动画库以及本人手写的 css 动画,但假如开发者需求对动画停止各种复杂控制,不引荐运用此库。
运用
能够应用如下方式运用:
import React, { useRef } from "react";
import ReactCssAnimate from "rc-css-animate";
// 引入 animate.css 作为动画依赖
import "animate.css";
function App() {
const animateRef = useRef(null);
return (
<ReactCssAnimate
// 定义当前展现动画的组件
// 默许运用 div
tag="div"
// 当前组件的 className
className=""
// 当前组件的 style
style={{}}
// 当前组件的 ref
ref={animateRef}
// 动画前缀
clsPrefix="animate__"
// 当前动画的 className
animateCls="animated backInDown infinite"
// 动画开端时分能否处于展现状态
initialVisible={false}
// 获取动画完毕能否处置展现状态
getVisibleWhenAnimateEnd={(cls) => {
// 假如当前 animateCls 中有 Out
// 返回 false 则会在动画完毕后不再显现
if (cls.includes("Out")) {
return false;
}
return true;
}}
// 动画完毕回调
onAnimationEnd={() => {
console.log("done");
}}
>
测试动画
);
}
ReactCssAnimate 运用了 React hooks,但是也提供了兼容的类组件。同时也提供了全局的前缀设置。
import React from "react";
import {
// 运用类组件兼容之前的版本
CompatibleRAnimate as ReactCssAnimate,
setPrefixCls,
} from "rc-css-animate";
// 引入 animate.css 作为动画依赖
import "animate.css";
// 设置全局 prefix,会被当前组件掩盖
setPrefixCls("animate__");
/** 构建动画块组件 */
function BlockWrapper(props) {
// 需求获取并传入 className, children, style
const { className, children, style } = props;
return (
<div
className={className}
style={{
background: "red",
padding: 100,
...style,
}}
>
{children}
);
}
function App() {
return (
<ReactCssAnimate
tag={BlockWrapper}
// 当前动画的 className
animateCls="animated backInDown infinite"
>
测试动画
);
}
源码解析
源代码较为简单,是基于 createElment 和 forwardRef 构建完成。其中 forwardRef 会将当前设置的 ref 转发到内部组件中去。关于 forwardRef 不熟习的同窗能够查看一下官网中关于 Refs 转发的文档。
import React, {
createElement,
forwardRef,
useCallback,
useEffect,
useState,
} from "react";
import { getPrefixCls } from "./prefix-cls";
import { AnimateProps } from "./types";
// 全局的动画前缀
let prefixCls: string = "";
const getPrefixCls = (): string => prefixCls;
// 设置全局的动画前缀
export const setPrefixCls = (cls: string) => {
if (typeof cls !== "string") {
return;
}
prefixCls = cls;
};
const Animate = (props: AnimateProps, ref: any) => {
const {
tag = "div",
clsPrefix = "",
animateCls,
style,
initialVisible,
onAnimationEnd,
getVisibleWhenAnimateEnd,
children,
} = props;
// 经过 initialVisible 获取组件的显隐,假如没有则默许为 true
const [visible, setVisible] = useState(initialVisible ?? true);
// 当前不需求展现,返回 null 即可
if (!visible) {
return null;
}
// 没有动画类,直接返回子组件
if (!animateCls || typeof animateCls !== "string") {
return <>{children}</>;
}
useEffect(() => {
// 当前没获取恳求完毕的设置显现躲藏,直接返回,不停止处置
if (!getVisibleWhenAnimateEnd) {
return;
}
const visibleWhenAnimateEnd = getVisibleWhenAnimateEnd(animateCls);
// 假如动画完毕后需求展现并且当前没有展现,直接停止展现
if (visibleWhenAnimateEnd && !visible) {
setVisible(true);
}
}, [animateCls, visible, getVisibleWhenAnimateEnd]);
const handleAnimationEnd = useCallback(() => {
if (!getVisibleWhenAnimateEnd) {
onAnimationEnd?.();
return;
}
// 当前处于展现状态,且动画完毕后需求躲藏,直接设置 visible 为 false
if (visible && !getVisibleWhenAnimateEnd(animateCls)) {
setVisible(false);
}
onAnimationEnd?.();
}, [getVisibleWhenAnimateEnd]);
let { className = "" } = props;
if (typeof className !== "string") {
className = "";
}
let animateClassName = animateCls;
// 获取最终的动画前缀
const finalClsPrefix = clsPrefix || getPrefixCls();
// 没有或者动画前缀不是字符串,不停止处置
if (!finalClsPrefix || typeof finalClsPrefix !== "string") {
animateClassName = animateCls.split(" ").map((item) =>
`${finalClsPrefix}${item}`
).join(" ");
}
// 创立并返回 React 元素
return createElement(
tag,
{
ref,
onAnimationEnd: handleAnimationEnd,
// 将传送的 className 和 animateClassName 兼并
className: className.concat(` ${animateClassName}`),
style,
},
children,
);
};
// 应用 forwardRef 转发 ref
// 第一个参数是 props,第二个参数是 ref
export default forwardRef(Animate);
以上代码全部在 rc-css-animate 中。这里也欢送各位小同伴提出 issue 和 pr。
标签: #css动画停止