From d352cbbf88e25c872b727e5137fdb211e80b4117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=BCleyman=20Yasir=20KULA?= Date: Sat, 10 Apr 2021 14:29:30 +0300 Subject: [PATCH] Plugin now supports mobile screens with cutouts at the top --- .../Resources/ImageCropper.prefab | 91 ++++++++++++++++++- .../ImageCropper/Scripts/NotchCompensator.cs | 86 ++++++++++++++++++ .../Scripts/NotchCompensator.cs.meta | 12 +++ package.json | 2 +- 4 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 Plugins/ImageCropper/Scripts/NotchCompensator.cs create mode 100644 Plugins/ImageCropper/Scripts/NotchCompensator.cs.meta diff --git a/Plugins/ImageCropper/Resources/ImageCropper.prefab b/Plugins/ImageCropper/Resources/ImageCropper.prefab index ea64c42..b35e64c 100644 --- a/Plugins/ImageCropper/Resources/ImageCropper.prefab +++ b/Plugins/ImageCropper/Resources/ImageCropper.prefab @@ -11,6 +11,23 @@ Prefab: m_ParentPrefab: {fileID: 0} m_RootGameObject: {fileID: 1448628512259654} m_IsPrefabParent: 1 +--- !u!1 &1003987235598816 +GameObject: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + serializedVersion: 5 + m_Component: + - component: {fileID: 224641587912896608} + - component: {fileID: 222099147780825774} + - component: {fileID: 114441583655136190} + m_Layer: 5 + m_Name: NotchBackground + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 --- !u!1 &1030790067843440 GameObject: m_ObjectHideFlags: 1 @@ -166,6 +183,7 @@ GameObject: - component: {fileID: 114413964075013978} - component: {fileID: 222276492554401868} - component: {fileID: 114770838951270700} + - component: {fileID: 114406915835164700} m_Layer: 5 m_Name: Canvas m_TagString: Untagged @@ -1452,6 +1470,21 @@ MonoBehaviour: m_FillAmount: 1 m_FillClockwise: 1 m_FillOrigin: 0 +--- !u!114 &114406915835164700 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1195633223483760} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e8515777b12faab4aa32d26f9037af5c, type: 3} + m_Name: + m_EditorClassIdentifier: + avoidScreenCutout: 1 + buttons: {fileID: 224704235191488630} + viewport: {fileID: 224551337473686612} + notchBackground: {fileID: 114441583655136190} --- !u!114 &114413964075013978 MonoBehaviour: m_ObjectHideFlags: 1 @@ -1515,6 +1548,33 @@ MonoBehaviour: m_VerticalOverflow: 0 m_LineSpacing: 1 m_Text: Cancel +--- !u!114 &114441583655136190 +MonoBehaviour: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1003987235598816} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.10588236, g: 0.10588236, b: 0.10588236, a: 1} + m_RaycastTarget: 0 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, + Version=1.0.0.0, Culture=neutral, PublicKeyToken=null + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 --- !u!114 &114444465039278626 MonoBehaviour: m_ObjectHideFlags: 1 @@ -2460,6 +2520,12 @@ CanvasRenderer: m_PrefabParentObject: {fileID: 0} m_PrefabInternal: {fileID: 100100000} m_GameObject: {fileID: 1030790067843440} +--- !u!222 &222099147780825774 +CanvasRenderer: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1003987235598816} --- !u!222 &222183074754662218 CanvasRenderer: m_ObjectHideFlags: 1 @@ -2663,7 +2729,7 @@ Canvas: m_Enabled: 1 serializedVersion: 3 m_RenderMode: 2 - m_Camera: {fileID: 0} + m_Camera: {fileID: 20718564225388336} m_PlaneDistance: 100 m_PixelPerfect: 0 m_ReceivesEvents: 1 @@ -3033,7 +3099,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: -5000, y: -5000} + m_AnchoredPosition: {x: -100, y: -100} m_SizeDelta: {x: 512, y: 512} m_Pivot: {x: 0.5, y: 0.5} --- !u!224 &224511230723951244 @@ -3183,6 +3249,7 @@ RectTransform: m_LocalScale: {x: 0, y: 0, z: 0} m_Children: - {fileID: 224551337473686612} + - {fileID: 224641587912896608} - {fileID: 224704235191488630} m_Father: {fileID: 4226976008158634} m_RootOrder: 0 @@ -3210,6 +3277,24 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!224 &224641587912896608 +RectTransform: + m_ObjectHideFlags: 1 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 100100000} + m_GameObject: {fileID: 1003987235598816} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 224630300329585382} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 100} + m_Pivot: {x: 0.5, y: 1} --- !u!224 &224658208608280252 RectTransform: m_ObjectHideFlags: 1 @@ -3260,7 +3345,7 @@ RectTransform: - {fileID: 224183418109822420} - {fileID: 224691360249124054} m_Father: {fileID: 224630300329585382} - m_RootOrder: 1 + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0.9} m_AnchorMax: {x: 1, y: 1} diff --git a/Plugins/ImageCropper/Scripts/NotchCompensator.cs b/Plugins/ImageCropper/Scripts/NotchCompensator.cs new file mode 100644 index 0000000..77cf6bf --- /dev/null +++ b/Plugins/ImageCropper/Scripts/NotchCompensator.cs @@ -0,0 +1,86 @@ +using UnityEngine; +using UnityEngine.UI; +#if UNITY_EDITOR && UNITY_2021_1_OR_NEWER +using Screen = UnityEngine.Device.Screen; // To support Device Simulator on Unity 2021.1+ +#endif + +namespace ImageCropperNamespace +{ + public class NotchCompensator : MonoBehaviour + { +#if UNITY_EDITOR || UNITY_ANDROID || UNITY_IOS +#pragma warning disable 0649 + [SerializeField] + [Tooltip( "If enabled, on Android and iOS devices with notch screens, top buttons will be repositioned so that the cutout(s) don't obscure them" )] + private bool avoidScreenCutout = true; + + [SerializeField] + private RectTransform buttons; + [SerializeField] + private RectTransform viewport; + [SerializeField] + private Image notchBackground; +#pragma warning restore 0649 + +#pragma warning disable 0414 + private RectTransform canvasTR; +#pragma warning restore 0414 + + private bool screenDimensionsChanged = true; + + private void Awake() + { + canvasTR = (RectTransform) transform; + } + + // Window is resized, update the list + private void OnRectTransformDimensionsChange() + { + screenDimensionsChanged = true; + } + + private void LateUpdate() + { + if( screenDimensionsChanged ) + { + CheckScreenCutout(); + screenDimensionsChanged = false; + } + } + + // If a cutout is intersecting with the buttons at the top on notch screens, shift these buttons downwards + private void CheckScreenCutout() + { + if( !avoidScreenCutout ) + return; + +#if UNITY_2017_2_OR_NEWER && ( UNITY_EDITOR || UNITY_ANDROID || UNITY_IOS ) + // Check if there is a cutout at the top of the screen + int screenHeight = Screen.height; + float safeYMax = Screen.safeArea.yMax; + if( safeYMax < screenHeight - 1 ) // 1: a small threshold + { + // There is a cutout, shift the top buttons downwards + float cutoutPercentage = ( screenHeight - safeYMax ) / Screen.height; + float cutoutLocalSize = cutoutPercentage * canvasTR.rect.height; + + buttons.anchoredPosition = new Vector2( 0f, -cutoutLocalSize ); + viewport.sizeDelta = new Vector2( 0f, -cutoutLocalSize ); + notchBackground.rectTransform.sizeDelta = new Vector2( 0f, cutoutLocalSize + 5f ); // 5f: to prevent a thin black line from appearing when canvas is scaled with screen size + + if( !notchBackground.enabled ) + notchBackground.enabled = true; + } + else + { + buttons.anchoredPosition = Vector2.zero; + viewport.sizeDelta = Vector2.zero; + + if( notchBackground.enabled ) + notchBackground.enabled = false; + } +#endif + } +#endif + } +} \ No newline at end of file diff --git a/Plugins/ImageCropper/Scripts/NotchCompensator.cs.meta b/Plugins/ImageCropper/Scripts/NotchCompensator.cs.meta new file mode 100644 index 0000000..a4a9cf3 --- /dev/null +++ b/Plugins/ImageCropper/Scripts/NotchCompensator.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e8515777b12faab4aa32d26f9037af5c +timeCreated: 1617958394 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/package.json b/package.json index ac84441..230de3f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.yasirkula.imagecropper", "displayName": "Image Cropper", - "version": "1.0.1", + "version": "1.0.2", "documentationUrl": "https://github.com/yasirkula/UnityImageCropper", "changelogUrl": "https://github.com/yasirkula/UnityImageCropper/releases", "licensesUrl": "https://github.com/yasirkula/UnityImageCropper/blob/master/LICENSE.txt",