摘要:以前一直投入在中,寫動畫的時候不是用中的,就是依賴像這樣的庫,最近轉向,在得到很多大佬關于動畫的回應,于是決定分享給大家,如有其他見解,非常歡迎在下面評論中交流以下便是本文要分享的創建動畫的幾種方式下面,勒次個特斯大特一特給元素添加是最簡單
以前一直投入在 React Native 中,寫動畫的時候不是用 CSS 中的 transitions / animations,就是依賴像 GreenSock 這樣的庫,最近轉向 Web,在 Tweet 得到很多大佬關于 React Web 動畫 的回應,于是決定分享給大家,如有其他見解,非常歡迎在下面評論中交流
以下便是本文要分享的創建 React 動畫 的幾種方式
CSS animation
JS Style
React Motion
Animated
Velocity React
下面,勒次個特斯大特一特
CSS animation給元素添加 class 是最簡單,最常見的書寫方式。如果你的 app 正在使用 CSS,那么這將是你最愉快的選擇
贊同者: 我們只需修改 opacity 和 transform 這樣的屬性,就可構建基本的動畫,而且,在組件中,我們可以非常容易地通過 state 去更新這些值
反對者:這種方式并不跨平臺,在 React Native 中就不適用,而且,對于較復雜的動畫,這種方式難以控制
接下來,我們通過一個實例來體驗一下這種創建方式:當 input focus 的時候,我們增加它的寬度
首先,我們要創建兩個 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; }
一個是它原始的樣式,一個是它 focus 后的樣式
下面,我們就開始書寫我們的 React 組件
在此,推薦一個 在線的 React VS Code IDE,真的很強大,讀者不想構建自己的 React app,可以在其中檢驗以下代碼的正確性
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(" ")} />
我們有一個 focused 的 state,初始值為 false,我們通過更新該值來創建我們的動畫
在 componentDidMount 中,我們添加兩個監聽器,一個 focus,一個 blur,指定的回調函數都是 focus
focus 方法會獲取之前 focused 的值,并負責切換該值
在 render 中,我們通過 state 來改變 input 的 classNames,從而實現我們的動畫
JS StyleJavaScipt styles 跟 CSS 中的 classes 類似,在 JS 文件中,我們就可以擁有所有邏輯
贊同者:跟 CSS 動畫 一樣,且它的表現更加清晰。它也不失為一個好方法,可以不必依賴任何 CSS
反對者:跟 CSS 動畫 一樣,也是不跨平臺的,且動畫一旦復雜,也難以控制
在下面的實例中,我們將創建一個 input,當用戶輸入時,我們將一個 button 從 disable 轉變為 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", } }
我們有一個 disabled 的 state,初始值為 true
onChange 方法會獲取用戶的輸入,當輸入非空時,就切換 disabled 的值
根據 disabled 的值,確定是否將 buttonEnabled 添加到 button 中
React MotionReact Motion 是 Cheng Lou 書寫的一個非常不錯的開源項目。它的思想是你可以對Motion 組件 進行簡單的樣式設置,然后你就可以在回調函數中通過這些值,享受動畫帶來的樂趣
對于絕大多數的動畫組件,我們往往不希望對動畫屬性(寬高、顏色等)的變化時間做硬編碼處理,react-motion 提供的 spring 函數就是用來解決這一需求的,它可以逼真地模仿真實的物理效果,也就是我們常見的各類緩動效果
下面是一個森破的示例
{ ({ x }) => }
這是官方提供的幾個 demo,真的可以是不看不知道,一看嚇一跳
Chat Heads
Draggable Balls
TodoMVC List Transition
Water Ripples
Draggable List
贊同者:React Motion 可以在 React Web 中使用,也可以在 React Native 中使用,因為它是跨平臺的。其中的 spring 概念最開始對我來說感覺挺陌生,然而上手之后,發現它真的很神奇,并且,它有很詳細的 API
反對者:在某些情況下,他不如純 CSS / JS 動畫,雖然它有不錯的 API,容易上手,但也需要學習成本
為了使用它,首先我們要用 yarn 或 npm 安裝它
yarn add react-motion
在下面的實例中,我們將創建一個 dropdown 菜單,當點擊按鈕時,下拉菜單友好展開
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
我們有一個 height 的 state,初始值為 38,代表 menu 的高度
animate 方法設置 menu 的 height,如果 原 height 為 38,則設置 新 height 為 233,如果 原 height 為 233,則設置 新 height 為 38
在 render 中,我們使用 Motion 組件 包裝整個 p 標簽 列表,將 this.state.height 的當前值設為組件的 height,然后在組件的回調函數中使用該值作為整個下拉的高度
當按鈕被點擊時,我們通過 this.animate 切換下拉的高度
AnimatedAnimated 是基于 React Native 使用的同一個動畫庫建立起來的
它背后的思想是創建聲明式動畫,通過傳遞配置對象來控制動畫
贊同者:跨平臺,它在 React Native 中已經非常穩定,如果你在 React Native 中使用過,那么你將不用再重復學習。其中的 interpolate 是一個神奇的插值函數,我們將在下面看到
反對者:基于 Twitter 的交流,它目前貌似不是 100% 的穩定,在老的瀏覽器中的,存在前綴和性能的問題,而且,它也有學習成本
為了使用 Animated,我們首先還是要用 yarn 或 npm 安裝它
yarn add animated
在下面的實例中,我們將模擬在提交表單成功后顯示的動畫 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) 創建一個值為 0 的類屬性 - animatedValue
創建 animate 方法,處理所有的動畫,首先通過 this.animatedValue.setValue(0) 初始化動畫值,實現的效果就是每次重新執行該動畫,然后調用 Animated.timing,animatedValue 作為第一個參數傳遞,配置對象 作為第二個參數,一個設置最終動畫值,一個設置持續時間,一個設置緩動效果
在 render 中,我們用 interpolate 方法創建 marginLeft 對象,包含 inputRange 和 outputRange 數組,我們使用此對象作為 UI 中 message 的 style 屬性
我們使用 Animated.div 替代默認的 div
我們將 animatedValue 和 marginLeft 作為 Animated.div 的 style 屬性
Velocity ReactVelocity React 是基于已經存在的 Velocity 建立起來的
贊同者:上手容易,API 簡單明了,相對其他庫更易于掌握
反對者:有些不得不克服的問題,比如 componentDidMount 后動畫并沒有真正地起作用等,而且,它不跨平臺
下面是一個森破的示例
首先還是要用 yarn 或 npm 安裝它
yarn add velocity-react
在下面的實例中,我們將創建一個很酷的動畫輸入
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
我們要創建一個可重復使用的組件來滿足每個 letter 的動畫
在這個組件中,我們將 animation 的 opacity 設為 1,marginTop 設為 0,這些值代表著傳入子組件的重寫值,即當組件被創建時,組件的 opacity 會由初始的 0 變為 1,marginTop 會由初始的 100 變為 0,我們還設置了 500 ms 的持續時間,最后值得一提的是 runOnMount 屬性,它的意思是在組件 掛載 或 創建 完后執行該動畫
其中的 onChange 方法會獲取用戶的每次輸入,并創建一個由 VelocityLetter 組成的新數組
在 render 中,我們就使用該數組在 UI 中渲染 letters
總結總的來說,基本的動畫,我會選擇 JS style,復雜的動畫,我更偏向 React Motion。而對于 React Native,我還是堅持使用 Animated,一旦 Animated 成熟,在 Web 中可能也會投入使用,目前,我真的很享受 React Motion
原文鏈接: React Animations in Depth (Nader Dabit)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87263.html
摘要:前端日報精選新特性一覽動畫的種創建方式,每一種都不簡單精讀,和它們在之中的優先級變量作用域與提升變量的生命周期詳解讓完成背景圖加載完畢后顯示之解析的原理中文深入理解筆記改進數組的功能百度外賣前端周刊第期知乎專欄基礎繼承基礎作用域和 2017-08-14 前端日報 精選 ES8 新特性一覽React Web 動畫的 5 種創建方式,每一種都不簡單精讀 React functional s...
摘要:童鞋已經造了個版本。這里很明顯,方案和方案可應對簡單場景如沒有回調等,方案可編程性最大,最靈活,可以適合復雜的動畫場景或者承受復雜的交互場景。主要是那上面的演示和傳統的直接操作的方式對比。注釋里已經寫了這是優化重點。 簡介 transformjs在非react領域用得風生水起,那么react技術棧的同學能用上嗎?答案是可以的。junexie童鞋已經造了個react版本。 動畫實現方式 ...
摘要:前面不短時間持續投入了時間在做應用架構方面的考量一個是冒險進行了一次應用架構的調整另一個是跟進了的進展當然實際上是同一個事情也許錯過的比收獲的還多一些不過能走到現在也算幸運了畢竟單頁面應用還面臨很多不成熟之處國慶長假過去不少現在的想法估計會 前面不短時間持續投入了時間在做 React 應用架構方面的考量一個是冒險進行了一次應用架構的調整, 另一個是跟進了 Redux 的進展當然, 實際...
摘要:圖層信息第一層動畫圖層圖層類型動畫該圖層起始關鍵幀該圖層結束關鍵幀開始第層動畫如何動起來時序圖利用屬性動畫控制進度,每次進度改變通知到每一層,觸發重繪。對于簡單的動畫,在實際使用時性能不太明顯。 本文由云+社區發表作者:paulzeng 導語:Lottie是Airbnb開源的一個面向 iOS、Android、React Native 的動畫庫,可實現非常復雜的動畫,使用也及其簡單,極大...
摘要:快速入門什么是是一個開放源代碼的庫,為呈現的數據提供了視圖渲染。最后,項目根組件應該通過來進行注冊,以便能夠進行打包和正常運行。基本思想是渲染一個立方體,并將觀眾置于中心,隨后移動。表示從指定方向平均照亮所有物體的光源。 React VR 快速入門 什么是React React是一個開放源代碼的JavaScript庫,為HTML呈現的數據提供了視圖渲染。React視圖通常使用指定的像H...
閱讀 2472·2021-11-24 09:39
閱讀 3518·2019-08-30 15:53
閱讀 594·2019-08-29 15:15
閱讀 2903·2019-08-26 13:23
閱讀 3212·2019-08-26 10:48
閱讀 643·2019-08-26 10:31
閱讀 748·2019-08-26 10:30
閱讀 2359·2019-08-23 18:32