From 67f348c3f374743c0c7413a240f6286c9c2fe975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=96=D0=B8=D1=80=D0=BA=D0=B5=D0=B2=D0=B8=D1=87?= Date: Mon, 15 Jul 2024 08:56:14 +0300 Subject: [PATCH] wip --- .../compottie/avp/AnimatedVectorPainter.kt | 17 ++- .../compottie/avp/animator/AnimatorSpec.kt | 6 + .../compottie/avp/animator/BrushAnimator.kt | 93 ------------- .../compottie/avp/animator/FloatAnimator.kt | 20 ++- .../compottie/avp/animator/ObjectAnimator.kt | 18 +-- .../compottie/avp/animator/PaintAnimator.kt | 130 ++++++++++++++++++ .../compottie/avp/animator/PathAnimator.kt | 4 +- .../avp/animator/rememberObjectAnimator.kt | 21 +++ .../compottie/avp/xml/AnimationParsers.kt | 8 +- .../compottie/avp/xml/ValueParsers.kt | 104 -------------- .../avp/xml/XmlAmimatedVectorParser.kt | 36 ++--- .../compottie/avp/xml/xmldom/Element.kt | 13 -- .../avp/xml/xmldom/MalformedXMLException.kt | 6 - .../compottie/avp/xml/xmldom/Node.kt | 16 --- .../compottie/avp/xml/xmldom/NodeList.kt | 10 -- .../{TestUtil.kt => ExpressionsTestUtil.kt} | 0 dynamic_properties.md | 2 +- 17 files changed, 223 insertions(+), 281 deletions(-) create mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/AnimatorSpec.kt delete mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/BrushAnimator.kt create mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/PaintAnimator.kt create mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/rememberObjectAnimator.kt delete mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/ValueParsers.kt delete mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/Element.kt delete mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/MalformedXMLException.kt delete mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/Node.kt delete mode 100644 compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/NodeList.kt rename compottie/src/commonTest/kotlin/expressions/{TestUtil.kt => ExpressionsTestUtil.kt} (100%) diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/AnimatedVectorPainter.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/AnimatedVectorPainter.kt index 1586967e..ce065c6e 100644 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/AnimatedVectorPainter.kt +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/AnimatedVectorPainter.kt @@ -13,22 +13,31 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.IntSize +import io.github.alexzhirkevich.compottie.avp.animator.ObjectAnimator +import org.jetbrains.compose.resources.DefaultComposeEnvironment import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.getResourceItemByEnvironment import kotlin.math.roundToInt + + @Composable public fun rememberAnimatedVectorPainter( resource : DrawableResource, + animations : List>, isAtAnd : Boolean ) : Painter { - TODO() + val environment = LocalComposeEnvironment.cu + val path = resource.getResourceItemByEnvironment(environment).path } + private class AnimatedVectorPainter( - vector: AnimatedImageVector, + private val vector: AnimatedImageVector, density : Density, time : () -> Float ) : Painter() { + override val intrinsicSize: Size = density.run { DpSize( vector.defaultWidth, @@ -37,8 +46,8 @@ private class AnimatedVectorPainter( } private val viewportSize = IntSize( - intrinsicSize.width.roundToInt(), - intrinsicSize.height.roundToInt() + vector.viewportWidth.roundToInt(), + vector.viewportHeight.roundToInt() ) private val root = AnimatedGroupComponent(vector.root) diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/AnimatorSpec.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/AnimatorSpec.kt new file mode 100644 index 00000000..dfa0df0d --- /dev/null +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/AnimatorSpec.kt @@ -0,0 +1,6 @@ +package io.github.alexzhirkevich.compottie.avp.animator + +public interface AnimatorSpec { + + public suspend fun load() : ObjectAnimator<*,*> +} \ No newline at end of file diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/BrushAnimator.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/BrushAnimator.kt deleted file mode 100644 index 46c0a3c4..00000000 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/BrushAnimator.kt +++ /dev/null @@ -1,93 +0,0 @@ -package io.github.alexzhirkevich.compottie.avp.animator - -import androidx.compose.animation.core.Easing -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.LinearGradientShader -import androidx.compose.ui.graphics.Shader -import androidx.compose.ui.graphics.lerp as colorLerp -import kotlin.math.min -import androidx.compose.ui.geometry.lerp as offsetLerp -import androidx.compose.ui.util.lerp as floatLerp - -internal sealed interface ColorData { - - fun lerp(other : ColorData, progress: Float) : - - sealed interface GradientColorData : ColorData { - val colorStops : List> - } - - class Solid(val color: Color) : ColorData { - - } - - class LinearGradient( - override val colorStops : List>, - val from : Offset, - val to : Offset - ) : GradientColorData -} - - -internal class PaintData( - var color: Color, - var shader : Shader? -) - -internal sealed class PaintAnimator : ObjectAnimator() - -internal class DynamicPaintAnimator( - override val duration: Float, - override val valueFrom: ColorData, - override val valueTo: ColorData, - override val startOffset: Float, - override val interpolator: Easing -) : ObjectAnimator() { - - private val paintData = PaintData(Color.Transparent, null) - - private val colors = if (valueFrom is ColorData.GradientColorData && valueTo is ColorData.GradientColorData) - List(min(valueFrom.colorStops.size, valueTo.colorStops.size)){ - Color.Transparent - }.toMutableList() - else mutableListOf() - - private val colorStops = colors.map { 0f }.toMutableList() - - override fun interpolate(progress: Float): PaintData { - - paintData.color = Color.Transparent - paintData.shader = null - - if (valueFrom is ColorData.Solid && valueTo is ColorData.Solid) { - paintData.color = colorLerp(valueFrom.color, valueTo.color, progress) - } - if (valueFrom is ColorData.LinearGradient && valueTo is ColorData.LinearGradient) { - - val size = min(valueFrom.colorStops.size, valueTo.colorStops.size) - paintData.shader = LinearGradientShader( - from = offsetLerp(valueFrom.from, valueTo.from, progress), - to = offsetLerp(valueFrom.to, valueTo.to, progress), - colors = List(size) { - colorLerp(valueFrom.colorStops[it].second, valueTo.colorStops[it].second, progress) - }, - colorStops = List(size) { - floatLerp(valueFrom.colorStops[it].first, valueTo.colorStops[it].first, progress) - } - ) - } - - return paintData - } -} - -internal class StaticPaintAnimator( - override val startOffset: Float, - override val duration: Float, - override val valueFrom: ColorData, - override val valueTo: ColorData, - override val interpolator: Easing -) : PaintAnimator(){ - -} \ No newline at end of file diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/FloatAnimator.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/FloatAnimator.kt index 0f0c5c65..ebfa1520 100644 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/FloatAnimator.kt +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/FloatAnimator.kt @@ -4,13 +4,27 @@ import androidx.compose.animation.core.Easing import androidx.compose.animation.core.LinearEasing import androidx.compose.ui.util.lerp -internal sealed class FloatAnimator : ObjectAnimator() +public sealed class FloatAnimator : ObjectAnimator() + +public fun FloatAnimator( + duration: Float, + delay : Float, + valueFrom: Float, + valueTo: Float, + interpolator: Easing +) : FloatAnimator = DynamicFloatAnimator( + duration = duration, + valueFrom = valueFrom, + valueTo = valueTo, + delay = delay, + interpolator = interpolator +) internal class DynamicFloatAnimator( override val duration: Float, override val valueFrom: Float, override val valueTo: Float, - override val startOffset: Float, + override val delay: Float, override val interpolator: Easing ) : FloatAnimator() { @@ -22,7 +36,7 @@ internal class DynamicFloatAnimator( internal class StaticFloatAnimator( private val value : Float ) : FloatAnimator() { - override val startOffset: Float get() = 0f + override val delay: Float get() = 0f override val duration: Float get() = 0f override val valueFrom: Float get() = value override val valueTo: Float get() = value diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/ObjectAnimator.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/ObjectAnimator.kt index 557740d3..b6f19729 100644 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/ObjectAnimator.kt +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/ObjectAnimator.kt @@ -2,26 +2,26 @@ package io.github.alexzhirkevich.compottie.avp.animator import androidx.compose.animation.core.Easing -internal abstract class ObjectAnimator { +public sealed class ObjectAnimator { - abstract val startOffset: Float + public abstract val delay: Float - abstract val duration: Float + public abstract val duration: Float - abstract val valueFrom: T + public abstract val valueFrom: T - abstract val valueTo: T + public abstract val valueTo: T - abstract val interpolator: Easing + public abstract val interpolator: Easing protected abstract fun interpolate(progress: Float): R - fun animate(time: Float): R { + internal fun animate(time: Float): R { - val progress = if (time < startOffset) { + val progress = if (time < delay) { 0f } else { - ((time - startOffset) / duration).coerceIn(0f, 1f) + ((time - delay) / duration).coerceIn(0f, 1f) } return interpolate(interpolator.transform(progress)) diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/PaintAnimator.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/PaintAnimator.kt new file mode 100644 index 00000000..c013745e --- /dev/null +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/PaintAnimator.kt @@ -0,0 +1,130 @@ +package io.github.alexzhirkevich.compottie.avp.animator + +import androidx.compose.animation.core.Easing +import androidx.compose.animation.core.LinearEasing +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.LinearGradientShader +import androidx.compose.ui.graphics.Shader +import androidx.compose.ui.graphics.TileMode +import androidx.compose.ui.graphics.lerp as colorLerp +import kotlin.math.min +import androidx.compose.ui.geometry.lerp as offsetLerp +import androidx.compose.ui.util.lerp as floatLerp + +internal sealed interface ColorData { + + sealed interface GradientColorData : ColorData { + val colorStops : List> + } + + class Solid(val color: Color) : ColorData + + class LinearGradient( + override val colorStops : List>, + val start : Offset, + val end : Offset, + val tileMode: TileMode + ) : GradientColorData { + val colors = colorStops.map { it.second } + val stops = colorStops.map { it.first } + } +} + + +internal class PaintData( + var color: Color = Color.Transparent, + var shader : Shader? = null +) + +internal sealed class PaintAnimator : ObjectAnimator() + +internal class DynamicPaintAnimator( + override val duration: Float, + override val valueFrom: ColorData, + override val valueTo: ColorData, + override val delay: Float, + override val interpolator: Easing +) : ObjectAnimator() { + + private val paintData = PaintData() + + private val colors = if ( + valueFrom is ColorData.GradientColorData && + valueTo is ColorData.GradientColorData + ) { + List(min(valueFrom.colorStops.size, valueTo.colorStops.size)) { + Color.Transparent + }.toMutableList() + } else { + mutableListOf() + } + private val colorStops = colors.map { 0f }.toMutableList() + + override fun interpolate(progress: Float): PaintData { + + paintData.color = Color.Transparent + paintData.shader = null + + if (valueFrom is ColorData.Solid && valueTo is ColorData.Solid) { + paintData.color = colorLerp(valueFrom.color, valueTo.color, progress) + } + if (valueFrom is ColorData.LinearGradient && valueTo is ColorData.LinearGradient) { + + repeat(colors.size) { + colors[it] = colorLerp( + valueFrom.colors[it], + valueTo.colors[it], + progress + ) + colorStops[it] = floatLerp( + valueFrom.stops[it], + valueTo.stops[it], + progress + ) + } + paintData.shader = LinearGradientShader( + from = offsetLerp(valueFrom.start, valueTo.start, progress), + to = offsetLerp(valueFrom.end, valueTo.end, progress), + colors = colors, + colorStops = colorStops, + tileMode = valueTo.tileMode + ) + } + + return paintData + } +} + +internal class StaticPaintAnimator( + val value : ColorData +) : PaintAnimator(){ + + override val delay: Float get() = 0f + override val duration: Float get() = 0f + override val valueFrom: ColorData get() = value + override val valueTo: ColorData get() = value + override val interpolator: Easing get() = LinearEasing + + private val paint = PaintData() + override fun interpolate(progress: Float): PaintData { + paint.color = Color.Transparent + paint.shader = null + when (value){ + is ColorData.LinearGradient -> { + paint.shader = LinearGradientShader( + from = value.start, + to = value.end, + colors = value.colors, + colorStops = value.stops, + tileMode = value.tileMode + ) + } + is ColorData.Solid -> { + paint.color = value.color + } + } + + return paint + } +} \ No newline at end of file diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/PathAnimator.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/PathAnimator.kt index 1b4ce8cd..5a7e1c16 100644 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/PathAnimator.kt +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/PathAnimator.kt @@ -13,7 +13,7 @@ internal class DynamicPathAnimator( override val duration: Float, override val valueFrom: List, override val valueTo: List, - override val startOffset: Float, + override val delay: Float, override val interpolator: Easing ) : PathAnimator() { @@ -36,7 +36,7 @@ internal class DynamicPathAnimator( internal class StaticPathAnimator( val value : List ) : PathAnimator() { - override val startOffset: Float get() = 0f + override val delay: Float get() = 0f override val duration: Float get() = 0f override val valueFrom: List get() = value override val valueTo: List get() = value diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/rememberObjectAnimator.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/rememberObjectAnimator.kt new file mode 100644 index 00000000..5cc7f87e --- /dev/null +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/animator/rememberObjectAnimator.kt @@ -0,0 +1,21 @@ +package io.github.alexzhirkevich.compottie.avp.animator + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember + +@Composable +public fun rememberObjectAnimator(xml : suspend () -> String) : AnimatorSpec { + return remember { + object : AnimatorSpec { + override suspend fun load(): ObjectAnimator<*, *> { + xml().encodeToByteArray(). + } + } + } +} + +@Composable +public fun rememberObjectAnimator(xml : ByteArray) : AnimatorSpec { + l +} + diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/AnimationParsers.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/AnimationParsers.kt index ed929781..be8a7cac 100644 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/AnimationParsers.kt +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/AnimationParsers.kt @@ -1,3 +1,4 @@ +@file: Suppress("invisible_member", "invisible_reference") package io.github.alexzhirkevich.compottie.avp.xml import androidx.compose.animation.core.LinearEasing @@ -9,6 +10,7 @@ import io.github.alexzhirkevich.compottie.avp.animator.DynamicPaintAnimator import io.github.alexzhirkevich.compottie.avp.animator.DynamicPathAnimator import io.github.alexzhirkevich.compottie.avp.animator.ObjectAnimator import org.jetbrains.compose.resources.vector.xmldom.Element +import org.jetbrains.compose.resources.vector.childrenSequence import org.jetbrains.compose.resources.vector.xmldom.MalformedXMLException internal fun Element.parseAnimation() : List> { @@ -90,7 +92,7 @@ private fun ValueType.toAnimator( duration = duration, valueFrom = fromValue as ColorData, valueTo = toValue as ColorData, - startOffset = 0f, + delay = 0f, interpolator = LinearEasing ) @@ -98,7 +100,7 @@ private fun ValueType.toAnimator( duration = duration, valueFrom = fromValue as Float, valueTo = toValue as Float, - startOffset = 0f, + delay = 0f, interpolator = LinearEasing ) @@ -106,7 +108,7 @@ private fun ValueType.toAnimator( duration = duration, valueFrom = fromValue as List, valueTo = toValue as List, - startOffset = 0f, + delay = 0f, interpolator = LinearEasing ) } diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/ValueParsers.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/ValueParsers.kt deleted file mode 100644 index aa515a73..00000000 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/ValueParsers.kt +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 io.github.alexzhirkevich.compottie.avp.xml - -import androidx.compose.ui.graphics.PathFillType -import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.graphics.StrokeJoin -import androidx.compose.ui.graphics.TileMode -import androidx.compose.ui.unit.Density -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp - -private const val ALPHA_MASK = 0xFF000000.toInt() - -// parseColorValue is copied from Android: -// https://cs.android.com/android-studio/platform/tools/base/+/05fadd8cb2aaafb77da02048c7a240b2147ff293:sdk-common/src/main/java/com/android/ide/common/vectordrawable/VdUtil.kt;l=58 -/** - * Parses a color value in #AARRGGBB format. - * - * @param color the color value string - * @return the integer color value - */ -internal fun parseColorValue(color: String): Int { - require(color.startsWith("#")) { "Invalid color value $color" } - - return when (color.length) { - 7 -> { - // #RRGGBB - color.substring(1).toUInt(16).toInt() or ALPHA_MASK - } - 9 -> { - // #AARRGGBB - color.substring(1).toUInt(16).toInt() - } - 4 -> { - // #RGB - val v = color.substring(1).toUInt(16).toInt() - var k = (v shr 8 and 0xF) * 0x110000 - k = k or (v shr 4 and 0xF) * 0x1100 - k = k or (v and 0xF) * 0x11 - k or ALPHA_MASK - } - 5 -> { - // #ARGB - val v = color.substring(1).toUInt(16).toInt() - var k = (v shr 12 and 0xF) * 0x11000000 - k = k or (v shr 8 and 0xF) * 0x110000 - k = k or (v shr 4 and 0xF) * 0x1100 - k = k or (v and 0xF) * 0x11 - k or ALPHA_MASK - } - else -> ALPHA_MASK - } -} - -internal fun parseFillType(fillType: String): PathFillType = when (fillType) { - "nonZero" -> PathFillType.NonZero - "evenOdd" -> PathFillType.EvenOdd - else -> throw UnsupportedOperationException("unknown fillType: $fillType") -} - -internal fun parseStrokeCap(strokeCap: String): StrokeCap = when (strokeCap) { - "butt" -> StrokeCap.Butt - "round" -> StrokeCap.Round - "square" -> StrokeCap.Square - else -> throw UnsupportedOperationException("unknown strokeCap: $strokeCap") -} - -internal fun parseStrokeJoin(strokeJoin: String): StrokeJoin = when (strokeJoin) { - "miter" -> StrokeJoin.Miter - "round" -> StrokeJoin.Round - "bevel" -> StrokeJoin.Bevel - else -> throw UnsupportedOperationException("unknown strokeJoin: $strokeJoin") -} - -internal fun parseTileMode(tileMode: String): TileMode = when (tileMode) { - "clamp" -> TileMode.Clamp - "repeated" -> TileMode.Repeated - "mirror" -> TileMode.Mirror - else -> throw throw UnsupportedOperationException("unknown tileMode: $tileMode") -} - -internal fun String?.parseDp(density: Density): Dp = with(density) { - return when { - this@parseDp == null -> 0f.dp - endsWith("dp") -> removeSuffix("dp").toFloat().dp - endsWith("px") -> removeSuffix("px").toFloat().toDp() - else -> throw UnsupportedOperationException("value should ends with dp or px") - } -} diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/XmlAmimatedVectorParser.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/XmlAmimatedVectorParser.kt index 89729842..71eca507 100644 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/XmlAmimatedVectorParser.kt +++ b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/XmlAmimatedVectorParser.kt @@ -1,3 +1,5 @@ +@file: Suppress("invisible_member", "invisible_reference") + /* * Copyright 2020 The Android Open Source Project * @@ -46,13 +48,21 @@ import io.github.alexzhirkevich.compottie.avp.DefaultTrimPathStartAnimator import io.github.alexzhirkevich.compottie.avp.animator.ColorData import io.github.alexzhirkevich.compottie.avp.animator.FloatAnimator import io.github.alexzhirkevich.compottie.avp.animator.ObjectAnimator +import io.github.alexzhirkevich.compottie.avp.animator.PaintAnimator import io.github.alexzhirkevich.compottie.avp.animator.PathAnimator import io.github.alexzhirkevich.compottie.avp.animator.StaticFloatAnimator import io.github.alexzhirkevich.compottie.avp.animator.StaticPathAnimator -import io.github.alexzhirkevich.compottie.avp.animator.toAnimator import io.github.alexzhirkevich.compottie.avp.xml.BuildContext.Group import org.jetbrains.compose.resources.vector.xmldom.Element import org.jetbrains.compose.resources.vector.xmldom.Node +import org.jetbrains.compose.resources.vector.parseDp +import org.jetbrains.compose.resources.vector.parseFillType +import org.jetbrains.compose.resources.vector.parseColorValue +import org.jetbrains.compose.resources.vector.parseColorValue +import org.jetbrains.compose.resources.vector.parseStrokeCap +import org.jetbrains.compose.resources.vector.parseStrokeJoin +import org.jetbrains.compose.resources.vector.parseTileMode +import org.jetbrains.compose.resources.vector.childrenSequence // Parsing logic is the same as in Android implementation @@ -135,21 +145,21 @@ private fun Element.parsePath( pathFillType = attributeOrNull(ANDROID_NS, "fillType") ?.let(::parseFillType) ?: PathFillType.NonZero, name = name ?: DefaultPathName, - fill = attributeOrNull(ANDROID_NS, "fillColor")?.let(::parseStringBrush) - ?: apptAttr(ANDROID_NS, "fillColor")?.let(Element::parseElementBrush), + fill = attributeOrNull(ANDROID_NS, "fillColor")?.let(::parseColorStops) + ?: apptAttr(ANDROID_NS, "fillColor")?.let(Element::parseColorStops)?.let(::StaticPathAnimator), fillAlpha = floatAnimator( thisAnimators, VectorProperty.FillAlpha, DefaultAlphaAnimator ), - stroke = attributeOrNull(ANDROID_NS, "strokeColor")?.let(::parseStringBrush) - ?: apptAttr(ANDROID_NS, "strokeColor")?.let(Element::parseElementBrush), + stroke = attributeOrNull(ANDROID_NS, "strokeColor")?.let(::parseColorStops) + ?: apptAttr(ANDROID_NS, "strokeColor")?.let(Element::parseColorStops), strokeAlpha = floatAnimator( thisAnimators, VectorProperty.StrokeAlpha, DefaultAlphaAnimator ), - strokeLineWidth = attributeOrNull(ANDROID_NS, "strokeWidth")?.toFloat()?.toAnimator() + strokeLineWidth = attributeOrNull(ANDROID_NS, "strokeWidth")?.toFloat()?.let(::StaticFloatAnimator) ?: DefaultStrokeLineWidthAnimator, strokeLineCap = attributeOrNull(ANDROID_NS, "strokeLineCap") ?.let(::parseStrokeCap) ?: StrokeCap.Butt, @@ -240,8 +250,6 @@ private fun Element.parseGroup( } while (removedGroup == Group.Virtual) } -private fun parseStringBrush(str: String) = SolidColor(Color(parseColorValue(str))) - private fun Element.parseElementBrush(): Brush? = childrenSequence .filterIsInstance() @@ -258,7 +266,7 @@ private fun Element.parseGradient(): Brush? { } private fun Element.parseLinearGradient() = ColorData.LinearGradient( - colorStops = parseColorStops(), + colorStops = parseColorStops().toList(), start = Offset( attributeOrNull(ANDROID_NS, "startX")?.toFloat() ?: 0f, attributeOrNull(ANDROID_NS, "startY")?.toFloat() ?: 0f @@ -288,7 +296,7 @@ private fun Element.parseSweepGradient() = Brush.sweepGradient( ) ) -private fun Element.parseColorStops(): Array> { +private fun Element.parseColorStops(): List> { val items = childrenSequence .filterIsInstance() .filter { it.nodeName == "item" } @@ -314,7 +322,7 @@ private fun Element.parseColorStops(): Array> { } } - return colorStops.toTypedArray() + return colorStops } private fun Element.parseColorStop(defaultOffset: Float): Pair? { @@ -364,9 +372,3 @@ private fun Element.apptAttr( it.getAttribute("name") == "$prefix:$name" } } - -internal val Element.childrenSequence get() = sequence { - for (i in 0 until childNodes.length) { - yield(childNodes.item(i)) - } -} diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/Element.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/Element.kt deleted file mode 100644 index eb240f08..00000000 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/Element.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.jetbrains.compose.resources.vector.xmldom - -import kotlin.reflect.KProperty - -/** - * XML DOM Element. - */ -internal interface Element: Node { - - fun getAttributeNS(nameSpaceURI: String, localName: String): String - - fun getAttribute(name: String): String -} diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/MalformedXMLException.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/MalformedXMLException.kt deleted file mode 100644 index ffaf7790..00000000 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/MalformedXMLException.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.jetbrains.compose.resources.vector.xmldom - -/** - * Error throw when parsed XML is malformed - */ -public class MalformedXMLException(message: String?) : Exception(message) diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/Node.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/Node.kt deleted file mode 100644 index 8f663be5..00000000 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/Node.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.jetbrains.compose.resources.vector.xmldom - -/** - * XML DOM Node. - */ -internal interface Node { - val textContent: String? - - val nodeName: String - val localName: String - - val childNodes: NodeList - val namespaceURI: String - - fun lookupPrefix(namespaceURI: String): String -} \ No newline at end of file diff --git a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/NodeList.kt b/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/NodeList.kt deleted file mode 100644 index db6a029e..00000000 --- a/compottie-avp/src/commonMain/kotlin/io/github/alexzhirkevich/compottie/avp/xml/xmldom/NodeList.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.jetbrains.compose.resources.vector.xmldom - -/** - * XML DOM Node list. - */ -internal interface NodeList { - fun item(i: Int): Node - - val length: Int -} \ No newline at end of file diff --git a/compottie/src/commonTest/kotlin/expressions/TestUtil.kt b/compottie/src/commonTest/kotlin/expressions/ExpressionsTestUtil.kt similarity index 100% rename from compottie/src/commonTest/kotlin/expressions/TestUtil.kt rename to compottie/src/commonTest/kotlin/expressions/ExpressionsTestUtil.kt diff --git a/dynamic_properties.md b/dynamic_properties.md index 18ecee94..6570155b 100644 --- a/dynamic_properties.md +++ b/dynamic_properties.md @@ -127,4 +127,4 @@ shapeLayer("Precomposition 1", "Shape Layer 4") { } ``` -Just like precompositions, groups can be nested. So the keypath to the desired shape may lay throught the large amount of groups +Just like precompositions, groups can be nested. So the keypath to the desired shape may пше з through the large amount of groups