Open yaofly2012 opened 1 year ago
更新state方式的动画不可行的,性能太差。如果像ReactJs里那样可以直接操作DOM最好了。
RN提供两种动画系统:
Animated
LayoutAnimated
Animated
怎么理解?
Animated
侧重于输入和输出之间的声明性关系,以及两者之间的可配置变换
Animated
旨在以声明的形式来定义动画的输入与输出,在其中建立一个可配置的变化函数,然后使用start/stop
方法来控制动画按顺序执行
触发方式:
基于时间
用户交互
以声明的形式来定义动画的输入与输出
配置变化函数
使用start/stop
方法来控制动画按顺序执行。
可动画组件:
diffClamp(AnimatedValue, min, max)
Create a new Animated value that is limited between 2 values. It uses the difference between the last value so even if the value is far from the bounds it will start changing when the value starts getting closer again.
(value = clamp(value + diff, min, max))
看来RN官方文档解释实在不知道diffClamp(AnimatedValue, min, max)
是干嘛的。在深入了解前可以先了解CSSclamp(min, val, max)
函数功能。diffClamp
是限制Animated.Value
的范围,不过计算规则稍稍麻烦些:OutputAnimatedValue = clamp(OutputAnimatedValue + diff, min, max)
(diff = CurrentInputAnimatedValue - LastInputAnimatedValue),公式有点抽象,直接贴源码:
diffClamp
const diffClamp = function (
a: AnimatedNode,
min: number,
max: number,
): AnimatedDiffClamp {
return new AnimatedDiffClamp(a, min, max);
};
export default class AnimatedDiffClamp extends AnimatedWithChildren {
constructor(a: AnimatedNode, min: number, max: number) {
super();
this._a = a;
this._min = min;
this._max = max;
this._value = this._lastValue = this._a.__getValue();
}
__getValue(): number {
const value = this._a.__getValue();
const diff = value - this._lastValue;
this._lastValue = value;
this._value = Math.min(Math.max(this._value + diff, this._min), this._max);
return this._value;
}
}
核心就是constructor
和__getValue
方法。输出值this._value
计算基于两个规则:
this._value = this._value + diff
this._value
限制在[min, max]
之间,即:
this._value
小于min
,则this._value = min
;this._value
大于max
,则this._value = max
。举个🌰,假设当前Input是0,对于Animated.diffClamp(Input, 0, 10) 的输出: |
当前Input | 上次Input | Diff(当前Input - 上次Input) | 上次Output | 当前Output | |
---|---|---|---|---|---|---|
1 | 0 | - | - | - | 0 | |
2 | 2 | 0 | 2 | 0 | 2 | |
3 | 8 | 2 | 6 | 2 | 8 | |
4 | 10 | 8 | 2 | 8 | 10 | |
5 | 11 | 10 | 1 | 10 | 10 | |
6 | 20 | 11 | 9 | 10 | 10 | |
7 | 15 | 20 | -5 | 10 | 5 |
第5,6步因为大于最大值10,所以被限制为10。
一般用于实现可折叠导航栏。
Animated.Value
Standard value for driving animations
驱动动画的标准值(即动画过程中变化的值)。一个Animated.Value
可以以同步方式驱动多个属性,但一次只能由一种机制驱动(目前3种)。
mapped to this animated value
Bind opacity to animated value
一个Animated Value可以绑定任意数量的其他属性/其他Animated Value。
Animated.Value
实例对象可以绑定到多个style属性或者其他属性。
Animated.Value
实例对象作为state还是成员变量比较合适?看文档Demo里都是作为成员变量使用,并且只实例化一次。文档里有说明:
Don't modify the animated value directly. You can use the useRef Hook to return a mutable ref object. This ref object's current property is initialized as the given argument and persists throughout the component lifecycle.
Don't modify the animated value directly. It is usually stored as a state variable in class components.
类组件为啥要用state, 可以用作成员变量吗?【可以,本质是要求避免re-render时重新创建】
Animated.Value
利用一个或者多个Animated.Value
产生新的Animated.Value
。
所谓插值就是将一个区间值(inputRange
)映射到一个新的区间值(outputRange
)。
这里需要注意两点:
Issues:
inputRange
和outRange
数组长度必须一致】Animated.timing
Animated.spring
Animated.decay
串行,并行
动画的中间值处理可以通过timing函数生成外,还可通过其他Animated.Value
值生成。
toValue
属性指定类似跟踪动态值,跟踪手势是指直接将滑动、滚动事件产生的变化映射Animated.Value
值。
useNativeDriver
useNativeDriver
?useNativeDriver
?
Using Native Driver for Animated
Value
⚠️⚠️:非必需不要获取当前Value值 。毕竟只有Native知道当前值,要获取当前Value值(在JS层里)必然对性能造成影响。
Animated is designed to be fully serializable
完全通过Plain Object声明动画。这样可将动画信息传给Native并让Native执行。
Issues:
有时候可能会根据Animated.Value
值执行一些操作。可以利用addListener
绑定事件。
All dimensions in React Native are unitless, and represent density-independent pixels
There is no universal mapping from points to physical units of measurement
Density-independent pixels ?
what dimension units are used in React Native?
Size Matters: How I used React Native to make my App look great on every device
https://www.npmjs.com/package/react-native-responsive-dimensions#why-responsive-dimensions
tansform-origin
解决方案:
FlatList
实现sticky头部 TODO头部渲染在哪里?
刚开始利用FlatList. ListHeaderComponent
属性渲染头部。但是快速下拉页面时头部会出现空白区域(TODO 查询下原因)。尝试多种方式,还是放弃了。
目前将头部渲染在FlatList
外部。
用JS可以开发媲美native用户体验的APP。
从此你是个native开发者了。
Issues
TouchableHighlight
和TouchableOpacity
如何选择几个概念
布局:
flex
布局,只支持flexbox布局。相当于容器的display
属性(其实没有display
属性)有且只有一个枚举指flex
。position
**Start
,**End
**Vertical
,**Horizontal
宽高:
“声明”样式: RN里应该是定义样式,只能通过
style
属性定义样式。样式定义是个普通的JS对象。