How to detect if screen has rounded corners in react-native - react-native

How can I detect whether device screen has rounded corners and also estimate the radius of the corners (if possible) ?
I want to modify my view more typically cardview to adapt these screens. I have successfully retrieved the screen width and height by using Dimensions
width: Dimensions.get('window').width,
height: Dimensions.get('window').height
I am not able to adapt my parent view according to the curves at 4 corners with above approach. If I give static radius to the parent view it give bad look & feel on rectangular screens and it's not acceptable.
One approach I thought of is generate a list of all devices with rounded corners and apply border radius to only these devices. But it's harder to maintain the list and adapt the list with newcomers in the market.
Can anyone help me with it ? Any sort of approach or guideline will really help me. Thank you in advance

After struggling with it, I came with a much easier solution that why shouldn't I ask user whether he/she has rounded cornered screen when the app starts first time and later giving an option in settings under my app to change whenever user wanted.
I stored user's selection in local storage and modified my view based on that flag. Now I don't have to maintain a list of all devices instead it will cover all use cases.

Currently there is no option to get corner radius from Dimensions. There is only 4 values in Dimensions object given below.
{ width: 384, height: 592, scale: 2, fontScale: 1 }

Even if you have answered and accepted your own answer already, it is not really a solution for the original post.
I think basically all phones with notches have round corners while devices without notches typically do not have round corners. If you have notches, you have an inset in your Safe Area. If you are using react-native-safe-area-context for example, you can get the insets with
const insets = useSafeAreaInsets();
const hasNotch = insets.top || insets.bottom || insets.right || insets.left;

Related

Crop image using a bounding box react-native-camera

i have a camera view in my app in which there is a resizable bounding box
now after taking the image i want to able to only take the part of the image that was focused so i used ImageEditor from this react-native library
the issue i have i am not getting consistent results on the cropping i currently have th following values
boxX staring X position of the bounding box; boxY staring Y position of the bounding box; boxWidth width of the bounding box; boxHeight height of the bounding box.
i used the following code at first
ImageEditor.cropImage(image.uri,
{
offset: {x: boxX, y: boxY},
size: {width: boxWidth, height: boxHeight},
}
)
this gives a very pixalated and very wrong cropping of the image i dont know why, then i added some calculations to it by adding new variables like the image width and height and also the devices width and height and came up with this code:
ImageEditor.cropImage(data.uri,
{
offset: {x: ((boxX)/deviceWidth)*data.width, y:((boxY)/deviceHeight)*data.height},
size: {width: boxWidth/deviceWidth*imageWidth, height: boxHeight/deviceHeight*imageHeight},
}
)
this is much better but the cropping is still wrong on Android but on iOS this seems to work fine and accurate, my question is how can i achieve this please let me know if there is any calculations i should do to get consistent results.
For image cropping I think you should try:
1) https://github.com/ivpusic/react-native-image-crop-picker
It is more used, looks to be maintained better and could simplify your work.
or
2) a picker and https://github.com/prscX/react-native-photo-editor
if you want more complicated editing.
or
3) if you are satisfied with your current library for iOS, use one of the 2 from above only for android.
Note: this is a known issue of the react-native-image-editor, especially for android. The discussions and possible workarounds that could work on some devices can be found here:
https://github.com/callstack/react-native-image-editor/issues/54#issuecomment-754688978

How do you scale images/sprites properly in Godot?

I'm trying to create a 2D cross-platform game (primarily for android & ios in portrait mode, however compatibility with a tablet/desktop would be a bonus) and I'm trying to wrap my head around scaling of my sprites.
I've looked online, and I've ended up setting the following in my Project Settings > Stretch
'Mode' : 2D
'Aspect' : keep-height.
According to https://www.mydevice.io the viewport of my android phone is 360 x 640px (the standard 16:9 ratio for mobiles). But obviously phones/tablet screens come in all sorts of dimensions.
If I wanted to create a sprite with a width exactly 1/3rd of that of my screen/viewport, how should I go about doing this? Should I be creating multiple sprites of various dimensions (in say, GraphicsGale) to account for different screen sizes, or should I be purely doing this scaling in Godot?
I know there's a 'scale' property in Godot, but I can't see a way of setting my image width and height via pixels or by a percentage of the viewport.
Have you tried setting the sprite size depending on the viewport height and width ?
$sprite.size.x = get_viewport().size.x * 0.33
$sprite.size.y = get_viewport().size.y * 0.33
You can check out this reddit post if this is not working.

getUserMedia (Selfie) Full Screen on Mobile

I've the following constraints which are working perfectly fine over Chrome in Desktop (simulating mobile resolution)
const constraints = {
audio: false,
video: {
width: screen.width,
height: screen.height
}
};
navigator.mediaDevices.getUserMedia(constraints).then(stream => {})
However when actually trying this on iPhone / Safari the camera doesn't respects this at all and gets super small or distorted - removing the width / height from the constraints makes it better ratio but not full screen at all, just centralized.
I've also tried with min / max constraints without lucky.
Is there any way to get this working on iPhones?
I have built a few AR Websites which are mobile first. When you request a resolution the web browser sees if the resolution exists, and if it doesn't it then decides if it should emulate the feed for you. Not all browsers do emulation (even though it is part of the spec). This is why it may work in some browsers and not others. Safari won't emulate the resolution you are asking for with the camera you have picked (I presume the front).
You can read more about this here (different problem, but provides a deeper explaination): Why the difference in native camera resolution -vs- getUserMedia on iPad / iOS?
Solution
The way I tackled this is:
Without canvas
Ask for a 720p feed, fallback to 480p feed if 720 gives an over-constrained error. This will work cross-browser.
Have a div element which is 100% width and height, fills the screen, and sets overlay to hidden.
Place the video element connected to the MediaStream inside, make it 100% height of the container. The parent div overlay hidden will in effect crop the sides. There will be no feed distortion.
With canvas
Do not show the video element, use a canvas as the video view. Make the canvas the same size as your screen or the same aspect ratio and use CSS to make it fill the screen (latter is more performant).
Calculate the top, left, width and height variables to draw the video in the canvas (make sure your calculation centers the video). Make sure you do a cover calculation vs fill. The aim is to crop the parts of the video which do not need to be shown (I.e. like the descriptions of various methods in https://css-tricks.com/almanac/properties/o/object-fit) . Example on how to draw video into a canvas here: http://html5doctor.com/video-canvas-magic/
This will give you the same effect of what you are looking for. Production examples of something similar.
https://www.maxfactor.com/vmua/
https://demo.holitionbeauty.com/
P.s. when I get time I can code an example, short on hours this week.
There are a couple of quirks on mobile gUM() you need to know about.
First, if the device is in portrait orientation things work weirdly. You need to swap the width and height. So, let's say you're on a 480x640 device (do those even exist? who cares? it's an example). To get the appropriate size video you need
const constraints = {
audio: false,
video: {
width: screen.height,
height: screen.width
}
};
I can't figure out exactly why it's like this. But it is. On iOS and Android devices.
Second, it's hard to get the cameras to deliver exactly the same resolution as the device screen size. I tweak the width and height to make them divisible by eight and I get a decent result.
Third, I figure the sizes I need by putting a <video ...> tag in my little web app with CSS that makes it fill the browser screen, then querying its size with
const rect = videoElement.getBoundingClientRect()
const width = rect.width > rect.height ? rect.width : rect.height
const height = rect.width > rect.height ? rect.height : rect.width
This makes the mobile browser do the work of figuring out what size you actually need, and adapts nicely to the browser's various toolbars.

Programatically turn screen upside-down in react-native

I am building a two player game.
When player A makes a turn, the screen should turn upside down for player seated on the opposite side.
I tried using transform on a View, but think that only works on text.
So I am looking for a solution to either
a. Keep the device orientation, but turn it upside down by 180 degrees.
b. Rotate the root view on my app by 180 degrees
I would appreciate suggestions.
Correction - turning the view using transform worked for me.
It was merely not working when in storyboard mode (not sure why).
Below works!
const rotateView = {
flex: 1,
transform: [{
rotate: '-180deg'
}],
}
View is rotated by 180 degrees.

React Native best practice for positioning, favor percentages and calculations over flex?

Coming from a web background it would be considered bad practice to (or not possible) to absolutely position elements and calculate their position in a layout based on the window dimensions. In react-native, we have access to the dimensions of the view port through the React.Dimensions.
For example: let {height, width} = Dimensions.get('window')
I can now use that to center a 100px element by setting it so:
left: (width/2) - 50
I much prefer this to using more traditional css techniques. Is there a reason why this shouldn't be done? In a browser the viewport could change if the user resizes the window, but on mobile the viewport size will be static.
In my opinion, favor the declarative and dynamic solution when possible (flex over number calculations). But it's a mix of both eventually for a lot of apps.
This blog post compares some layout methods in react native and could help you with better understanding when to use what.