I have a wheel that has 8 arcs, when I turn on debugger the arcs rendered correctly:
But when I turn the debugger off, the arcs position is just messed up:
I tried to build a release version and still got the wrong result. Here is my code:
import * as d3Shape from 'd3-shape'
import React, {forwardRef, useEffect, useImperativeHandle, useRef, useState} from 'react'
import {Animated, Dimensions, Image, TouchableOpacity, View} from 'react-native'
import Svg, {G, Path} from 'react-native-svg'
import Images from '~/styles/Images'
import ImageReward from './components/ImageReward'
import {styles} from './styles'
...
const renderPaths = () => {
let paths: any[] = []
for (let i = 0; i < _wheelPaths.length; i++) {
const arc = _wheelPaths[i]
const [x, y] = arc.centroid
const number = arc.value.toString()
paths.push({
index: i,
body: (
<G key={`arc-${i}`}>
<Path d={arc.path} strokeWidth={0} fill={arc.color} />
<G
rotation={angleOffset}
origin={`${x}, ${y}`}
>
{_textRender(x, y, number, i)}
</G>
</G>
),
})
}
paths = paths.sort((a, b) => a.index - b.index)
return paths.map((i) => i.body)
}
...
const _renderSvgWheel = () => {
return (
<View style={styles.container}>
{_renderKnob()}
<Animated.View
style={{...}}>
{props.options.middleImgSource ? (
<Image
source={props.options.middleImgSource}
style={{
position: 'absolute',
width: props.options.innerRadius * 2,
height: props.options.innerRadius * 2,
zIndex: 1,
}}
/>
) : null}
<AnimatedSvg
width={gameScreen}
height={gameScreen}
viewBox={`0 0 ${width} ${width}`}
style={{
transform: [{rotate: `-${angleOffset}deg`}],
margin: 10,
zIndex: 0,
}}>
<G y={width / 2} x={width / 2}>
{renderBulb(_wheelPaths?.length * 2)}
{renderPaths()}
</G>
</AnimatedSvg>
</Animated.View>
</View>
)
}
...
return (
<View style={styles.container}>
<View
style={{
width: width,
justifyContent: 'center',
alignItems: 'center',
}}>
<Animated.View style={styles.content}>{_renderSvgWheel()}</Animated.View>
</View>
{props.options.playButton ? _renderTopToPlay() : null}
</View>
)
As you can see I intended to use paths.sort before return it, just to make sure the index is right, but the problem still there
Related
I'm trying to design an application screen (I used React Navigation) where several images are displayed vertically inside a FlatList. Each image takes up around 90% of the screen, is centered and has some border-radius, to see the other images, the user has to scroll down.
All these things I was able to do myself, the only problem is, when I scroll down the first image, there is a huge empty gap at the top before showing image 2, and when I scroll down again to see image 3, the bottom bit of image 2 is still showing in the upper part of the screen, separated by another huge gap and the bottom of image 3 is cut out of the screen.
What I've been trying to do is to show exactly one full image at a time, and I don't know whether there's something wrong with the scrolling itself, or the styling I applied to the components.
Here's the code:
import {View, FlatList, Image, Dimensions} from 'react-native';
import {pictures} from './pictures.js';
const ImageScreen = () => {
const deviceWidth = Dimensions.get('window').width;
const deviceHeight = Dimensions.get('screen').height;
function renderImages(pictures){
return(
<View style={{ width: deviceWidth, height: deviceHeight, alignItems:'center'}}>
<Image source={{uri: pictures.item.imageId}}
style={{height:'90%',width:'90%', borderRadius:22 }}/>
</View>
);}
return(
<FlatList data={pictures} keyExtractor={(item)=> item.id} renderItem={renderImages}
pagingEnabled={true} />
);
};
export default SightOverview;
please find below code to display list:
import * as React from 'react';
import { View, FlatList, Image, Dimensions } from 'react-native';
const App = () => {
const pictures = [{
imageId: 'https://picsum.photos/id/1/200/300'
}]
const deviceWidth = Dimensions.get('window').width;
const deviceHeight = Dimensions.get('screen').height;
function renderImages({ item }) {
console.log(item)
return (
<View style={{ flex: 1, width: deviceWidth, height: deviceHeight, alignItems: 'center' }}>
<Image source={{ uri: item.imageId }}
style={{ width: deviceWidth * 0.8, height: deviceHeight * 0.5, borderRadius: 22 }} />
</View>
);
}
return (
<View style={{ flex: 1 }}>
<FlatList data={pictures} keyExtractor={(item) => item.id} renderItem={renderImages}
pagingEnabled={true} />
</View>
);
};
export default App;
import statements
import * as React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import Animated from 'react-native-reanimated';
import BottomSheet from 'reanimated-bottom-sheet';
main app function
export default function App() {
const renderContent = () => (
<View
style={{ backgroundColor: 'white', padding: 16, height: 450, }} >
<Text>Swipe down to close</Text>
</View>
const sheetRef = React.useRef(null);
const fall = new Animated.Value(1)
return (
<>
<View
style={{
flex: 1,
backgroundColor: 'papayawhip', alignItems: 'center', justifyContent: 'center',
}}
>
<Button title="Open Bottom Sheet" onPress={() => sheetRef.current.snapTo(0)} />
</View>
continue with bottom sheet code
<BottomSheet
ref={sheetRef}
snapPoints={[200, 0]}
initialSnap={1} borderRadius={20}
renderContent={renderContent}
callbackNode={fall}
enabledGestureInteraction={true}
/>
</>
)
}
I have set enabledGestureInteraction to true but still it is not working
I haven't used reanimated-bottom-sheet before. But looks like there is a problem with snapPoints property. It should be:
snapPoints={[0, 200]}
The package is out of date. I suggest you use this one instead: https://gorhom.github.io/react-native-bottom-sheet/
I'm using it in my project. It's awesome.
The solution I found for this is we have to wrap our components inside GestureHandlerRootView compnent from react-native-gesture-handler and we have to set it's style with flex:1
discussion ref link - https://github.com/gorhom/react-native-bottom-sheet/issues/775
I want to show 6 options per row instead of showing only one option per row.
I'm still new in react-native
Here is the code :
import React from 'react';
import {fromJS} from 'immutable';
import {ScrollView, StyleSheet, TouchableOpacity} from 'react-native';
import {Text} from 'src/components';
import Option from './OptionVariable';
import {checkOption} from 'src/modules/product/helper';
import {margin} from 'src/components/config/spacing';
class AttributeVariable extends React.Component {
onSelectOption = (option) => {
const {onSelectAttribute, attribute} = this.props;
onSelectAttribute(attribute.get('id'), attribute.get('name'), option.get('option'));
};
render() {
const {attribute, meta_data, variations} = this.props;
// Attribute selected
const attributeSelected = meta_data.find(attr => attr.get('id') === attribute.get('id') && attr.get('name') === attribute.get('name'));
return (
<>
<Text>
{attribute.get('name')}: <Text colorSecondary>{attributeSelected ? attributeSelected.get('option') : ''}</Text>
</Text>
<ScrollView
style={styles.attribute}
vertical
showsHorizontalScrollIndicator={false}>
{attribute.get('options').map(option => {
const disabled = meta_data.size === 0 ? false : !checkOption(variations, meta_data, fromJS({
id: attribute.get('id'),
name: attribute.get('name'),
option: option.get('option'),
}));
return (
<TouchableOpacity
activeOpacity={disabled ? 1 : 0}
key={option}
onPress={() => disabled ? {} : this.onSelectOption(option)}
>
<Option
type={attribute.get('type')}
selected={attributeSelected && option.get('option') === attributeSelected.get('option')}
disabled={disabled}
option={option}
/>
</TouchableOpacity>
)
})}
</ScrollView>
</>
);
}
}
const styles = StyleSheet.create({
attribute: {
marginTop: margin.small,
},
});
export default AttributeVariable;
Here is how it looks :
I hope everything is clear to you.
Sorry for my bad english it's not my main language....
Thanks in advance for any help.
you can say in your attribute style:
attribute: {
marginTop: margin.small,
flexDirection: 'row'
},
so it should align in rows instead of columns
That should help you to learn more about styling components in react native: https://facebook.github.io/react-native/docs/flexbox
Try using the Flatlist (instead of ScrollView) component passing the horizontal={true} props.
Like this:
FlatList
horizontal={true}
data={attribute.option}
renderItem={({ item }) => "Pass your component"}
keyExtractor={item => item.id}
/>
UPDATE 2 :
I used View instead of ScrollView with the following styles and it worked just fine..
<View style={[styles.container, ]}
horizontal
style={{AlignContent: 'flex-start', flexDirection: 'row', alignItems: 'flex-start',}}
style={styles.attribute}
showsHorizontalScrollIndicator={false}>
UPDATE 1 :
I solved the problem using this :
container: {
marginTop: margin.small,
flexDirection: 'row-reverse',
position: 'relative',
width: 'auto',
alignSelf: 'stretch',
maxWidth: 29,
height: 29,
marginBottom: margin.big,
borderRadius: borderRadius.base,
borderWidth: 1,
},
I changed the size of option so all of them appear on the same row (not exactly what I want but it works)
If anyone have a better answer please share.
I'm trying to add a gradient to my area chart using react-native-svg-charts from this example: https://github.com/JesperLekland/react-native-svg-charts-examples/blob/master/storybook/stories/area-chart/with-gradient.js.
The code compiles but I get the following error at runtime:
https://imgur.com/nasKm9x (sorry I don't have enough) reputation to post an image yet)
I'm using Expo on my Android phone. I'm fairly new to programming, so I'm not sure what to even try.
import * as shape from 'd3-shape'
import { View } from 'native-base';
import * as React from 'react';
import { AreaChart, Defs, LinearGradient, Path, Stop } from 'react-native-svg-charts'
// import styles from './styles';
class DashboardChart extends React.Component {
render() {
const data = [ 50, 10, 40, 95, 14, 24, 85, 91, 35, 53, 53, 24, 50, 20, 80 ]
const ChartLine = ({line}) => (
<Path
key={'line'}
d={line}
stroke={'rgb(134, 65, 244)'}
fill={'none'}
/>
)
const Gradient = ({ index }) => (
<Defs key={index}>
<LinearGradient id={'gradient'} x1={'0%'} y={'0%'} x2={'0%'} y2={'100%'}>
<Stop offset={'0%'} stopColor="blue" stopOpacity={1}/>
<Stop offset={'100%'} stopColor="white" stopOpacity={1}/>
</LinearGradient>
</Defs>
)
return (
<View>
<AreaChart
style={{ height: 200 }}
data={data}
contentInset={{ top: 40, bottom: 10 }}
curve={shape.curveNatural}
svg={{
fill: 'url(#gradient)'
}}
>
{/* <Grid/> */}
<Gradient/>
<ChartLine/>
</AreaChart>
</View>
);
}
}
export default DashboardChart;
In the example that you linked to the Defs, LinearGradient, and Stop components were imported from react-native-svg. So those components may be undefined in the react-native-svg-charts library, which would explain the error you are seeing.
Try fixing your imports to this (installing react-native-svg if you haven't already):
import { AreaChart } from 'react-native-svg-charts'
import { Defs, LinearGradient, Path, Stop } from 'react-native-svg'
I have the following React-Native code which alerts the user that it was pressed, however it does not respond to anything.
I have tried using different Touchable components but none seem to work, the only one is Button but that's not really what I want, I'm building a slider so a button is not really appropriate for this.
Anyway, here's my code:
import React, {Component} from 'react';
import {View, TouchableWithoutFeedback, Alert, Text} from 'react-native';
import styles from './styles.js';
import LinearGradient from 'react-native-linear-gradient';
export default class BrightnessSlider extends Component {
value: 100;
constructor(...args) {
super(...args);
}
render() {
return (
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}} colors={["#222", "#ddd"]} style={styles.brightnessSliderRunnable}>
<View style={styles.brightnessSliderTrack}>
<TouchableWithoutFeedback onPress={() => Alert.alert("Hello World")}>
<View style={styles.brightnessSliderThumb} />
</TouchableWithoutFeedback>
</View>
</LinearGradient>
)
}
}
and ./styles.js
import {StyleSheet} from "react-native";
export default styles = StyleSheet.create({
brightnessSliderRunnable: {
top: 50,
height: 9,
width: width - 20,
left: 10,
backgroundColor: "#555",
opacity: 1,
elevation: 1,
borderWidth: 0
// position: "absolute"
},
brightnessSliderThumb: {
width: 23,
height: 23,
borderColor: "#888",
// opacity: 1,
borderWidth: 2,
backgroundColor: "#ffffff",
position: "absolute",
top: -7,
borderRadius: 5,
elevation: 2
},
brightnessSliderTrack: {
width: "100%",
elevation: 1,
borderWidth: 0
}
});
Thanks for any help
Questioner's original code.
Solution
Added by questioner's solution.
Change position: absolute to position: relative.
Change your style type made by StyleSheet as below.
Your original.
{...styles.colourContainer, opacity: 100 - this.darkness}
Recommend way.
[styles.colourContainer, {opacity: 100 - this.darkness}]
I tested code and it works well when we touch the white square.
Tested on iOS.
Original App.js.
App.js changed by me.
import React, {Component} from 'react';
import {View, Dimensions, Text} from 'react-native';
import BrightnessSlider from '../components/BrightnessSlider';
import styles from '../components/TempStyle.js';
const d = Dimensions.get('window'),
width = d.width,
height = d.height;
export default class BrightnessSliderTest extends Component {
constructor(...args) {
super(...args);
this.darkness = 0;
this.prevColours = ["#ff0000", "#00ff00", "#0000ff"];
}
render() {
// It is not possible just access the style created by StyleSheet.create(). Do not use StyleSheet.create() or change to flatten the StyleSheet object.
const sty = [styles.colourContainer,{ opacity: 100 - this.darkness}];
return (
<View style={styles.container}>
<View style={sty}>
<View style={styles.toolBar}>
<View style={styles.colourPalette}>
{this.prevColours.map((i, a) => <View key={String(a)} style={[styles.colourTile, {backgroundColor: i}]}/>)}
</View>
{/* <Button title={"Save To Palette"} onTap={this.saveToPalette}>Save</Button> */}
</View>
<BrightnessSlider />
</View>
</View>
);
}
}
Why?
I am not sure how you can use your component in other components. But if you do not have container having enough size can show your component, touch area may not work. That is why I use backgroundColor for container sometimes in testing.
Added after testing full code used in question.
It is not possible just access the style through like spread operator created by StyleSheet.create(). Do not use StyleSheet.create() or change to flatten the StyleSheet object.
And Style can be worked differently from platforms(iOS, Android).