文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
a.js 5.48 KB
一键复制 编辑 原始数据 按行查看 历史
Delli 提交于 6年前 . complete
import React, { Component } from 'react'
import {
Text,
View,
Image,
StyleSheet,
ScrollView,
Dimensions,
Animated,
TouchableOpacity,
findNodeHandle,
UIManager,
Alert,
Easing
} from 'react-native'
import Icon from 'react-native-vector-icons/Ionicons'
let {width, height} = Dimensions.get('window')
export default class BuyCar extends Component{
constructor(props){
super(props)
this.state = {
animateBtnX: 0,
animateBtnY: -999,
addBtnY: -999,
addBtnX:0,
runAnim: new Animated.Value(0),
endX: 26,// 购物车的位置 在距屏幕的左侧26像素
endY: height-44, // 购物车的位置 在距屏幕的底部44像素
curvature: .003, // 动画抛高系数,值越大抛的越高
duration: 800, // 动画运动时间
}
}
// 获取点击坐标XY
getScreenXY(i,item){
const self = this;
const handle = findNodeHandle(this.refs[i]);
UIManager.measure(handle, (x,y,width,height,pageX,pageY) => {
console.log(x,y,width,height,pageX,pageY)
let data=item
let pos= [pageX, pageY, self.state.endX, self.state.endY]
self.setState({
addBtnY: pageY,
addBtnX: pageX
})
self.run(pos,data)
})
}
//运行动画
run(position = [],data = {}){
if(position.length != 4){
return
}
this.state.runAnim.setValue(0)
const { inputRange, outputX, outputY } = this.getPaths(position)
// console.log(inputRange, outputX, outputY)
this.setState({
animateBtnX: this.state.runAnim.interpolate({
inputRange:inputRange, outputRange: outputX
}),
animateBtnY: this.state.runAnim.interpolate({
inputRange:inputRange, outputRange: outputY
})
})
// console.log(this.state.animateBtnX,this.state.animateBtnY)
Animated.timing(this.state.runAnim, {
toValue: inputRange.length,
duration: this.state.duration,
easing: Easing.linear // 缓动函数
}).start(()=>{
this.state.runAnim.setValue(0)
this.setState({
addBtnY: -999,
addBtnX: 0
})
})
}
// 获得路径
getPaths(position){
const [ startX, startY, endX, endY ] = position
const { curvature } = this.state, speed = 500//166.67
let diffX = endX - startX,
diffY = endY - startY;
let b = ( diffY - curvature * diffX * diffX ) / diffX,
start_x = 0,
rate = diffX > 0? 1: -1,
inputRange = [], outputX = [], outputY = [];
let step = () => {
let tangent = 2 * curvature * start_x + b;
start_x = start_x + rate * Math.sqrt(speed / (tangent * tangent + 1));
if ((rate == 1 && start_x > diffX) || (rate == -1 && start_x < diffX)) {
start_x = diffX;
}
let x = start_x, y = curvature * x * x + b * x;
inputRange.push(outputX.length)
outputX.push(x)
outputY.push(y)
if (start_x !== diffX) {
step()
}
}
step()
return { inputRange, outputX, outputY }
}
render(){
return(
<View style={styles.fullScreen}>
<ScrollView style={styles.scrollView}>
{
['美国队长','绿箭侠','超人','蝙蝠侠','蚁人','绿巨人','猫女','钢铁侠','雷神托尔','黑寡妇','鹰眼侠','葫芦娃','孙悟空','牛魔王','哪吒','唐僧'].map((item, i) => {
return(
<View style={styles.addBtn} key={i}>
<TouchableOpacity ref={i} onPress={this.getScreenXY.bind(this,i,item)}>
<Icon name={"ios-add-circle"} size={26} color={"#3190e8"} />
</TouchableOpacity>
<Text style={{fontSize: 14, color: '#333',paddingHorizontal:10}}>{item}</Text>
</View>
)
})
}
</ScrollView>
<Animated.View style={[styles.tmpBtn, {
top:this.state.addBtnY,
left: this.state.addBtnX,
transform: [
{ translateX: this.state.animateBtnX },
{ translateY: this.state.animateBtnY },
]
}]}>
<View style={{width:20, height:20,backgroundColor:"blue", borderRadius: 20}}></View>
</Animated.View>
<View style={{position:'absolute',bottom:0, left:0,width:width,height:60,flexDirection:'row'}}>
<View style={{flex:2,backgroundColor:'#3190e8'}}></View>
<View style={{flex:8,backgroundColor:'#000000'}}></View>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
fullScreen: {
flex:1,
alignItems: "center",
justifyContent: "center",
},
addBtn:{
backgroundColor: "pink",
alignItems: "center",
justifyContent: "center",
flexDirection: 'row',
width:width,
flex:1,
height:30,
marginTop: 10,
// paddingVertical: 10,
},
scrollView:{
marginBottom:60,
},
tmpBtn: {
position: "absolute",
backgroundColor:'red',
width:20,
height:20,
borderRadius:20
}
})
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化