Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions js/project/Fireworks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
'use strict'
import React,{
StyleSheet,
View,
Animated,
Component
} from 'react-native';
import Dimensions from 'Dimensions';

var screenWidth = Dimensions.get('window').width;
var screenHeight = Dimensions.get('window').height;

var COLORS = ['#FF5252', '#FF4081', '#E040FB', '#7C4DFF', '#448AFF', '#40C4FF', '#69F0AE', '#FFFF00', '#FFD740', '#FF6E40'];
var PARTICLE_COUNT = 12;

class SingleFirework extends Component {
constructor(props) {
super(props);
this._mounted = false;
this.riseAnim = new Animated.Value(0);
this.riseOpacity = new Animated.Value(1);
this.particles = [];
for (var i = 0; i < PARTICLE_COUNT; i++) {
this.particles.push({
x: new Animated.Value(0),
y: new Animated.Value(0),
opacity: new Animated.Value(0),
});
}
this.state = {
color: COLORS[Math.floor(Math.random() * COLORS.length)],
originX: Math.random() * (screenWidth - 60) + 30,
targetY: -(Math.random() * screenHeight * 0.3 + screenHeight * 0.15),
};
}

componentDidMount() {
this._mounted = true;
this._delayTimer = setTimeout(() => {
if (this._mounted) {
this._startAnimation();
}
}, this.props.delay || 0);
}

componentWillUnmount() {
this._mounted = false;
if (this._delayTimer) {
clearTimeout(this._delayTimer);
}
if (this._restartTimer) {
clearTimeout(this._restartTimer);
}
}

_resetValues() {
this.riseAnim.setValue(0);
this.riseOpacity.setValue(1);
this.particles.forEach(function(p) {
p.x.setValue(0);
p.y.setValue(0);
p.opacity.setValue(0);
});
}

_startAnimation() {
if (!this._mounted) return;

this._resetValues();

var newColor = COLORS[Math.floor(Math.random() * COLORS.length)];
var newOriginX = Math.random() * (screenWidth - 60) + 30;
var newTargetY = -(Math.random() * screenHeight * 0.3 + screenHeight * 0.15);
this.setState({color: newColor, originX: newOriginX, targetY: newTargetY});

var riseDuration = 800 + Math.random() * 400;

var riseAnimation = Animated.parallel([
Animated.timing(this.riseAnim, {
toValue: 1,
duration: riseDuration,
}),
Animated.timing(this.riseOpacity, {
toValue: 0,
duration: riseDuration,
}),
]);

var explodeAnimations = this.particles.map(function(p, i) {
var angle = (i / PARTICLE_COUNT) * Math.PI * 2;
var distance = 30 + Math.random() * 60;
var dx = Math.cos(angle) * distance;
var dy = Math.sin(angle) * distance;

return Animated.parallel([
Animated.timing(p.x, {toValue: dx, duration: 700}),
Animated.timing(p.y, {toValue: dy + 20, duration: 700}),
Animated.sequence([
Animated.timing(p.opacity, {toValue: 1, duration: 50}),
Animated.timing(p.opacity, {toValue: 0, duration: 650}),
]),
]);
});

var self = this;
Animated.sequence([
riseAnimation,
Animated.parallel(explodeAnimations),
]).start(function() {
if (self._mounted) {
self._restartTimer = setTimeout(function() {
self._startAnimation();
}, Math.random() * 1000 + 500);
}
});
}

render() {
var color = this.state.color;
var originX = this.state.originX;
var targetY = this.state.targetY;

var riseY = this.riseAnim.interpolate({
inputRange: [0, 1],
outputRange: [0, targetY],
});

var particleViews = this.particles.map(function(p, i) {
return (
<Animated.View
key={i}
style={{
position: 'absolute',
width: 5,
height: 5,
borderRadius: 3,
backgroundColor: color,
opacity: p.opacity,
transform: [{translateX: p.x}, {translateY: p.y}],
}}
/>
);
});

return (
<View style={{position: 'absolute', left: originX, bottom: 20}} pointerEvents="none">
<Animated.View style={{
width: 3,
height: 12,
borderRadius: 2,
backgroundColor: color,
opacity: this.riseOpacity,
transform: [{translateY: riseY}],
}} />
<Animated.View style={{
position: 'absolute',
left: 0,
top: 0,
transform: [{translateY: riseY}],
}}>
{particleViews}
</Animated.View>
</View>
);
}
}

export default class Fireworks extends Component {
render() {
return (
<View style={styles.container} pointerEvents="none">
<SingleFirework delay={0} />
<SingleFirework delay={600} />
<SingleFirework delay={1200} />
<SingleFirework delay={1900} />
<SingleFirework delay={2600} />
</View>
);
}
}

var styles = StyleSheet.create({
container: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'transparent',
},
});
44 changes: 41 additions & 3 deletions js/project/MyIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,25 @@ import React,{
TouchableHighlight,
TouchableOpacity,
NavigatorIOS,
Component
Component,
Alert,
AppState
} from 'react-native';
import Swiper from 'react-native-swiper';
import Dimensions from 'Dimensions';
import ServiceType from './serviceType';
import Home from './Home.js';
import Fireworks from './Fireworks.js';
var width = Dimensions.get('window').width;
export default class MyIndex extends Component{
constructor(props){
super(props);

this.state = {

imageurls:[]
}

this._lastAlertDate = null;
this._handleAppStateChange = this._handleAppStateChange.bind(this);
}
banner(urls){

Expand All @@ -44,7 +47,35 @@ export default class MyIndex extends Component{
});

}
_checkDailyReminder(){
var now = new Date();
var hour = now.getHours();
var todayStr = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate();
if (hour === 8 && this._lastAlertDate !== todayStr) {
this._lastAlertDate = todayStr;
Alert.alert(
'新品推荐',
'今日有新产品上线,欢迎前往线下门店选购!',
[{text: '知道了'}]
);
}
}
_handleAppStateChange(appState){
if (appState === 'active') {
this._checkDailyReminder();
}
}
componentDidMount(){
Alert.alert(
'温馨提示',
'本网站正在升级中,部分功能可能暂时无法使用,敬请谅解!',
[{text: '我知道了'}]
);
this._checkDailyReminder();
this._reminderTimer = setInterval(() => {
this._checkDailyReminder();
}, 60000);
AppState.addEventListener('change', this._handleAppStateChange);
fetch('http://api.gujia007.com/v1/flash-data')
.then((res) => {

Expand All @@ -62,6 +93,12 @@ export default class MyIndex extends Component{

}

componentWillUnmount(){
if (this._reminderTimer) {
clearInterval(this._reminderTimer);
}
AppState.removeEventListener('change', this._handleAppStateChange);
}
render() {

let urls = this.state.imageurls;
Expand Down Expand Up @@ -94,6 +131,7 @@ export default class MyIndex extends Component{
<ServiceType navigator={this.props.navigator} navComponent={this.props.navComponent}/>
</ScrollView>

<Fireworks />
</View>
);

Expand Down