100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > css实现数字切换动画(封装成React组件)

css实现数字切换动画(封装成React组件)

时间:2018-08-20 04:31:04

相关推荐

css实现数字切换动画(封装成React组件)

背景

最近做项目遇到一个需求,要做选择优惠券后金额试算的一个金额切换的动画效果,如图所示:

然后我把做了几个小demo用于演示:

技术

所用技术为:React.js、css3

本效果用的是CSS3transition属性

transition 属性设置元素当过渡效果,四个简写属性为:

实现

我把0~9的数字全部列出来,排成一列,然后再根据需要展示的数字去对这个数字列进行定位,再利用transition过渡效果实现数字切换动画。

如图所示:

布局

首先是布局代码,将0~9的数字排列出来

<div className="number-animation-wrap"><div className="number-animation-wrap-hidden">0</div><div className="number-animation" style={style}><div className="number">0</div><div className="number">1</div><div className="number">2</div><div className="number">3</div><div className="number">4</div><div className="number">5</div><div className="number">6</div><div className="number">7</div><div className="number">8</div><div className="number">9</div></div></div>

样式

设置样式:

overflow: hidden;超出隐藏

transition: top 0.2s实现过渡动画

@defaultSize: 16;.number-animation-wrap {position: relative;display: inline-block;overflow: hidden;.number-animation {position: absolute;left: 0;top: 0;height: auto;transform-origin: 0 0;transition: top 0.2s;//过渡属性的名称 过渡动画所需的时间}.number,.number-animation-wrap-hidden {line-height: unit((36/@defaultSize),rem);font-size: unit((36/@defaultSize),rem);font-weight: bold;text-align: center;}.number-animation-wrap-hidden{visibility: hidden;}}

控制定位

根据要显示的数字value计算出要偏移的距离,

利用top对布局中的数字列表进行定位,展示对应的数字:

let style = {top: (-1 * value * this.lineHeight / this.defaultSize) + 'rem'}

随着value的变化,动态地生成样式并设置到数字列表div上

<div className="number-animation" style={style}>

调用

我将其封装成了组件,可以很方便的调用,可以根据需要进行组装:

import NumberAnimation from "../../src/numberAnimation";<div style={{textAlign:"center",fontSize: "36px",fontWeight: "bold"}}><div style={{margin:"2rem 0"}}>倒计时 <NumberAnimation value={this.state.number} /></div><div style={{margin:"2rem 0"}}>计时{this.state.number2.toFixed(2).toString().replace(".",":").split("").map((numberItem, index) => {return (<NumberAnimation key={index} value={numberItem} />)})}</div><div style={{margin:"2rem 0"}}>访问人数{this.state.number4.toString().split("").map((numberItem, index) => {return (<NumberAnimation key={index} value={numberItem} />)})}</div><div style={{margin:"2rem 0"}}>{this.state.number.toString().split("").map((numberItem, index) => {return (<NumberAnimation key={index} value={numberItem} />)})}</div><div style={{margin:"2rem 0"}}>{this.state.number2.toFixed(2).toString().split("").map((numberItem, index) => {return (<NumberAnimation key={index} value={numberItem} />)})}</div><div style={{margin:"2rem 0"}}>{this.state.number3.toFixed(2).toString().split("").map((numberItem, index) => {return (<NumberAnimation key={index} value={numberItem} />)})}<button onClick={()=>{this.setState({number3: Math.random()*Math.random()*100})}}> 点击切换数字</button></div></div>

全部代码

js文件

//NumberAnimation.jsimport React, { Component } from 'react';import '../../../less/numberAnimation.less'class NumberAnimation extends Component {constructor(props) {super(props);this.state = {height : 36}}render() {const { value } = this.props;if (isNaN(value)) {//非数字if (value == '.') {return (<div className="number-animation-wrap"><div className="number-animation-wrap-hidden">.</div><div className="number-animation"><div className="number">{value}</div></div></div>)}else {return ''}}let height = document.getElementsByClassName("number").length && document.getElementsByClassName("number")[0].offsetHeight;if(height != this.state.height){this.setState({height : height})}let style = {top: (-1 * value * this.state.height) + 'px'}return (<div className="number-animation-wrap"><div className="number-animation-wrap-hidden">0</div><div className="number-animation" style={style}><div className="number">0</div><div className="number">1</div><div className="number">2</div><div className="number">3</div><div className="number">4</div><div className="number">5</div><div className="number">6</div><div className="number">7</div><div className="number">8</div><div className="number">9</div></div></div>)}}export default NumberAnimation;

样式文件

//style.less@defaultSize: 16;.number-animation-wrap {position: relative;display: inline-block;overflow: hidden;.number-animation {position: absolute;left: 0;top: 0;height: auto;transform-origin: 0 0;transition: top 0.2s;//过渡属性的名称 过渡动画所需的时间}.number,.number-animation-wrap-hidden {line-height: unit((36/@defaultSize),rem);font-size: unit((36/@defaultSize),rem);font-weight: bold;text-align: center;}.number-animation-wrap-hidden{visibility: hidden;}}

调用示例文件

//numberAnimationPage.jsimport React, { Component } from "react";import NumberAnimation from "../../src/numberAnimation";class NumberAnimationPage extends Component {constructor(props) {super(props);this.state = {number: 0,number2: 0,number3: 0};this.number = 0;this.number2 = 0;}componentDidMount() {setInterval(() => {console.log(1)this.setState({number: this.number++,number2: this.number2 += 0.01})}, 1000)}render() {return (<div style={{textAlign:"center"}}><div style={{margin:"2rem 0"}}><NumberAnimation value={this.state.number} /></div><div style={{margin:"2rem 0"}}>{this.state.number.toString().split("").map((numberItem, index) => {return (<NumberAnimation key={index} value={numberItem} />)})}</div><div style={{margin:"2rem 0"}}>{this.state.number2.toFixed(2).toString().split("").map((numberItem, index) => {return (<NumberAnimation key={index} value={numberItem} />)})}</div><div style={{margin:"2rem 0"}}>{this.state.number3.toFixed(2).toString().split("").map((numberItem, index) => {return (<NumberAnimation key={index} value={numberItem} />)})}<button onClick={()=>{this.setState({number3: Math.random()*Math.random()*100})}}> 点击切换数字</button></div></div>);}}module.exports = NumberAnimationPage;

总结

本组件是以单个数字形式进行展示,可以供使用者灵活组装组件中过滤了传入值为非数字的情况,支持用于展示整数、小数

大家有什么建议,或者其他的实现思路,欢迎在评论区分享。

本文链接

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