300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > html css js react vue 文字一行一行显示出来

html css js react vue 文字一行一行显示出来

时间:2021-07-26 03:59:51

相关推荐

html css js react vue 文字一行一行显示出来

前端时间在做年报,就不难涉及到年报具有的几大特性:

1、页面滑动特效

2、文字一行一行出现特效

3、页面内动画

等等

这片文章主要展示一下文字一行一行出现特效代码(react 为例)

先看效果图:

第一步:分析

想要使 文字一行一行显示出来 无非就三种方式

1、使用css控制:底层一个完整页面,上层一个只有背景图的完整页面,通过动画渐渐向下移动上层div,使底层div信息逐渐展示出来,以达到渐显的效果,但视觉效果较差。

2、使用js控制:使用js逐步增加dom节点,并给dom节点添加动画效果。(对于React,Vue这类框架层面应用,不建议直接使用JS控制 DOM 节点增删)

3、js + css控制:初次页面全部渲染出来,并给每一行增加 id 属性,但Css样式为 opacity: 0 透明,渲染完成后,通过js改变 css 动画 样式。(本文所采用方式)

第二部:布局

1、想要使文字一行一行展示出来,我们期望的是得到渲染数组,这样才能对顺序进行控制。不同段落之间我们也期望 从上往下的段落一行一行展示出来,所以我们期望得到一个二位数组,like this:

paragraphArrays : [[<Text text="第一段第一行" />,<Text text="第一段第二行" />,<Text text="第一段第三行" />,],[<Text text="第二段第一行" />,<Text text="第二段第二行" />,<Text text="第二段第三行" />,],]

2、不同页面的文本承载container样式可能不同,所以我们期望使用者可自定义样式。

3、不同页面段落之间的样式可能不同,所以我们期望使用者可自定义样式。

4、使用者可自定义行 id

这样,动画组件的 props 我们就定义好了

第三部:实现

1、渲染函数:

js:

import React, { useEffect } from 'react'import classnames from 'classnames'import styles from './AnimationText.module.scss'/*** @description: 文字段落一行一行出现动画* @param props:* paragraphArrays : [[<Text text="第一段第一行" />,<Text text="第一段第二行" />,<Text text="第一段第三行" />,],[<Text text="第二段第一行" />,<Text text="第二段第二行" />,<Text text="第二段第三行" />,],]* paragraphClassName: 段落className* className: container className* id: container id* @return {*}*/function AnimationText(props) {const { paragraphArrays, paragraphClassName, className, id } = props || {}return (<div className={classnames(styles.container, className)} id={id || 'animationText'} >{(paragraphArrays || []).map((item, index) => (<div className={classnames(styles.paragraph, paragraphClassName)}>{(item || []).map((component, idx) => (<div id={`${index}-${idx}-${id || 'animationText'}`} className={styles.nodeItem} >{component}</div>))}</div>))}</div>)}export default AnimationText

css:

.paragraph {margin-bottom: 15px;}.nodeItem {opacity: 0;}

2、获取 container DOM 节点

// 用于存储 存放动画的 containerlet element// 等同于 componentDidMountuseEffect(() => {element = document.getElementById(id || 'animationText')}, [])

3、获取到DOM节点后, 开始执行动画

css 动画定义:

// 透明度从0 到 1,动画只执行一次.nodeItemShow {visibility: visible;animation: scan 3s ease 0s 1;}@keyframes scan {0% {opacity: 0;}100% {opacity: 1;}}

js:

// 获取到 element 后,循环 paragraphArrays 数组,使用count 计数,每隔 600 * count 毫秒改变当前count 行的 css 样式useEffect(() => {if (element) {let count = 0for (let i = 0; i < paragraphArrays.length; i += 1) {for (let j = 0; j < paragraphArrays[i].length; j += 1) {count += 1setTimeout(() => {const ele = document.getElementById(`${i}-${j}-${id || 'animationText'}`)ele.setAttribute('class', styles.nodeItemShow)}, 600 * count)}}}}, [element])

完整代码:

js:

import React, { useEffect } from 'react'import classnames from 'classnames'import styles from './AnimationText.module.scss'/*** @description: 文字段落一行一行出现动画* @param props:* paragraphArrays : [[<Text text="第一段第一行" />,<Text text="第一段第二行" />,<Text text="第一段第三行" />,],[<Text text="第二段第一行" />,<Text text="第二段第二行" />,<Text text="第二段第三行" />,],]* paragraphClassName: 段落className* className: container className* id: container id* @return {*}*/function AnimationText(props) {const { paragraphArrays, paragraphClassName, className, id } = props || {}let elementuseEffect(() => {element = document.getElementById(id || 'animationText')}, [])useEffect(() => {if (element) {let count = 0for (let i = 0; i < paragraphArrays.length; i += 1) {for (let j = 0; j < paragraphArrays[i].length; j += 1) {count += 1setTimeout(() => {const ele = document.getElementById(`${i}-${j}-${id || 'animationText'}`)ele.setAttribute('class', styles.nodeItemShow)}, 600 * count)}}}}, [element])return (<div className={classnames(styles.container, className)} id={id || 'animationText'} >{(paragraphArrays || []).map((item, index) => (<div className={classnames(styles.paragraph, paragraphClassName)}>{(item || []).map((component, idx) => (<div id={`${index}-${idx}-${id || 'animationText'}`} className={styles.nodeItem} >{component}</div>))}</div>))}</div>)}export default AnimationText

css:

.container {width: auto;}.paragraph {margin-bottom: 15px;}.nodeItem {opacity: 0;}.nodeItemShow {visibility: visible;animation: scan 3s ease 0s 1;}@keyframes scan {0% {opacity: 0;}100% {opacity: 1;}}

一个简单的 文字一行一行显示出来 动画组件就实现啦

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。