React native: transparent view inside opaque view - javascript

I want to show view from camera with opaque frame and transparent center. Something like in the picture (black part is a view from camera). I'm looking for solution with pure react-native components, no additional libs (like https://github.com/gilbox/react-native-masked-view), without adding fullscreen image with transparent center or other hacks.

I found simple solution, I added View, transparent inside with opaque border, something like this:
let {width, height} = Dimensions.get('window');
<View
style={{
position: 'absolute',
top: -width/2 + 100,
left: -width/2 + 50,
right: -width/2 + 50,
bottom: -width/2 + 200,
backgroundColor: 'transparent',
borderWidth: width/2,
borderRadius: width,
borderColor: 'red',
opacity: 0.3,
}}
/>

Related

How to smoothly rotate line without interpolate method on React-Native

I have a line on the middle of my screen, that works with Accelerometer and moves this top or bottom and also supposed to rotate. I am using LayoutAnimation, but seems like this method doesn't allow me to rotate my line smoothly, it goes well with 'top' property, but it's not working with rotation
I've tried to install react-native-canvas, but this package wrecks my app at all so I have to recreate it ;D (it pissed me off).
Also I tried to make this animation with interpolate, but it seems like working for fixed degrees and looks weird
componentDidMount(){
setUpdateIntervalForType(SensorTypes.accelerometer, 150);
const subscription = accelerometer.subscribe(({ x, y, z }) =>{
let d = getAngles(x,y,z);
this.updateValues(d.roll,d.pitch);
}
);
}
updateValues(roll,pitch){
LayoutAnimation.configureNext(CustomLayoutAnimation)
this.setState({roll,pitch})
}
render() {
return (
...
{<View style={{position:"relative",top:calculateOffset(this.state.roll,this.state.screenOffset)+"%",width:"80%",height:4,backgroundColor:"orange",transform:[{rotate:`${this.state.pitch}deg`}]}} />}
...
);
}
I'm on search for some working package to work with or way to solve this problem.
Try this:
<View
style={{
position:"relative",
top: calculateOffset(this.state.roll,this.state.screenOffset)+"%",
width: "80%",
height: "80%",
backgroundColor: "transparent",
justifyContent: "center",
transform:[{rotate:`${this.state.pitch}deg`}]}}
}}
>
<View
style={{
height: 4,
backgroundColor: "orange",
width: "100%"
}}
/>
</View>
I hope it help you.
I resolved this with interpolation and Animated API.
It looks weird though, but works ;)

React native / expo app: how to make a diagonal background?

I'm building an availability calendar in our app and for days that have check-ins and check-outs (which happen at 12:00PM) I wish to show the calendar day either half green or half right, like this:
With CSS, currently, we achieve this effect like this:
linear-gradient(to bottom right, #beffbe 50%, #ffbdc2 51%)
What would be the best way of implementing this?
I'm using expo so maybe something involving <LinearGradient> ?
Don't know if this is the best solution, but you can achieve this effect by adding a bordered <View /> as a sibling of your content:
import { Dimensions } from 'react-native';
const { width } = Dimensions.get('window');
render() {
(...)
<View style={{
borderRightWidth: width,
borderRightColor: 'red',
borderTopWidth: width,
borderTopColor: 'green',
position: 'absolute',
opacity: 0.5
}} />
[Your content goes here]
(...)
}
Hope it helps

How to make React Native's ScrollView initial zoom to not be 1?

I want to put content (multiple images vertically arranged) in a React Native ScrollView (iOS only for now, Android will come later) that is bigger than the phone's screen, and start zoomed out so that it is all visible at the same time.
Are there any good examples of using ScrollView.scrollResponderZoomTo in a componentDidMount call that zooms out to fit content in the screen, something like
<ScrollView
style={{width: 500, height: 1000}}
// + whatever other properties make this work required way
>
<View style={{width: 2000, height: 5000}}>
<Image style={{width: 2000, height: 2000}} source={.....}/>
<Image style={{width: 2000, height: 3000}} source={.....}/>
</View>
</ScrollView>
I tried setting the 'zoomScale' property, but that seems to be ignored and always uses the value 1.
According to this issue (https://github.com/facebook/react-native/issues/2176) there is a scrollResponderZoomTo function that can be used, but when I try to use it, it seems that no matter what values I give it it zooms out much too far and off center.
The F8 sample app has a ZoomableImage module (https://github.com/fbsamples/f8app/blob/b5df451259897d1838933f01ad4596784325c2ad/js/tabs/maps/ZoomableImage.js) which uses the Image.resizeMode.contain style to make an image fit the screen, but that loses the quality of image, so when you zoom in it gets blurry.
This may not be the way you intended to do this, but a possible solution:
You may get the devices height and width (var {height, width} = Dimensions.get('window')) and you know your image sizes,so you may easily calculate the needed width and height, let's call them var neededWidth, neededHeight;. You may then calculate the zoom to which you would like to zoom out: var zoom = Math.min(height / neededHeight, width / neededWidth);.
With these values in place, you may set an Animated value for the zoom, starting at 1 ending at zoom like this in your componentWillMount:
Animated.timing(
this.state.animatedZoom,
{toValue: zoom}
).start();
The constructor would look like this:
constructor(props) {
super(props);
this.state = {
animatedZoom: new Animated.Value(1),
};
}
The render function would look like this (reference for transform can be found here):
<ScrollView
style={{width: 500, height: 1000, transform: [{ scale: this.state.animatedZoom }]}}
>
<View style={{width: 2000, height: 5000}}>
<Image style={{width: 2000, height: 2000}} source={.....}/>
<Image style={{width: 2000, height: 3000}} source={.....}/>
</View>
</ScrollView>
I found a way to control the zoom programatically. Let's say you want to set the default zoom level when the scrollview mounts. You can use the method scrollResponderZoomTo of the ScrollView's scroll responder with a timeout.
setScrollViewRef = (ref) => {
this.mapScrollView = ref;
setTimeout(() => {
this.mapScrollView._scrollResponder.scrollResponderZoomTo({
height: this.mapSize, width: this.mapSize, animated: false,
});
}, 1);
};
And render your scrollview with a contentContainerStyle constraining the size you want.
renderMapView = () => {
this.mapSize = Dimensions.get('window').width * 2;
return (
<ScrollView
style={{ flex: 1 }}
ref={this.setScrollViewRef}
maximumZoomScale={4}
minimumZoomScale={0.5}
contentContainerStyle={{ width: this.mapSize, height: this.mapSize }}
centerContent
>
<Map width={this.mapSize} height={this.mapSize} />
</ScrollView>
);
};
This will set the default zoom level to 50% and let the whole <Map /> be visible. If you want another zoom level, you can provide a different height/width to scrollResponderZoomTo. Only works on iOS.
#Levalis's answer save my day.
scrollResponderZoomTo is currently the best shot in React Native according to this issue #2176
If anyone encounter the "zooms out much too far and off center" problem, try to call scrollResponderZoomTo with the same rect as you set in your style:
// declare image size in styles.js...
image: {
width: <image width>,
height: <image height>
}
// ...and inside your component
this.scrollView._scrollResponder.scrollResponderZoomTo({
height: <image height>, width: <image width>, animated: false,
})

make a view scroll horizontally rather than vertically

I'm struggling to make a scroll view scroll sidewards rather than up and down in titanium. I'll need the solution for both iOS and Android.
var challengesScrollView= Ti.UI.createScrollView({
top: '60%',
height: c1Container.height,
width: '60%',
backgroundColor: 'yellow',
zIndex: 9000,
/* left & right work too */
contentHeight:'auto',
});
challengesScrollView.add(c1Container);
challengesScrollView.add(c2Container);
challengesScrollView.add(c3Container);
mainContainer.add(challengesScrollView);
UPDATE:
my mainContainer is the following:
var mainContainer= Ti.UI.createView({
left: '5%',
right:'5%',
top: '9%',
bottom:'15%',
});
and c1Container is:
var c1Container= Ti.UI.createView({
top:'1%',
width:'70dp',
height: '90dp',
zIndex:20,
left:'10dp',
backgroundColor:'#3b214a',
borderRadius: 5
});
and it contains the following:
var c1PicView= Ti.UI.createView({
width: '55dp',
height: '55dp',
top: '5%',
borderRadius: 5,
//backgroundColor:'pink',
zIndex:5
});
var c1Pic= Ti.UI.createImageView({
image:'girl.jpg',
width: c1PicView.width,
height: c1PicView.height,
zIndex:5
});
var cName= 'Mary';
var c1Name=Ti.UI.createLabel({
color: 'white',
text: cName,
font:{fontSize: '14sp'},
top: '60dp'
});
c1Container.add(c1PicView);
c1PicView.add(c1Pic);
c1Container.add(c1Name);
c2 is the same as c1 apart from the name
I'm not sure how to position c1Container, c2Container and c3Container etc. so that they will just add on the view sidewards. I can't give actual pixel, left or right positions because the scroll view could have up to 20 mini containers. All help appreciated
simple thing is that you just need to set layout property to horizontal.
In fact, you can use a ScrollView (and it should work both on iOS and android).
I've just tried this code which works just fine :
var win = Ti.UI.createWindow();
var challengesScrollView = Ti.UI.createScrollView({
top: '60%',
height: '30%',
width: '60%',
backgroundColor: 'yellow',
layout: 'horizontal'
});
win.add(challengesScrollView);
function addView() {
challengesScrollView.add(Ti.UI.createView({
left: '10dp',
width: '100dp',
height: '100dp',
backgroundColor: '#FF0000'
}));
setTimeout(addView, 2000);
}
win.addEventListener('open', addView);
win.open();
This code add a new View to the ScrollView every 2 seconds and, as you wish, the ScrollView's width change every time.
The property layout: 'horizontal' is used to place each view horizontally in the ScrollView. Thus, you don't have to calculate the absolute position of each view.
If this property doesn't solve your issue, maybe you should share more code (for example the construction of your containers). Otherwise, it will be difficult to help you ;)
use Horizontal scroll widget in android
For iOS:
UIScrollView scrolls in different directions depending on its contentSize property. If you make the contentSize's width larger then the actual width of the scroll view, it should scroll horizontally.

Titanium - Textarea within a ScrollView

I am trying to create a textarea box within a scrollview. The problem is that it works in iOS, but in Android, when typing multiple lines within the textarea, I cannot scroll up and down to view what I have typed. I know in native Android that you can provide a maximum number of lines and the scrollbars to allow in the view XML file that allows a scrollable textarea within a scrollview, but is there a way to do something similar or a different way of doing this for Titanium?
Here is the code which I am using:
var win = Ti.UI.createWindow({
title: 'Test',
backgroundColor: 'transparent'
});
var view = Ti.UI.createScrollView({
top: 10,
left: 10,
right: 10,
});
var ta = Ti.UI.createTextArea({
top: 5,
left: 5,
right: 5,
height: 400,
backgroundColor: '#AA8BC9'
});
var btn = Ti.UI.createButton({
top: 800,
left: 10,
right: 10,
width: Ti.UI.FILL,
height: Ti.UI.SIZE,
backgroundColor: 'FF00CC',
text: 'OK'
});
view.add(ta);
view.add(btn);
win.add(view);
win.open();
Kibria, This is the problem in old titanium sdk. I also facing this problem with tableview and scrollview in android. I hope this problem can resolve in new titanium sdk.
The alternative solution is you need to set scrollview layout to vertical. and your TextArea height set to auto and then add your button. In this way your scrollview and textarea works perfect for you.

Categories

Resources