1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.compose.animation.core
18 
19 import androidx.compose.ui.geometry.Offset
20 import androidx.compose.ui.geometry.Rect
21 import androidx.compose.ui.geometry.Size
22 import androidx.compose.ui.unit.Dp
23 import androidx.compose.ui.unit.DpOffset
24 import androidx.compose.ui.unit.IntOffset
25 import androidx.compose.ui.unit.IntSize
26 import androidx.compose.ui.unit.dp
27 
28 private const val DpVisibilityThreshold = 0.1f
29 private const val PxVisibilityThreshold = 0.5f
30 
31 private val RectVisibilityThreshold =
32     Rect(PxVisibilityThreshold, PxVisibilityThreshold, PxVisibilityThreshold, PxVisibilityThreshold)
33 
34 /**
35  * Visibility threshold for [IntOffset]. This defines the amount of value change that is considered
36  * to be no longer visible. The animation system uses this to signal to some default [spring]
37  * animations to stop when the value is close enough to the target.
38  */
39 public val IntOffset.Companion.VisibilityThreshold: IntOffset
40     get() = IntOffset(1, 1)
41 
42 /**
43  * Visibility threshold for [Offset]. This defines the amount of value change that is considered to
44  * be no longer visible. The animation system uses this to signal to some default [spring]
45  * animations to stop when the value is close enough to the target.
46  */
47 public val Offset.Companion.VisibilityThreshold: Offset
48     get() = Offset(PxVisibilityThreshold, PxVisibilityThreshold)
49 
50 /**
51  * Visibility threshold for [Int]. This defines the amount of value change that is considered to be
52  * no longer visible. The animation system uses this to signal to some default [spring] animations
53  * to stop when the value is close enough to the target.
54  */
55 public val Int.Companion.VisibilityThreshold: Int
56     get() = 1
57 
58 /**
59  * Visibility threshold for [Dp]. This defines the amount of value change that is considered to be
60  * no longer visible. The animation system uses this to signal to some default [spring] animations
61  * to stop when the value is close enough to the target.
62  */
63 public val Dp.Companion.VisibilityThreshold: Dp
64     get() = DpVisibilityThreshold.dp
65 
66 /**
67  * Visibility threshold for [DpOffset]. This defines the amount of value change that is considered
68  * to be no longer visible. The animation system uses this to signal to some default [spring]
69  * animations to stop when the value is close enough to the target.
70  */
71 public val DpOffset.Companion.VisibilityThreshold: DpOffset
72     get() = DpOffset(Dp.VisibilityThreshold, Dp.VisibilityThreshold)
73 
74 /**
75  * Visibility threshold for [Size]. This defines the amount of value change that is considered to be
76  * no longer visible. The animation system uses this to signal to some default [spring] animations
77  * to stop when the value is close enough to the target.
78  */
79 public val Size.Companion.VisibilityThreshold: Size
80     get() = Size(PxVisibilityThreshold, PxVisibilityThreshold)
81 
82 /**
83  * Visibility threshold for [IntSize]. This defines the amount of value change that is considered to
84  * be no longer visible. The animation system uses this to signal to some default [spring]
85  * animations to stop when the value is close enough to the target.
86  */
87 public val IntSize.Companion.VisibilityThreshold: IntSize
88     get() = IntSize(1, 1)
89 
90 /**
91  * Visibility threshold for [Rect]. This defines the amount of value change that is considered to be
92  * no longer visible. The animation system uses this to signal to some default [spring] animations
93  * to stop when the value is close enough to the target.
94  */
95 public val Rect.Companion.VisibilityThreshold: Rect
96     get() = RectVisibilityThreshold
97 
98 // TODO: Add Dp.DefaultAnimation = spring<Dp>(visibilityThreshold = Dp.VisibilityThreshold)
99 // The floats coming out of this map are fed to APIs that expect objects (generics), so it's
100 // better to store them as boxed floats here instead of causing unboxing/boxing every time
101 // the values are read out and forwarded to other APIs
102 @Suppress("PrimitiveInCollection")
103 internal val VisibilityThresholdMap: Map<TwoWayConverter<*, *>, Float> =
104     mapOf(
105         Int.VectorConverter to 1f,
106         IntSize.VectorConverter to 1f,
107         IntOffset.VectorConverter to 1f,
108         Float.VectorConverter to 0.01f,
109         Rect.VectorConverter to PxVisibilityThreshold,
110         Size.VectorConverter to PxVisibilityThreshold,
111         Offset.VectorConverter to PxVisibilityThreshold,
112         Dp.VectorConverter to DpVisibilityThreshold,
113         DpOffset.VectorConverter to DpVisibilityThreshold
114     )
115