Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added border curve style prop ("Squircle" effect - iOS only) #32017

Closed
wants to merge 11 commits into from

Conversation

eric-edouard
Copy link
Contributor

@eric-edouard eric-edouard commented Aug 15, 2021

Summary

Since iOS 13+, it is possible to change the corner curve property on iOS in order to smoothen border radius and make it more "rounded" (also called "squircle")
Here's an article explaining in details what it is.
This property is also built in figma, but currently there is no way to implement this directly with react-native despite it being available natively on iOS.

Many open source react-native libraries were created in order to simulate this behaviour:
react-native-super-ellipse-mask
react-native-squircle-view
react-native-figma-squircle

But they rely on creating an SVG shape with the smoothed corners and masking the view behind. This makes it not very performant (flickering on mounting was a common side-effect)

This PR aims at implementing the property natively.

PR for the docs update: facebook/react-native-website#2785

Changelog

[iOS] [Added] - Added cornerCurve style prop to smoothen the border radius (squircle effect)

Test Plan

We used the RNTester app and added an example with cornerCurve set to 'continuous' (only on iOS).

As the difference is quite subtle, we also made some more tests to better illustrate the difference (these are not in the showcase app):

IMG_0810

We overlapped two views with position: absolute, the one in the background has a red background and has cornerRadius set to false, and the one in the foreground is set to true. We can clearly see where the borders differs on the corners.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 15, 2021
@analysis-bot
Copy link

analysis-bot commented Aug 15, 2021

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: 8fef520

@analysis-bot
Copy link

analysis-bot commented Aug 15, 2021

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 9,244,183 -106,910
android hermes armeabi-v7a 8,756,653 +423,508
android hermes x86 9,688,928 -294,541
android hermes x86_64 9,655,826 -113,017
android jsc arm64-v8a 10,880,255 +214,725
android jsc armeabi-v7a 9,783,974 +472,903
android jsc x86 10,920,388 +142,791
android jsc x86_64 11,528,797 +311,901

Base commit: 8fef520

@eric-edouard eric-edouard marked this pull request as ready for review September 18, 2021 15:16
eric-edouard added a commit to eric-edouard/react-native-website that referenced this pull request Sep 18, 2021
Copy link
Contributor

@janicduplessis janicduplessis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about naming it borderCurve (borderRadiusCurve? cornerCurve? borderRadiusStyle?) with value 'circular' | 'continuous'.

cc @yungsters

RCT_CUSTOM_VIEW_PROPERTY(cornerSmoothing, BOOL, RCTView)
{
if ([RCTConvert BOOL:json]) {
view.layer.cornerCurve = @"continuous";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use kCACornerCurveContinuous / kCACornerCurveCircular

@@ -259,6 +259,14 @@ - (RCTShadowView *)shadowView
view.removeClippedSubviews = json ? [RCTConvert BOOL:json] : defaultView.removeClippedSubviews;
}
}
RCT_CUSTOM_VIEW_PROPERTY(cornerSmoothing, BOOL, RCTView)
{
if ([RCTConvert BOOL:json]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cornerCurve seems to be available on iOS 13+ only. You can add if (@available(iOS 13.0, *)) { so it does nothing on older versions.

@janicduplessis janicduplessis self-assigned this Sep 28, 2021
@react-native-bot react-native-bot added Platform: iOS iOS applications. Type: Enhancement A new feature or enhancement of an existing feature. labels Oct 1, 2021
@yungsters
Copy link
Contributor

What about naming it borderCurve (borderRadiusCurve? cornerCurve? borderRadiusStyle?) with value 'circular' | 'continuous'.

Sounds good to me.

borderCurve: ?('circular' | 'continuous'),

@eric-edouard eric-edouard changed the title Added corner smoothing style prop ("Squircle" effect - iOS only) Added border curve style prop ("Squircle" effect - iOS only) Oct 4, 2021
React/Views/RCTView.h Outdated Show resolved Hide resolved
React/Views/RCTViewManager.m Outdated Show resolved Hide resolved
@eric-edouard
Copy link
Contributor Author

@janicduplessis is it normal that the CI fails here ? Thanks

@janicduplessis
Copy link
Contributor

I think its fine, failures don't seem related to your changes.

LGTM thanks for the PR!!

@yungsters Can you import this?

@facebook-github-bot
Copy link
Contributor

@yungsters has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

@philIip philIip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks so much for working on this! looking real snazzy - just have one change i'd like to be made.

React/Views/RCTViewManager.m Outdated Show resolved Hide resolved
@janicduplessis
Copy link
Contributor

@philIip Could you have a look at this again? seems like all feedback have been addressed.

@eric-edouard
Copy link
Contributor Author

@janicduplessis @philIip quick bump on this one, looks like the ReactNativeViewViewConfig.js doesn't exist anymore + merging with main fails locally with

error: add_cacheinfo failed to refresh for path 'packages/react-native-gradle-plugin/gradlew.bat'; merge aborting.

Any help on what should I do next to get this feature merged? Thanks!

@giautm
Copy link

giautm commented May 7, 2022

I think this commit can help, 7b9490b Just move the change to Libraries/NativeComponent/PlatformBaseViewConfig.js

@eric-edouard
Copy link
Contributor Author

thanks @giautm
@janicduplessis I kept running into merge issues mentioned above so I just opened a fresh PR here: #33783 if you don't mind. This one can safely be closed

facebook-github-bot pushed a commit that referenced this pull request Jul 21, 2022
Summary:
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
NOTE: PR is based on #32017 which went stale for quite a long time but can now safely be closed

![](https://preview.redd.it/nuvl4746ys471.png?width=960&crop=smart&auto=webp&s=084a517a645364ac246b70b7fa8e0f2470cc7af3)

Since iOS 13+, it is possible to change the corner curve property on iOS in order to smoothen border radius and make it more "rounded" (also called "squircle")
Here's an [article](https://medium.com/arthurofbabylon/a-smooth-corner-radius-in-ios-54b80aa2d372) explaining in details what it is.
This property is also built in figma, but currently there is no way to implement this directly with react-native despite it being available natively on iOS.

Many open source react-native libraries were created in order to simulate this behaviour:
[react-native-super-ellipse-mask](https://github.com/everdrone/react-native-super-ellipse-mask)
[react-native-squircle-view](https://github.com/everdrone/react-native-squircle-view)
[react-native-figma-squircle](https://github.com/tienphaw/react-native-figma-squircle)

But they rely on creating an SVG shape with the smoothed corners and masking the view behind. This makes it not very performant (flickering on mounting was a common side-effect)

This PR aims at implementing the property natively.

PR for the docs update: facebook/react-native-website#2785

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[iOS] [Added] - Added `borderCurve` style prop for smooth border radius (squircle effect)

Pull Request resolved: #33783

Test Plan:
We used the RNTester app and added an example with `cornerCurve ` set to `'continuous'` (only on iOS).

As the difference is quite subtle, we also made some more tests to better illustrate the difference (these are not in the RN-tester app):

![IMG_0810](https://user-images.githubusercontent.com/19872411/133893536-26207c53-aade-4583-9eef-7a1739b6907b.PNG)

We overlapped two views with `position: absolute`, the one in the background has a red background and has `cornerRadius` set to `false`, and the one in the foreground is set to `true`. We can clearly see where the borders differs on the corners.

Reviewed By: sammy-SC

Differential Revision: D37883631

Pulled By: cipolleschi

fbshipit-source-id: 09f06de9628fa326323eba63875de30102c4a59e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Needs: React Native Team Attention Platform: iOS iOS applications. Type: Enhancement A new feature or enhancement of an existing feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants