我正在尝试在React Native中创建一个渐变,当应用程序打开时,它将以一种颜色开始,然后每30秒逐渐变成另一种颜色。常规的线性渐变可以正常工作,无需添加动画。我尝试使用插值和Animated timing,如React Native文档中所示,但似乎没有任何效果。
我的代码:
更新:经过查阅许多不同的资源,我得出结论,唯一实现 LinearGradient 类动画的方法是逐步快速地改变颜色,就像他们的文档中所示。然而,他们的示例是连续的,并且不允许您设置所需的最终颜色。对于我的应用程序,我希望渐变保持一个颜色30秒,然后经过10秒的过渡到下一个颜色渐变,然后重复。例如,它会看起来像这样:红色渐变(30秒),从红色到橙色的过渡(10秒),橙色渐变(30秒),从橙色到绿色的过渡(10秒),等等。
我使用此代码时遇到了两种类型的错误,似乎交替出现。通常,第一个错误是当第一个计时器(30秒)触发时出现的错误:
我的代码:
import React, {Component} from 'react';
import {processColor, AppRegistry, StyleSheet, Dimensions, Animated, Image, Easing, View} from 'react-native';
import TimerMixin from 'react-timer-mixin';
import LinearGradient from 'react-native-linear-gradient';
var screenWidth = Dimensions.get('window').width;
var screenHeight = Dimensions.get('window').height;
//HEX version of colors
var gradientColors = [['#EF2A2A', '#EF6A2A'], //Red
['#EF6A2A', '#EFD82A'], //Orange
['#1BD170', '#61E822'], //Green
['#22D2E6', '#26F084'], //Aqua
['#2A3BEF', '#2ADCEF'], //Blue
['#EF2AD2', '#2A3BEF'], //Purple
['#EF2AD2', '#EF2A2A'] //Pink
]
var gradientColorsNoHash = [['EF2A2A', 'EF6A2A'], //Red
['EF6A2A', 'EFD82A'], //Orange
['1BD170', '61E822'], //Green
['22D2E6', '26F084'], //Aqua
['2A3BEF', '2ADCEF'], //Blue
['EF2AD2', '2A3BEF'], //Purple
['EF2AD2', 'EF2A2A'] //Pink
]
/*var gradientColors = [['ef2a2a', 'ef6a2a'], //Red
['ef6a2a', 'efd82a'], //Orange
['1bd170', '61e822'], //Green
['22d2e6', '26f084'], //Aqua
['2a3bef', '2adcef'], //Blue
['ef2ad2', '2a3bef'], //Purple
['ef2ad2', 'ef2a2a'] //Pink
]*/
//RGBA Version of Colors
/*var gradientColors = [['rgba(239, 42, 42, 1)', 'rgba(239, 106, 42, 1)'], //Red
['rgba(239, 106, 42, 1)', 'rgba(239, 216, 42, 1)'], //Orange
['rgba(0, 221, 103, 1)', 'rgba(97, 232, 35, 1)'], //Green
['rgba(34, 210, 230, 1)', 'rgba(38, 240, 132, 1)'], //Aqua
['rgba(42, 59, 239, 1)', 'rgba(42, 220, 239, 1)'], //Blue
['rgba(239, 42, 210, 1)', 'rgba(42, 59, 239, 1)'], //Purple
['rgba(239, 42, 210, 1)', 'rgba(239, 42, 42, 1)'] //Pink
]*/
function hex(c) {
var s = "0123456789abcdef";
var i = parseInt(c);
if (i == 0 || isNaN(c))
return "00";
i = Math.round(Math.min (Math.max (0, i), 255));
//console.log('hex(c) complete!');
return s.charAt((i - i % 16) / 16) + s.charAt(i % 16);
}
// Convert an RGB triplet to a hex string
function convertToHex (rgb) {
return hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
}
// Convert a hex string to an RGB triplet
function convertToRGB(hex) {
var color = [];
color[0] = parseInt(hex.substring(0, 2), 16);
color[1] = parseInt(hex.substring(2, 4), 16);
color[2] = parseInt(hex.substring(4, 6), 16);
return color;
}
function generateColor(colorStart,colorEnd,colorCount) {
// The beginning of your gradient
var start = convertToRGB(colorStart);
// The end of your gradient
var end = convertToRGB(colorEnd);
// The number of colors to compute
var len = colorCount;
//Alpha blending amount
var alpha = 0.0;
var saida = [];
for (i = 0; i < len; i++) {
var c = [];
alpha += (1.0/len);
c[0] = start[0] * alpha + (1 - alpha) * end[0];
c[1] = start[1] * alpha + (1 - alpha) * end[1];
c[2] = start[2] * alpha + (1 - alpha) * end[2];
saida.push(convertToHex(c));
}
return saida;
}
var number = randomIntFromInterval(0,6)
function randomIntFromInterval(min,max) { return Math.floor(Math.random()*(max-min+1)+min); }
const GradientView = React.createClass({
mixins: [TimerMixin],
getInitialState() {
return {
gradIndex: number,
colorTop: gradientColors[number][0],
colorBottom: gradientColors[number][1],
}
},
componentDidMount() {
this.setInterval(() => {
var count = 0
var topGradArray = generateColor(gradientColorsNoHash[this.state.gradIndex][0],(this.state.gradIndex === 6 ? 0 : gradientColorsNoHash[this.state.gradIndex+1][0] ),770);
var bottomGradArray = generateColor(gradientColorsNoHash[this.state.gradIndex][1],(this.state.gradIndex === 6 ? 0 : gradientColorsNoHash[this.state.gradIndex+1][1] ),770);
console.log('Gradients Made');
var clearId = this.setInterval(() => {
if (count == 0) {
this.setState({ clearId: clearId, gradIndex: ( this.state.gradIndex === 6 ? 0 : this.state.gradIndex+1 ) });
console.log('clearId SET!');
}
this.setState({
colorTop: processColor(topGradArray[count]),
colorBottom: processColor(bottomGradArray[count]),
});
count = count+1
if (count == 769) {
console.log('colorTop and Bottom Saved');
this.clearInterval(this.state.clearId)
}
}, 13);
}, 30000);
},
render(){
return(
<LinearGradient colors={[this.state.colorTop, this.state.colorBottom]}>
<View style={styles.translucentContainer}/>
</LinearGradient>
);
}
});
const styles = StyleSheet.create({
translucentContainer: {
width: screenWidth,
height: screenHeight,
backgroundColor: 'white',
opacity: 0.3,
},
});
export default GradientView;
AppRegistry.registerComponent('GradientView', () => GradientView);
更新:经过查阅许多不同的资源,我得出结论,唯一实现 LinearGradient 类动画的方法是逐步快速地改变颜色,就像他们的文档中所示。然而,他们的示例是连续的,并且不允许您设置所需的最终颜色。对于我的应用程序,我希望渐变保持一个颜色30秒,然后经过10秒的过渡到下一个颜色渐变,然后重复。例如,它会看起来像这样:红色渐变(30秒),从红色到橙色的过渡(10秒),橙色渐变(30秒),从橙色到绿色的过渡(10秒),等等。
我使用此代码时遇到了两种类型的错误,似乎交替出现。通常,第一个错误是当第一个计时器(30秒)触发时出现的错误:
当我忽略了那个错误信息后,当同一个定时器再次触发时,出现了这个错误:
此时,我认为错误的源头在于在componentDidMount()
函数中生成颜色时没有正确处理。