Skip to content

Commit

Permalink
Rename modifiers (#431)
Browse files Browse the repository at this point in the history
`haze` and `hazeChild` do not make sense in the new world, and can
confuse developers. This MR renames the modifiers to be clearer from the
name:

- `Modifier.haze` -> `Modifier.hazeBackground`
- `Modifier.hazeChild` -> `Modifier.hazeContent` (ideally this would be
`Modifier.haze` but that is a compatibility nightmare)
  • Loading branch information
chrisbanes authored Dec 2, 2024
1 parent a3d8e68 commit 3745f1b
Show file tree
Hide file tree
Showing 23 changed files with 201 additions and 199 deletions.
8 changes: 4 additions & 4 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ In older versions of Haze (older than v1.0), the Android implementation was alwa

The migration to [GraphicsLayer][graphicslayer] has resulted in Haze now having a single implementation across all platforms, based on the previous Android implementation. This will help minimize platform differences, and bugs.

It goes further though. In v0.7.x and older, Haze is all 'smoke and mirrors'. It draws all of the blurred areas in the `haze` layout node. The `hazeChild` nodes just updates the size, shape, etc, which the `haze` modifier reads, to know where to draw blurred.
It goes further though. In v0.7.x and older, Haze is all 'smoke and mirrors'. It draws all of the blurred areas in the `hazeBackground` layout node. The `hazeContent` nodes just updates the size, shape, etc, which the `hazeBackground` modifier reads, to know where to draw blurred.

With the adoption of [GraphicsLayer][graphicslayer]s, we now have a way to pass 'drawn' content around, meaning that we are no longer bound by the previous restrictions. v1.0 contains a re-written drawing pipeline, where the blurred content is drawn by the `hazeChild`, not the parent. The parent `haze` is now only responsible for drawing the background content into a graphics layer, and putting it somewhere for the children to access.
With the adoption of [GraphicsLayer][graphicslayer]s, we now have a way to pass 'drawn' content around, meaning that we are no longer bound by the previous restrictions. v1.0 contains a re-written drawing pipeline, where the blurred content is drawn by the `hazeContent`, not the parent. The parent `hazeBackground` is now only responsible for drawing the background content into a graphics layer, and putting it somewhere for the children to access.

This fixes a number of long-known issues on Haze, where all were caused by the fact that the blurred area wasn't drawn by the child.

Expand All @@ -31,10 +31,10 @@ Haze works on all versions of Android, but the effect it uses differs based on t

Haze utilizes RenderEffects for blurring, which technically only 'work' when running on Android 12 (SDK Level 31) or above. However, Haze by default does not enable blurring on SDK Level 31 due to [some issues](https://github.com/chrisbanes/haze/issues/77) found in testing, therefore only enables blurring on SDK Level 32 and above.

You can override this by setting the `blurEnabled` property in the `hazeChild` block, like so:
You can override this by setting the `blurEnabled` property in the `hazeContent` block, like so:

```kotlin
Modifier.hazeChild(...) {
Modifier.hazeContent(...) {
// Enable blur everywhere where it is technically possible...
blurEnabled = true
}
Expand Down
6 changes: 3 additions & 3 deletions docs/materials.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Class reference: [CupertinoMaterials](../api/haze-materials/dev.chrisbanes.haze.

### FluentMaterials

These implement 'material' styles similar to those available on Windows platforms. The values used are taken from the WinUI 3 Figma file published by Microsoft.
These implement 'material' styles similar to those available on Windows platforms. The values used are taken from the WinUI 3 Figma file published by Microsoft.

The primary use case for using these is for when aiming for consistency with native UI (i.e. for when mixing Compose Multiplatform content alongside WinUI content).

Expand All @@ -52,10 +52,10 @@ Box {

LargeTopAppBar(
modifier = Modifier
.hazeChild(
.hazeContent(
...
style = HazeMaterials.thin(),
),
)
}
```
```
6 changes: 3 additions & 3 deletions docs/migrating-1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ As we're now using a common implementation on all platforms, the Skia-backed pla

#### 🆕 HazeChildScope

- **What:** We now have a parameter on `Modifier.hazeChild` which allow you to provide a lambda block for controlling all of Haze's styling parameters. It is similar to concept to `Modifier.graphicsLayer { ... }`. See [here](usage.md#hazechildscope) for more information.
- **What:** We now have a parameter on `Modifier.hazeContent` which allow you to provide a lambda block for controlling all of Haze's styling parameters. It is similar to concept to `Modifier.graphicsLayer { ... }`. See [here](usage.md#hazechildscope) for more information.
- **Why:** This has been primarily added to aid animating Haze's styling parameters, in a performant way.

#### Default style functionality on Modifier.haze has been moved
Expand All @@ -52,8 +52,8 @@ This has resulted in Haze now having a single implementation across all platform

### New pipeline

In v0.7 and older, Haze is all 'smoke and mirrors'. It draws all of the blurred areas in the `haze` layout node. The `hazeChild` nodes just update the size, shape, etc, which the `haze` modifier reads, to know where to draw.
In v0.7 and older, Haze is all 'smoke and mirrors'. It draws all of the blurred areas in the `hazeBackground` layout node. The `hazeContent` nodes just update the size, shape, etc, which the `hazeBackground` modifier reads, to know where to draw.

With the adoption of GraphicsLayers, we now have a way to pass 'drawn' content around, meaning that we are no longer bound by the restraints of before. v1.0 contains a re-written drawing pipeline, where the blurred content is drawn by the `hazeChild`, not the parent. The parent `haze` is now only responsible for drawing the background content into a graphics layer, and putting it somewhere for the children to access.
With the adoption of GraphicsLayers, we now have a way to pass 'drawn' content around, meaning that we are no longer bound by the restraints of before. v1.0 contains a re-written drawing pipeline, where the blurred content is drawn by the `hazeContent`, not the parent. The parent `hazeBackground` is now only responsible for drawing the background content into a graphics layer, and putting it somewhere for the children to access.

This fixes a number of long-known issues on Haze, where all were caused by the fact that the blurred area wasn't drawn by the child.
6 changes: 3 additions & 3 deletions docs/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ You can provide an input scale value which determines how much the content is sc

In terms of the performance benefit which scaling provides, it's fairly small. In our Android benchmark tests, using an `inputScale` set to `0.5` reduced the _cost of Haze_ by **5-20%**. You can read more about this below.

!!! abstract "Cost of Haze"
!!! abstract "Cost of Haze"
Just to call out: the percentage that I mentioned is a reduction in the cost of Haze, not the total frame duration. Haze itself introduces a cost, which you can read more about below. The reduction in total frame duration duration will be in the region of 3-5%.

## Benchmarks
Expand All @@ -21,8 +21,8 @@ We currently have 4 benchmark scenarios, each of them is one of the samples in t

- **Scaffold**. The simple example, where the app bar and bottom navigation bar are blurred, with a scrollable list. This example uses rectangular haze areas.
- **Scaffold, with progressive**. Same as Scaffold, but using a progressive blur.
- **Images List**. Each item in the list has it's own `haze` and `hazeChild`. As each item has it's own `haze`, the internal haze state does not change all that much (the list item content moves, but the `hazeChild` doesn't in terms of local coordinates). This is more about multiple testing `RenderNode`s. This example uses rounded rectangle haze areas (i.e. we use `clipPath`).
- **Credit Card**. A simple example, where the user can drag the `hazeChild`. This tests how fast Haze's internal state invalidates and propogates to the `RenderNode`s. This example uses rounded rectangle haze areas like 'Images List'.
- **Images List**. Each item in the list has it's own `hazeBackground` and `hazeContent`. As each item has it's own `hazeBackground`, the internal haze state does not change all that much (the list item content moves, but the `hazeContent` doesn't in terms of local coordinates). This is more about multiple testing `RenderNode`s. This example uses rounded rectangle haze areas (i.e. we use `clipPath`).
- **Credit Card**. A simple example, where the user can drag the `hazeContent`. This tests how fast Haze's internal state invalidates and propogates to the `RenderNode`s. This example uses rounded rectangle haze areas like 'Images List'.

!!! abstract "Test setup"
All of the tests were ran with 16 iterations on a Pixel 6, running the latest version of Android available.
Expand Down
10 changes: 5 additions & 5 deletions docs/recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

Blurring the content behind app bars is a common use case, so how can we use Haze with `Scaffold`? It's pretty much the same as above:

!!! tip "Multiple hazeChilds"
Note: We are using multiple `hazeChild`s in this example. You can actually use an abitrary number of `hazeChild`s.
!!! tip "Multiple hazeContents"
Note: We are using multiple `hazeContent`s in this example. You can actually use an abitrary number of `hazeContent`s.

``` kotlin
val hazeState = remember { HazeState() }
Expand All @@ -15,7 +15,7 @@ Scaffold(
// Need to make app bar transparent to see the content behind
colors = TopAppBarDefaults.largeTopAppBarColors(Color.Transparent),
modifier = Modifier
.hazeChild(state = hazeState)
.hazeContent(state = hazeState)
.fillMaxWidth(),
) {
/* todo */
Expand All @@ -25,7 +25,7 @@ Scaffold(
NavigationBar(
containerColor = Color.Transparent,
modifier = Modifier
.hazeChild(state = hazeState)
.hazeContent(state = hazeState)
.fillMaxWidth(),
) {
/* todo */
Expand All @@ -34,7 +34,7 @@ Scaffold(
) {
LazyVerticalGrid(
modifier = Modifier
.haze(
.hazeBackground(
state = hazeState,
style = HazeDefaults.style(backgroundColor = MaterialTheme.colorScheme.surface),
),
Expand Down
26 changes: 13 additions & 13 deletions docs/usage.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Haze is implemented through two Compose Modifiers: [Modifier.haze](../api/haze/dev.chrisbanes.haze/haze.html) and [Modifier.hazeChild](../api/haze/dev.chrisbanes.haze/haze-child.html).
Haze is implemented through two Compose Modifiers: [Modifier.hazeBackground](../api/haze/dev.chrisbanes.haze/haze-background.html) and [Modifier.hazeContent](../api/haze/dev.chrisbanes.haze/haze-content.html).

The most basic usage would be something like:

Expand All @@ -10,7 +10,7 @@ Box {
modifier = Modifier
.fillMaxSize()
// Pass it the HazeState we stored above
.haze(state = hazeState)
.hazeBackground(state = hazeState)
) {
// todo
}
Expand All @@ -19,35 +19,35 @@ Box {
// Need to make app bar transparent to see the content behind
colors = TopAppBarDefaults.largeTopAppBarColors(Color.Transparent),
modifier = Modifier
// We use hazeChild on anything where we want the background
// We use hazeContent on anything where we want the background
// blurred.
.hazeChild(state = hazeState)
.hazeContent(state = hazeState)
.fillMaxWidth(),
)
}
```

## Styling

Haze has support for customizing the resulting effect, which is performed via the [HazeStyle](../api/haze/dev.chrisbanes.haze/-haze-style/) class, or the lambda block provided to `hazeChild`.
Haze has support for customizing the resulting effect, which is performed via the [HazeStyle](../api/haze/dev.chrisbanes.haze/-haze-style/) class, or the lambda block provided to `hazeContent`.

Styles can be provided in a number of different ways:

- [LocalHazeStyle](../api/haze/dev.chrisbanes.haze/-local-haze-style.html) composition local.
- The style parameter on [Modifier.hazeChild](../api/haze/dev.chrisbanes.haze/haze-child.html).
- By setting the relevant property in the optional [HazeChildScope](../api/haze/dev.chrisbanes.haze/-haze-child-scope/index.html) lambda `block`, passed into [Modifier.hazeChild](../api/haze/dev.chrisbanes.haze/haze-child.html).
- The style parameter on [Modifier.hazeContent](../api/haze/dev.chrisbanes.haze/haze-content.html).
- By setting the relevant property in the optional [HazeChildScope](../api/haze/dev.chrisbanes.haze/-haze-child-scope/index.html) lambda `block`, passed into [Modifier.hazeContent](../api/haze/dev.chrisbanes.haze/haze-content.html).

### HazeChildScope

We now have a parameter on `Modifier.hazeChild` which allow you to provide a lambda block, for controlling all of Haze's styling parameters. It is similar to concept to `Modifier.graphicsLayer { ... }`.
We now have a parameter on `Modifier.hazeContent` which allow you to provide a lambda block, for controlling all of Haze's styling parameters. It is similar to concept to `Modifier.graphicsLayer { ... }`.

It's useful for when you need to update styling parameters, using values derived from other state. Here's an example which fades the effect as the user scrolls:

```kotlin
FooAppBar(
...
modifier = Modifier
.hazeChild(state = hazeState) {
.hazeContent(state = hazeState) {
alpha = if (listState.firstVisibleItemIndex == 0) {
listState.layoutInfo.visibleItemsInfo.first().let {
(it.offset / it.size.height.toFloat()).absoluteValue
Expand All @@ -66,7 +66,7 @@ As we a few different ways to set styling properties, it's important to know how
Each styling property (such as `blurRadius`) is resolved seperately, and the order of precedence for each property is as follows, in order:

- Value set in [HazeChildScope](../api/haze/dev.chrisbanes.haze/-haze-child-scope/index.html), if specified.
- Value set in style provided to hazeChild (or HazeChildScope.style), if specified.
- Value set in style provided to hazeContent (or HazeChildScope.style), if specified.
- Value set in the [LocalHazeStyle](../api/haze/dev.chrisbanes.haze/-local-haze-style.html) composition local.

### Styling properties
Expand Down Expand Up @@ -94,7 +94,7 @@ Progressive blurs can be enabled by setting the `progressive` property on [HazeC
```kotlin
LargeTopAppBar(
// ...
modifier = Modifier.hazeChild(hazeState) {
modifier = Modifier.hazeContent(hazeState) {
progressive = HazeProgressive.verticalGradient(startIntensity = 1f, endIntensity = 0f)
}
)
Expand All @@ -113,7 +113,7 @@ You can provide any `Brush`, which will be used as a mask when the final effect
```kotlin
LargeTopAppBar(
// ...
modifier = Modifier.hazeChild(hazeState) {
modifier = Modifier.hazeContent(hazeState) {
mask = Brush.verticalGradient(...)
}
)
Expand All @@ -132,7 +132,7 @@ You can provide an input scale value which determines how much the content is sc
```kotlin
LargeTopAppBar(
// ...
modifier = Modifier.hazeChild(hazeState) {
modifier = Modifier.hazeContent(hazeState) {
inputScale = HazeInputScale.Auto
}
)
Expand Down
Loading

0 comments on commit 3745f1b

Please sign in to comment.