摘要:以前一直投入在中,寫動(dòng)畫的時(shí)候不是用中的,就是依賴像這樣的庫,最近轉(zhuǎn)向,在得到很多大佬關(guān)于動(dòng)畫的回應(yīng),于是決定分享給大家,如有其他見解,非常歡迎在下面評(píng)論中交流以下便是本文要分享的創(chuàng)建動(dòng)畫的幾種方式下面,勒次個(gè)特斯大特一特給元素添加是最簡(jiǎn)單
以前一直投入在 React Native 中,寫動(dòng)畫的時(shí)候不是用 CSS 中的 transitions / animations,就是依賴像 GreenSock 這樣的庫,最近轉(zhuǎn)向 Web,在 Tweet 得到很多大佬關(guān)于 React Web 動(dòng)畫 的回應(yīng),于是決定分享給大家,如有其他見解,非常歡迎在下面評(píng)論中交流
以下便是本文要分享的創(chuàng)建 React 動(dòng)畫 的幾種方式
CSS animation
JS Style
React Motion
Animated
Velocity React
下面,勒次個(gè)特斯大特一特
CSS animation給元素添加 class 是最簡(jiǎn)單,最常見的書寫方式。如果你的 app 正在使用 CSS,那么這將是你最愉快的選擇
贊同者: 我們只需修改 opacity 和 transform 這樣的屬性,就可構(gòu)建基本的動(dòng)畫,而且,在組件中,我們可以非常容易地通過 state 去更新這些值
反對(duì)者:這種方式并不跨平臺(tái),在 React Native 中就不適用,而且,對(duì)于較復(fù)雜的動(dòng)畫,這種方式難以控制
接下來,我們通過一個(gè)實(shí)例來體驗(yàn)一下這種創(chuàng)建方式:當(dāng) input focus 的時(shí)候,我們?cè)黾铀膶挾?/b>
首先,我們要?jiǎng)?chuàng)建兩個(gè) input 要用到的 class
.input { width: 150px; padding: 10px; font-size: 20px; border: none; border-radius: 4px; background-color: #ffffdffffd; transition: width .35s linear; outline: none; } .input-focused { width: 240px; }
一個(gè)是它原始的樣式,一個(gè)是它 focus 后的樣式
下面,我們就開始書寫我們的 React 組件
在此,推薦一個(gè) 在線的 React VS Code IDE,真的很強(qiáng)大,讀者不想構(gòu)建自己的 React app,可以在其中檢驗(yàn)以下代碼的正確性
class App extends Component { state = { focused: false, } componentDidMount() { this._input.addEventListener("focus", this.focus); this._input.addEventListener("blur", this.focus); } focus = () => { this.setState(prevState => ({ focused: !prevState.focused, })); } render() { return (); } }this._input = input} className={["input", this.state.focused && "input-focused"].join(" ")} />
我們有一個(gè) focused 的 state,初始值為 false,我們通過更新該值來創(chuàng)建我們的動(dòng)畫
在 componentDidMount 中,我們添加兩個(gè)監(jiān)聽器,一個(gè) focus,一個(gè) blur,指定的回調(diào)函數(shù)都是 focus
focus 方法會(huì)獲取之前 focused 的值,并負(fù)責(zé)切換該值
在 render 中,我們通過 state 來改變 input 的 classNames,從而實(shí)現(xiàn)我們的動(dòng)畫
JS StyleJavaScipt styles 跟 CSS 中的 classes 類似,在 JS 文件中,我們就可以擁有所有邏輯
贊同者:跟 CSS 動(dòng)畫 一樣,且它的表現(xiàn)更加清晰。它也不失為一個(gè)好方法,可以不必依賴任何 CSS
反對(duì)者:跟 CSS 動(dòng)畫 一樣,也是不跨平臺(tái)的,且動(dòng)畫一旦復(fù)雜,也難以控制
在下面的實(shí)例中,我們將創(chuàng)建一個(gè) input,當(dāng)用戶輸入時(shí),我們將一個(gè) button 從 disable 轉(zhuǎn)變?yōu)?enable
class App extends Component { state = { disabled: true, } onChange = (e) => { const length = e.target.value.length; if (length > 0) { this.setState({ disabled: false }); } else { this.setState({ disabled: true }); } } render() { const { disabled } = this.state; const label = disabled ? "Disabled" : "Submit"; return (); } } const styles = { App: { display: "flex", justifyContent: "left", }, input: { marginRight: 10, padding: 10, width: 190, fontSize: 20, border: "none", backgroundColor: "#ffffd", outline: "none", }, button: { width: 90, height: 43, fontSize: 17, border: "none", borderRadius: 4, transition: ".25s all", cursor: "pointer", }, buttonEnabled: { width: 120, backgroundColor: "#ffc107", } }
我們有一個(gè) disabled 的 state,初始值為 true
onChange 方法會(huì)獲取用戶的輸入,當(dāng)輸入非空時(shí),就切換 disabled 的值
根據(jù) disabled 的值,確定是否將 buttonEnabled 添加到 button 中
React MotionReact Motion 是 Cheng Lou 書寫的一個(gè)非常不錯(cuò)的開源項(xiàng)目。它的思想是你可以對(duì)Motion 組件 進(jìn)行簡(jiǎn)單的樣式設(shè)置,然后你就可以在回調(diào)函數(shù)中通過這些值,享受動(dòng)畫帶來的樂趣
對(duì)于絕大多數(shù)的動(dòng)畫組件,我們往往不希望對(duì)動(dòng)畫屬性(寬高、顏色等)的變化時(shí)間做硬編碼處理,react-motion 提供的 spring 函數(shù)就是用來解決這一需求的,它可以逼真地模仿真實(shí)的物理效果,也就是我們常見的各類緩動(dòng)效果
下面是一個(gè)森破的示例
{ ({ x }) => }
這是官方提供的幾個(gè) demo,真的可以是不看不知道,一看嚇一跳
Chat Heads
Draggable Balls
TodoMVC List Transition
Water Ripples
Draggable List
贊同者:React Motion 可以在 React Web 中使用,也可以在 React Native 中使用,因?yàn)樗强缙脚_(tái)的。其中的 spring 概念最開始對(duì)我來說感覺挺陌生,然而上手之后,發(fā)現(xiàn)它真的很神奇,并且,它有很詳細(xì)的 API
反對(duì)者:在某些情況下,他不如純 CSS / JS 動(dòng)畫,雖然它有不錯(cuò)的 API,容易上手,但也需要學(xué)習(xí)成本
為了使用它,首先我們要用 yarn 或 npm 安裝它
yarn add react-motion
在下面的實(shí)例中,我們將創(chuàng)建一個(gè) dropdown 菜單,當(dāng)點(diǎn)擊按鈕時(shí),下拉菜單友好展開
class App extends Component { state = { height: 38, } animate = () => { this.setState((state) => ({ height: state.height === 233 ? 38 : 233 })); } render() { return (); } } const styles = { menu: { marginTop: 20, width: 300, border: "2px solid #ffffd", overflow: "hidden", }, button: { display: "flex", width: 200, height: 45, justifyContent: "center", alignItems: "center", border: "none", borderRadius: 4, backgroundColor: "#ffc107", cursor: "pointer", }, selection: { margin: 0, padding: 10, borderBottom: "1px solid #ededed", }, }Animate{ ({ height }) => }Selection 1
Selection 2
Selection 3
Selection 4
Selection 5
Selection 6
我們從 react-motion 中 import Motion 和 spring
我們有一個(gè) height 的 state,初始值為 38,代表 menu 的高度
animate 方法設(shè)置 menu 的 height,如果 原 height 為 38,則設(shè)置 新 height 為 233,如果 原 height 為 233,則設(shè)置 新 height 為 38
在 render 中,我們使用 Motion 組件 包裝整個(gè) p 標(biāo)簽 列表,將 this.state.height 的當(dāng)前值設(shè)為組件的 height,然后在組件的回調(diào)函數(shù)中使用該值作為整個(gè)下拉的高度
當(dāng)按鈕被點(diǎn)擊時(shí),我們通過 this.animate 切換下拉的高度
AnimatedAnimated 是基于 React Native 使用的同一個(gè)動(dòng)畫庫建立起來的
它背后的思想是創(chuàng)建聲明式動(dòng)畫,通過傳遞配置對(duì)象來控制動(dòng)畫
贊同者:跨平臺(tái),它在 React Native 中已經(jīng)非常穩(wěn)定,如果你在 React Native 中使用過,那么你將不用再重復(fù)學(xué)習(xí)。其中的 interpolate 是一個(gè)神奇的插值函數(shù),我們將在下面看到
反對(duì)者:基于 Twitter 的交流,它目前貌似不是 100% 的穩(wěn)定,在老的瀏覽器中的,存在前綴和性能的問題,而且,它也有學(xué)習(xí)成本
為了使用 Animated,我們首先還是要用 yarn 或 npm 安裝它
yarn add animated
在下面的實(shí)例中,我們將模擬在提交表單成功后顯示的動(dòng)畫 message
import Animated from "animated/lib/targets/react-dom"; import Easing from "animated/lib/Easing"; class AnimatedApp extends Component { animatedValue = new Animated.Value(0); animate = () => { this.animatedValue.setValue(0); Animated.timing( this.animatedValue, { toValue: 1, duration: 1000, easing: Easing.elastic(1), } ).start(); } render() { const marginLeft = this.animatedValue.interpolate({ inputRange: [0, 1], outputRange: [-120, 0], }); return (); } } const styles = { button: { display: "flex", width: 125, height: 50, justifyContent: "center", alignItems: "center", border: "none", borderRadius: 4, backgroundColor: "#ffc107", cursor: "pointer", }, box: { display: "inline-block", marginTop: 10, padding: "0.6rem 2rem", fontSize:"0.8rem", border: "1px #eee solid", borderRadius: 4, boxShadow: "0 2px 8px rgba(0,0,0,.2)", }, }AnimateThanks for your submission!
從 animated 中 import Animated 和 Easing
用 new Animated.Value(0) 創(chuàng)建一個(gè)值為 0 的類屬性 - animatedValue
創(chuàng)建 animate 方法,處理所有的動(dòng)畫,首先通過 this.animatedValue.setValue(0) 初始化動(dòng)畫值,實(shí)現(xiàn)的效果就是每次重新執(zhí)行該動(dòng)畫,然后調(diào)用 Animated.timing,animatedValue 作為第一個(gè)參數(shù)傳遞,配置對(duì)象 作為第二個(gè)參數(shù),一個(gè)設(shè)置最終動(dòng)畫值,一個(gè)設(shè)置持續(xù)時(shí)間,一個(gè)設(shè)置緩動(dòng)效果
在 render 中,我們用 interpolate 方法創(chuàng)建 marginLeft 對(duì)象,包含 inputRange 和 outputRange 數(shù)組,我們使用此對(duì)象作為 UI 中 message 的 style 屬性
我們使用 Animated.div 替代默認(rèn)的 div
我們將 animatedValue 和 marginLeft 作為 Animated.div 的 style 屬性
Velocity ReactVelocity React 是基于已經(jīng)存在的 Velocity 建立起來的
贊同者:上手容易,API 簡(jiǎn)單明了,相對(duì)其他庫更易于掌握
反對(duì)者:有些不得不克服的問題,比如 componentDidMount 后動(dòng)畫并沒有真正地起作用等,而且,它不跨平臺(tái)
下面是一個(gè)森破的示例
首先還是要用 yarn 或 npm 安裝它
yarn add velocity-react
在下面的實(shí)例中,我們將創(chuàng)建一個(gè)很酷的動(dòng)畫輸入
import { VelocityComponent } from "velocity-react"; const VelocityLetter = ({ letter }) => () class VelocityApp extends Component { state = { letters: [], } onChange = (e) => { const letters = e.target.value.split(""); const arr = []; letters.forEach((l, i) => { arr.push( {letter}
) }); this.setState({ letters: arr }); } render() { return ( ); } } const styles = { input: { marginBottom: 20, padding: 8, width: 200, height: 40, fontSize: 22, backgroundColor: "#ffffd", border: "none", outline: "none", }, letters: { display: "flex", height: 140, }, letter: { marginTop: 100, fontSize: 22, whiteSpace: "pre", opacity: 0, } }{ this.state.letters }
從 velocity-react 中 import VelocityComponent
我們要?jiǎng)?chuàng)建一個(gè)可重復(fù)使用的組件來滿足每個(gè) letter 的動(dòng)畫
在這個(gè)組件中,我們將 animation 的 opacity 設(shè)為 1,marginTop 設(shè)為 0,這些值代表著傳入子組件的重寫值,即當(dāng)組件被創(chuàng)建時(shí),組件的 opacity 會(huì)由初始的 0 變?yōu)?1,marginTop 會(huì)由初始的 100 變?yōu)?0,我們還設(shè)置了 500 ms 的持續(xù)時(shí)間,最后值得一提的是 runOnMount 屬性,它的意思是在組件 掛載 或 創(chuàng)建 完后執(zhí)行該動(dòng)畫
其中的 onChange 方法會(huì)獲取用戶的每次輸入,并創(chuàng)建一個(gè)由 VelocityLetter 組成的新數(shù)組
在 render 中,我們就使用該數(shù)組在 UI 中渲染 letters
總結(jié)總的來說,基本的動(dòng)畫,我會(huì)選擇 JS style,復(fù)雜的動(dòng)畫,我更偏向 React Motion。而對(duì)于 React Native,我還是堅(jiān)持使用 Animated,一旦 Animated 成熟,在 Web 中可能也會(huì)投入使用,目前,我真的很享受 React Motion
原文鏈接: React Animations in Depth (Nader Dabit)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/87263.html
摘要:前端日?qǐng)?bào)精選新特性一覽動(dòng)畫的種創(chuàng)建方式,每一種都不簡(jiǎn)單精讀,和它們?cè)谥械膬?yōu)先級(jí)變量作用域與提升變量的生命周期詳解讓完成背景圖加載完畢后顯示之解析的原理中文深入理解筆記改進(jìn)數(shù)組的功能百度外賣前端周刊第期知乎專欄基礎(chǔ)繼承基礎(chǔ)作用域和 2017-08-14 前端日?qǐng)?bào) 精選 ES8 新特性一覽React Web 動(dòng)畫的 5 種創(chuàng)建方式,每一種都不簡(jiǎn)單精讀 React functional s...
摘要:童鞋已經(jīng)造了個(gè)版本。這里很明顯,方案和方案可應(yīng)對(duì)簡(jiǎn)單場(chǎng)景如沒有回調(diào)等,方案可編程性最大,最靈活,可以適合復(fù)雜的動(dòng)畫場(chǎng)景或者承受復(fù)雜的交互場(chǎng)景。主要是那上面的演示和傳統(tǒng)的直接操作的方式對(duì)比。注釋里已經(jīng)寫了這是優(yōu)化重點(diǎn)。 簡(jiǎn)介 transformjs在非react領(lǐng)域用得風(fēng)生水起,那么react技術(shù)棧的同學(xué)能用上嗎?答案是可以的。junexie童鞋已經(jīng)造了個(gè)react版本。 動(dòng)畫實(shí)現(xiàn)方式 ...
摘要:前面不短時(shí)間持續(xù)投入了時(shí)間在做應(yīng)用架構(gòu)方面的考量一個(gè)是冒險(xiǎn)進(jìn)行了一次應(yīng)用架構(gòu)的調(diào)整另一個(gè)是跟進(jìn)了的進(jìn)展當(dāng)然實(shí)際上是同一個(gè)事情也許錯(cuò)過的比收獲的還多一些不過能走到現(xiàn)在也算幸運(yùn)了畢竟單頁面應(yīng)用還面臨很多不成熟之處國慶長假過去不少現(xiàn)在的想法估計(jì)會(huì) 前面不短時(shí)間持續(xù)投入了時(shí)間在做 React 應(yīng)用架構(gòu)方面的考量一個(gè)是冒險(xiǎn)進(jìn)行了一次應(yīng)用架構(gòu)的調(diào)整, 另一個(gè)是跟進(jìn)了 Redux 的進(jìn)展當(dāng)然, 實(shí)際...
摘要:圖層信息第一層動(dòng)畫圖層圖層類型動(dòng)畫該圖層起始關(guān)鍵幀該圖層結(jié)束關(guān)鍵幀開始第層動(dòng)畫如何動(dòng)起來時(shí)序圖利用屬性動(dòng)畫控制進(jìn)度,每次進(jìn)度改變通知到每一層,觸發(fā)重繪。對(duì)于簡(jiǎn)單的動(dòng)畫,在實(shí)際使用時(shí)性能不太明顯。 本文由云+社區(qū)發(fā)表作者:paulzeng 導(dǎo)語:Lottie是Airbnb開源的一個(gè)面向 iOS、Android、React Native 的動(dòng)畫庫,可實(shí)現(xiàn)非常復(fù)雜的動(dòng)畫,使用也及其簡(jiǎn)單,極大...
摘要:快速入門什么是是一個(gè)開放源代碼的庫,為呈現(xiàn)的數(shù)據(jù)提供了視圖渲染。最后,項(xiàng)目根組件應(yīng)該通過來進(jìn)行注冊(cè),以便能夠進(jìn)行打包和正常運(yùn)行。基本思想是渲染一個(gè)立方體,并將觀眾置于中心,隨后移動(dòng)。表示從指定方向平均照亮所有物體的光源。 React VR 快速入門 什么是React React是一個(gè)開放源代碼的JavaScript庫,為HTML呈現(xiàn)的數(shù)據(jù)提供了視圖渲染。React視圖通常使用指定的像H...
閱讀 2492·2021-11-24 09:39
閱讀 3536·2019-08-30 15:53
閱讀 610·2019-08-29 15:15
閱讀 2918·2019-08-26 13:23
閱讀 3231·2019-08-26 10:48
閱讀 661·2019-08-26 10:31
閱讀 787·2019-08-26 10:30
閱讀 2377·2019-08-23 18:32