[go: nahoru, domu]

blob: 00832c4a71529ad729fedfa29693fdf00322e152 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.animation.core
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.unit.Bounds
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt
/**
* [TwoWayConverter] class contains the definition on how to convert from an arbitrary type [T]
* to a [AnimationVector], and convert the [AnimationVector] back to the type [T]. This allows
* animations to run on any type of objects, e.g. position, rectangle, color, etc.
*/
interface TwoWayConverter<T, V : AnimationVector> {
/**
* Defines how a type [T] should be converted to a Vector type (i.e. [AnimationVector1D],
* [AnimationVector2D], [AnimationVector3D] or [AnimationVector4D], depends on the dimensions of
* type T).
*/
val convertToVector: (T) -> V
/**
* Defines how to convert a Vector type (i.e. [AnimationVector1D], [AnimationVector2D],
* [AnimationVector3D] or [AnimationVector4D], depends on the dimensions of type T) back to type
* [T].
*/
val convertFromVector: (V) -> T
}
/**
* Factory method to create a [TwoWayConverter] that converts a type [T] from and to an
* [AnimationVector] type.
*
* @param convertToVector converts from type [T] to [AnimationVector]
* @param convertFromVector converts from [AnimationVector] to type [T]
*/
fun <T, V : AnimationVector> TwoWayConverter(
convertToVector: (T) -> V,
convertFromVector: (V) -> T
): TwoWayConverter<T, V> = TwoWayConverterImpl(convertToVector, convertFromVector)
/**
* Type converter to convert type [T] to and from a [AnimationVector1D].
*/
private class TwoWayConverterImpl<T, V : AnimationVector>(
override val convertToVector: (T) -> V,
override val convertFromVector: (V) -> T
) : TwoWayConverter<T, V>
internal fun lerp(start: Float, stop: Float, fraction: Float) =
(start * (1 - fraction) + stop * fraction)
/**
* A [TwoWayConverter] that converts [Float] from and to [AnimationVector1D]
*/
val Float.Companion.VectorConverter: TwoWayConverter<Float, AnimationVector1D>
get() = FloatToVector
/**
* A [TwoWayConverter] that converts [Int] from and to [AnimationVector1D]
*/
val Int.Companion.VectorConverter: TwoWayConverter<Int, AnimationVector1D>
get() = IntToVector
private val FloatToVector: TwoWayConverter<Float, AnimationVector1D> =
TwoWayConverter({ AnimationVector1D(it) }, { it.value })
private val IntToVector: TwoWayConverter<Int, AnimationVector1D> =
TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
/**
* A type converter that converts a [Rect] to a [AnimationVector4D], and vice versa.
*/
val Rect.Companion.VectorConverter: TwoWayConverter<Rect, AnimationVector4D>
get() = RectToVector
/**
* A type converter that converts a [Dp] to a [AnimationVector1D], and vice versa.
*/
val Dp.Companion.VectorConverter: TwoWayConverter<Dp, AnimationVector1D>
get() = DpToVector
/**
* A type converter that converts a [DpOffset] to a [AnimationVector2D], and vice versa.
*/
val DpOffset.Companion.VectorConverter: TwoWayConverter<DpOffset, AnimationVector2D>
get() = DpOffsetToVector
/**
* A type converter that converts a [Size] to a [AnimationVector2D], and vice versa.
*/
val Size.Companion.VectorConverter: TwoWayConverter<Size, AnimationVector2D>
get() = SizeToVector
/**
* A type converter that converts a [Bounds] to a [AnimationVector4D], and vice versa.
*/
val Bounds.Companion.VectorConverter: TwoWayConverter<Bounds, AnimationVector4D>
get() = BoundsToVector
/**
* A type converter that converts a [Offset] to a [AnimationVector2D], and vice versa.
*/
val Offset.Companion.VectorConverter: TwoWayConverter<Offset, AnimationVector2D>
get() = OffsetToVector
/**
* A type converter that converts a [IntOffset] to a [AnimationVector2D], and vice versa.
*/
val IntOffset.Companion.VectorConverter: TwoWayConverter<IntOffset, AnimationVector2D>
get() = IntOffsetToVector
/**
* A type converter that converts a [IntSize] to a [AnimationVector2D], and vice versa.
*/
val IntSize.Companion.VectorConverter: TwoWayConverter<IntSize, AnimationVector2D>
get() = IntSizeToVector
/**
* A type converter that converts a [Dp] to a [AnimationVector1D], and vice versa.
*/
private val DpToVector: TwoWayConverter<Dp, AnimationVector1D> = TwoWayConverter(
convertToVector = { AnimationVector1D(it.value) },
convertFromVector = { Dp(it.value) }
)
/**
* A type converter that converts a [DpOffset] to a [AnimationVector2D], and vice versa.
*/
private val DpOffsetToVector: TwoWayConverter<DpOffset, AnimationVector2D> =
TwoWayConverter(
convertToVector = { AnimationVector2D(it.x.value, it.y.value) },
convertFromVector = { DpOffset(it.v1.dp, it.v2.dp) }
)
/**
* A type converter that converts a [Size] to a [AnimationVector2D], and vice versa.
*/
private val SizeToVector: TwoWayConverter<Size, AnimationVector2D> =
TwoWayConverter(
convertToVector = { AnimationVector2D(it.width, it.height) },
convertFromVector = { Size(it.v1, it.v2) }
)
/**
* A type converter that converts a [Bounds] to a [AnimationVector4D], and vice versa.
*/
private val BoundsToVector: TwoWayConverter<Bounds, AnimationVector4D> =
TwoWayConverter(
convertToVector = {
AnimationVector4D(it.left.value, it.top.value, it.right.value, it.bottom.value)
},
convertFromVector = { Bounds(it.v1.dp, it.v2.dp, it.v3.dp, it.v4.dp) }
)
/**
* A type converter that converts a [Offset] to a [AnimationVector2D], and vice versa.
*/
private val OffsetToVector: TwoWayConverter<Offset, AnimationVector2D> =
TwoWayConverter(
convertToVector = { AnimationVector2D(it.x, it.y) },
convertFromVector = { Offset(it.v1, it.v2) }
)
/**
* A type converter that converts a [IntOffset] to a [AnimationVector2D], and vice versa.
*/
private val IntOffsetToVector: TwoWayConverter<IntOffset, AnimationVector2D> =
TwoWayConverter(
convertToVector = { AnimationVector2D(it.x.toFloat(), it.y.toFloat()) },
convertFromVector = { IntOffset(it.v1.roundToInt(), it.v2.roundToInt()) }
)
/**
* A type converter that converts a [IntSize] to a [AnimationVector2D], and vice versa.
*/
private val IntSizeToVector: TwoWayConverter<IntSize, AnimationVector2D> =
TwoWayConverter(
{ AnimationVector2D(it.width.toFloat(), it.height.toFloat()) },
{ IntSize(it.v1.roundToInt(), it.v2.roundToInt()) }
)
/**
* A type converter that converts a [Rect] to a [AnimationVector4D], and vice versa.
*/
private val RectToVector: TwoWayConverter<Rect, AnimationVector4D> =
TwoWayConverter(
convertToVector = {
AnimationVector4D(it.left, it.top, it.right, it.bottom)
},
convertFromVector = {
Rect(it.v1, it.v2, it.v3, it.v4)
}
)