Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/roubachof/Sharpnado.Shadows

Add as many custom shadows (Color, Offset, Blur, Neumorphism) as you like to any Xamarin.Forms view (Android, iOS, UWP).
https://github.com/roubachof/Sharpnado.Shadows

Last synced: about 1 month ago
JSON representation

Add as many custom shadows (Color, Offset, Blur, Neumorphism) as you like to any Xamarin.Forms view (Android, iOS, UWP).

Lists

README

        

# Sharpnado.Shadows

Get it from NuGet:

[![Nuget](https://img.shields.io/nuget/v/Sharpnado.Shadows.svg)](https://www.nuget.org/packages/Sharpnado.Shadows)

| Supported platforms |
|----------------------------|
| :heavy_check_mark: Android |
| :heavy_check_mark: iOS |
| :heavy_check_mark: UWP |
| :heavy_check_mark: Tizen |

![Presentation](Docs/github_banner.png)

## Initialization

* On Core project in `App.xaml.cs`:

For the namespace schema to work, you need to call initializer from App.xaml.cs like this:

```csharp
public App()
{
InitializeComponent();

Sharpnado.Shades.Initializer.Initialize(loggerEnable: false);
...
}
```

* On `iOS` add this line after `Xamarin.Forms.Forms.Init()` and before `LoadApplication(new App())`.

`Sharpnado.Shades.iOS.iOSShadowsRenderer.Initialize();`

* On `UWP`, you must register the renderers assembly like this, before `Xamarin.Forms.Forms.Init()`:

`var rendererAssemblies = new[] { typeof(UWPShadowsRenderer).GetTypeInfo().Assembly }; `

* On `Tizen` add this line after `Xamarin.Forms.Forms.Init()` and before `LoadApplication(new App())`.

`Sharpnado.Shades.Tizen.TizenShadowsRenderer.Initialize();`

## Presentation

Add as **many** **custom** shadows as you like to any `Xamarin.Forms` view (`Android`, `iOS`, `UWP`, `Tizen`).

* You can specify each shadow `Color`, `Opacity`, `BlurRadius`, and `Offset`
* Simply implement `Neumorphism`
* You can add one shadow, 3 shadows, 99 shadows, to any `Xamarin.Forms` element
* Animate any of these property and make the shadows dance around your elements
* No `AndroidX` or `SkiaSharp` dependency required (except Tizen), only `Xamarin.Forms`

## Animating shadows

Rendering `Shadows` is cpu intensive (especially on Android).

**Using Xamarin.Forms animation API whith shadows is totally fine**: it won't recreate the `Shadows` bitmaps.

However, animating the color, blur, opacity or size of a `Shade`, will result in creating **multiple bitmap on Android**.

Therefore if you want to animate the size of a view which is using `Shadows`, you should "disable" the shadows during the animation.

```xml

```

```csharp
private async Task MyViewTotallyFineAnimations()
{
// Nothing to disable here
await MyView.RotateXTo(90);
await MyView.ScaleTo(2);
await MyView.RotateXTo(0);
await MyView.ScaleTo(1);
}

private async Task MyViewNeedsDisableShadowsAnimation()
{
var shades = MyViewShadows.Shades;

// Disabling shadows
MyViewShadows.Shades = new List();

await MyView.AnimateWidthRequestAsync();

// Restoring shadows
MyViewShadows.Shades = shades;
}
```

## Shadows for Xamarin.Forms components creators

`Shadows` has been developed with modularity in mind, making it really easy to integrate into your own components.

Read the wiki doc: https://github.com/roubachof/Sharpnado.Shadows/wiki/Shadows-for-Xamarin.Forms-components-builders.

## Using Shadows

`Shadows` is a container for any `Xamarin.Forms` view.
Just wrap your view in it and start adding shadows:

**XAML**

```xml









```

**OUTPUT**

Thanks to the `CornerRadius` property you can match your target corner to achieve a perfect shadow.
For example, you can add a shadow to a rounded button:

**XAML**

```xml

```

**OUTPUT**

### Choose your Shade Collection

You can use several type of `IEnumerable`:

#### 1. ReadOnlyCollection

This is what you want to use most of the time.
All the different `IMarkupExtension` like `ImmutableShades, NeumorphismShades, SingleShade`, return a `ReadOnlyCollection`.
If you use a `ReadOnlyCollection`, all shades will be cloned to be sure the immutability is respected.
It means, you can specify shades as static objects in your `ResourceDictionary`, it won't create any leak or view hierarchy issues.

```xml

```

#### 2. ObservableCollection

Only if you want to dynamically add or remove shade during the view lifetime.

#### 3. All other IEnumerable

If you want to modify a shade property during the view lifetime.

**IMPORTANT**: if you don't use a `ReadOnlyCollection` please be sure to declare your `Shade` as transient.
It means you should declare a new instance of `Shade` for each `Shadows` views. For example, in code-behind with `new Shade()`, or in xaml with `Shades` property.
Just don't reference static instances of shade from `ResourceDictionary` with `StaticResource` references, or even in a C# class.

### Shades

The `Shadows` component has only 2 properties:

1. `int CornerRadius` which should be equal to the component's child view `CornerRadius` to achieve a good shadow effect,
2. `IEnumerable Shades` which is the enumeration of all the shades this shadow is made of.

A shade is what you could call a "sub-shadow".

Each shade has 4 properties:

1. `Point Offset`: the offset of the shade
2. `Color Color`: the color of the shade
3. `double Opacity`: the opacity of the shade
4. `double BlurRadius`: the amount of blur your want for this shade

**Logo.xaml**

```xml












```

**OUTPUT**

### Neumorphism

To have a nice `Neumorphism` effect we need to choose a background color.
I found that `#F0F0F3` was quite good, so I will stick to it for our content **and** our page background color.

Since `Neumorphism` implementation is made of 2 shadows, one bright at the top left, one dark at the bottom right, achieving a `Neumorphism` style with `Shadows` for all the views is really easy:

```xml

<Setter Property="CornerRadius" Value="10" />
<Setter Property="Shades">
<sh:ImmutableShades>
<sh:Shade BlurRadius="10"
Opacity="1"
Offset="-10,-10"
Color="White" />
<sh:Shade BlurRadius="10"
Opacity="1"
Offset="6, 6"
Color="#19000000" />
</sh:ImmutableShades>
</Setter>

```

If you want to add `Neumorphism` to specific elements a `NeumorphismShades` markup extension will help you with that:

**XAML**

```xml

```

**OUTPUT**

### Be creative!

One last thing: all properties of a `Shade` are animatable.

You can achieve nice effects thinking outside the box!
Have a look at the `BeCreative.xaml` file and its code-behind.

![BeCreative](Docs/nyan_cat.gif)

### Immutable and mutable collections of shades

To have a better control of your shades, `Shadows` provides 2 kinds of `MarkupExtension`:

1. One immutable collection of shades: `ImmutableShades` (readonly type)
2. One mutable collection: `ShadeStack` (observable collection type)

Use the first one if the shade collection will not change and the second one if you want to dynamically add or remove shades.

*Dynamic shades starting with 0 shade.*
```xml






```

#### SingleShade

You can also use the `SingleShade` markup extension if you just have one shadow.
It will remove some xaml elements:

```xml

```

## Performance

**Warning**: be sure to have the latest version of `Shadows` installed. Very big performance improvements (bitmap caching) have been implement in version 1.2.

* On `Android`, shadows are created thanks to `RenderScript`. Bitmaps are cached in a global `BitmapCache`. For a particular color, size and blur, you will only have one instance alive.
* On `iOS`, a `Shade` is implemented with a simple `CALayer`
* On `UWP`, `Shade` is implemented with `SpriteVisual` drop shadows.
* On `Tizen`, `Shade` is implemented with `SkiaSharp`.