本地开发react
Let us build a switch component from scratch.
让我们从头开始构建一个开关组件。
Tools used :
使用的工具 :
- React Native React本机
- React Native Reanimated React原生复活
- Figma 菲格玛
Design level dissection of Switch Component
开关组件的设计层剖析
The components are:
这些组件是:
- A rectangle with a border-radius. 具有边界半径的矩形。
- A circle placed absolute inside it. 在其中绝对放置一个圆。
Let us have a look at the measurements :
让我们来看看测量:
The rectangle dimensions are 50 x 28 with a border-radius of ~36.5px.
矩形尺寸为50 x 28,边框半径为〜36.5px。
The circle has dimensions of 24 x 24 with a fully rounded border-radius.
该圆的尺寸为24 x 24,边框半径为圆形。
设置React Native项目。 (Setting up React Native Project.)
(Skip to next section, if already done..)
( 如果已经完成,请跳到下一部分。 )
Go ahead to this link https://reactnative.dev/docs/environment-setup#docsNav and follow the steps on creating a new react native project.
转到此链接https://reactnative.dev/docs/environment-setup#docsNav,并按照创建新的react native项目的步骤进行操作。
npx react-native init RNSwitch
To start the application run npx react-native run-ios inside your React Native project folder. Open your project in VS Code and head to the file named App.js.And remove the code under the return statement and replace it with:
要启动应用程序,请在您的React Native项目文件夹中运行npx react-native run-ios 。 在VS Code中打开您的项目并转到名为App.js的文件,然后在return语句下删除该代码并将其替换为:
return {
<>
<View>
</View>
<>
}
You have successfully finished creating a project.
您已成功完成创建项目。
Let us start coding now. 💃
现在让我们开始编码。 💃
The Switch Component will look like this :
开关组件将如下所示:
import PropTypes from "prop-types";
import React, { useEffect, useState } from "react";
import { Pressable, StyleSheet } from "react-native";
import Animated, { interpolateColors, spring } from "react-native-reanimated";
const RNSwitch = ({
handleOnPress,
activeTrackColor,
inActiveTrackColor,
thumbColor,
value,
}) => {
const [switchTranslate] = useState(new Animated.Value(0));
useEffect(() => {
if (value) {
spring(switchTranslate, {
toValue: 21,
mass: 1,
damping: 15,
stiffness: 120,
overshootClamping: false,
restSpeedThreshold: 0.001,
restDisplacementThreshold: 0.001,
}).start();
} else {
spring(switchTranslate, {
toValue: 0,
mass: 1,
damping: 15,
stiffness: 120,
overshootClamping: false,
restSpeedThreshold: 0.001,
restDisplacementThreshold: 0.001,
}).start();
}
}, [value, switchTranslate]);
const interpolateBackgroundColor = {
backgroundColor: interpolateColors(switchTranslate, {
inputRange: [0, 22],
outputColorRange: [inActiveTrackColor, activeTrackColor],
}),
};
const memoizedOnSwitchPressCallback = React.useCallback(() => {
handleOnPress(!value);
}, [handleOnPress, value]);
return (
<Pressable onPress={memoizedOnSwitchPressCallback}>
<Animated.View
style={[styles.containerStyle, interpolateBackgroundColor]}
>
<Animated.View
style={[
styles.circleStyle,
{ backgroundColor: thumbColor },
{
transform: [
{
translateX: switchTranslate,
},
],
},
styles.shadowValue,
]}
/>
</Animated.View>
</Pressable>
);
};
const styles = StyleSheet.create({
circleStyle: {
width: 24,
height: 24,
borderRadius: 24,
},
containerStyle: {
width: 50,
paddingVertical: 2,
paddingHorizontal: 2,
borderRadius: 36.5,
},
shadowValue: {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.23,
shadowRadius: 2.62,
elevation: 4,
},
});
RNSwitch.propTypes = {
handleOnPress: PropTypes.func.isRequired,
value: PropTypes.bool.isRequired,
activeTrackColor: PropTypes.string,
inActiveTrackColor: PropTypes.string,
thumbColor: PropTypes.string,
};
RNSwitch.defaultProps = {
activeTrackColor: "#007AFF",
inActiveTrackColor: "#F2F5F7",
thumbColor: "#FFF",
};
export default RNSwitch;
For developers getting confused and going like, “What is exactly happening here?”. Let us break it down.
对于感到困惑和困惑的开发人员,“这里到底发生了什么?”。 让我们分解一下。
Component Structure
组件结构
-
Pressable
可按
Pressable is a Core Component wrapper that can detect various stages of press interactions introduced in the latest version of React Native v0.63.0.
Pressable是一个核心组件包装器,可以检测最新版本的React Native v0.63.0中引入的新闻交互的各个阶段。
This wraps our Animated View which has the dimensions of 50 x 28.
这将包装我们的动画视图,该视图的尺寸为50 x 28。
2. Animated View — Rectangle
2. 动画视图—矩形
3. Animated View — Absolute Positioned Circle
3. 动画视图-绝对定位圆
Animations Breakdown
动画细目
-
Translating the absolute positioned circle on changing the switch state.
在更改开关状态时平移绝对定位的圆。
It is a super simple smooth Spring Animation.
这是一个超级简单的平滑Spring动画。
spring(switchTranslate, {toValue: 0, // Initial for switchState false and 22 for truemass: 1,damping: 15,stiffness: 120,overshootClamping: false,restSpeedThreshold: 0.001,restDisplacementThreshold: 0.001,}).start();
2. Interpolating the switch track color when the Circle View translates.
2. 插值开关轨道颜色当圆视图平移。
const interpolateBackgroundColor = {backgroundColor: interpolateColors(switchTranslate, { inputRange: [0, 22], outputColorRange: [inActiveTrackColor, activeTrackColor], }),};
This is a cool interpolation function that is imported from the react-native reanimated library.
这是一个很酷的插值函数,是从react-native复活的库中导入的。
The color of the track goes from inActiveTrackColor to activeTrackColor when the switchTranslate value animates to 0 and 22.
当switchTranslate值的动画值分别为0和22时,轨道的颜色将从inActiveTrackColor变为activeTrackColor 。
So there you go we have our own simple Switch Component where the animations happen in the UI thread.
因此,您可以使用我们自己的简单Switch Component,在其中在UI线程中进行动画处理。
Let us see how it looks in iOS and Android.
让我们看看它在iOS和Android中的外观。
Woah that looks beautiful 🎉 .
哇好漂亮beautiful。
翻译自: https://medium.com/timeless/react-native-reanimated-switch-83c331af7877
本地开发react
所有评论(0)