1 /*
<lambda>null2 * Copyright 2021 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.graphics.res
18
19 import android.animation.TimeInterpolator
20 import android.content.res.Resources
21 import android.util.Xml
22 import android.view.animation.AnticipateOvershootInterpolator
23 import android.view.animation.BounceInterpolator
24 import androidx.compose.animation.core.Easing
25 import androidx.compose.animation.core.FastOutLinearInEasing
26 import androidx.compose.animation.core.FastOutSlowInEasing
27 import androidx.compose.animation.core.LinearEasing
28 import androidx.compose.animation.core.LinearOutSlowInEasing
29 import androidx.compose.animation.graphics.vector.Animator
30 import androidx.compose.animation.graphics.vector.compat.AndroidVectorResources
31 import androidx.compose.animation.graphics.vector.compat.TagObjectAnimator
32 import androidx.compose.animation.graphics.vector.compat.TagSet
33 import androidx.compose.animation.graphics.vector.compat.parseAnimatorSet
34 import androidx.compose.animation.graphics.vector.compat.parseInterpolator
35 import androidx.compose.animation.graphics.vector.compat.parseObjectAnimator
36 import androidx.compose.animation.graphics.vector.compat.seekToStartTag
37 import kotlin.math.PI
38 import kotlin.math.cos
39 import kotlin.math.pow
40 import kotlin.math.sin
41 import org.xmlpull.v1.XmlPullParserException
42
43 /** Synchronously loads an [Animator] resource. */
44 @Throws(XmlPullParserException::class)
45 internal fun loadAnimatorResource(
46 theme: Resources.Theme? = null,
47 res: Resources,
48 resId: Int
49 ): Animator {
50 val parser = res.getXml(resId)
51 val attrs = Xml.asAttributeSet(parser)
52
53 parser.seekToStartTag()
54 return when (parser.name) {
55 TagSet -> {
56 parser.parseAnimatorSet(res, theme, attrs)
57 }
58 TagObjectAnimator -> {
59 parser.parseObjectAnimator(res, theme, attrs)
60 }
61 else -> {
62 throw XmlPullParserException("Unknown tag: ${parser.name}")
63 }
64 }
65 }
66
toEasingnull67 internal fun TimeInterpolator.toEasing() = Easing { x -> getInterpolation(x) }
68
xnull69 internal val AccelerateDecelerateEasing = Easing { x ->
70 ((cos((x + 1) * Math.PI) / 2.0f) + 0.5f).toFloat()
71 }
72
xnull73 internal val AccelerateEasing = Easing { x -> x * x }
74
xnull75 internal fun AccelerateEasing(factor: Float) = Easing { x -> x.pow(factor * 2) }
76
AnticipateEasingnull77 internal fun AnticipateEasing(tension: Float) = Easing { x ->
78 x * x * ((tension + 1) * x - tension)
79 }
80
AnticipateOvershootEasingnull81 internal fun AnticipateOvershootEasing(tension: Float, extraTension: Float): Easing =
82 AnticipateOvershootInterpolator(tension, extraTension).toEasing()
83
84 internal val BounceEasing: Easing = BounceInterpolator().toEasing()
85
86 internal fun CycleEasing(cycle: Float) = Easing { x -> sin(2 * cycle * PI * x).toFloat() }
87
xnull88 internal val DecelerateEasing = Easing { x -> 1.0f - (1.0f - x) * (1.0f - x) }
89
xnull90 internal fun DecelerateEasing(factor: Float) = Easing { x -> 1.0f - (1.0f - x).pow(2 * factor) }
91
xnull92 internal fun OvershootEasing(tension: Float) = Easing { x ->
93 (x - 1f).let { t -> t * t * ((tension + 1f) * t + tension) + 1f }
94 }
95
96 private val builtinInterpolators =
97 hashMapOf(
98 android.R.anim.linear_interpolator to LinearEasing,
99 android.R.interpolator.fast_out_linear_in to FastOutLinearInEasing,
100 android.R.interpolator.fast_out_slow_in to FastOutSlowInEasing,
101 android.R.interpolator.linear to LinearEasing,
102 android.R.interpolator.linear_out_slow_in to LinearOutSlowInEasing,
103 AndroidVectorResources.FAST_OUT_LINEAR_IN to FastOutLinearInEasing,
104 AndroidVectorResources.FAST_OUT_SLOW_IN to FastOutSlowInEasing,
105 AndroidVectorResources.LINEAR_OUT_SLOW_IN to LinearOutSlowInEasing
106 )
107
108 /** Synchronously loads an interpolator resource as an [Easing]. */
109 @Throws(XmlPullParserException::class)
loadInterpolatorResourcenull110 internal fun loadInterpolatorResource(
111 theme: Resources.Theme? = null,
112 res: Resources,
113 resId: Int
114 ): Easing {
115 return builtinInterpolators[resId]
116 ?: res.getXml(resId).run {
117 seekToStartTag().parseInterpolator(res, theme, Xml.asAttributeSet(this))
118 }
119 }
120