Как мне создать базовую анимацию на Skiko (привязки Kotlin MPP к Skia)?

#windows #kotlin #desktop #skia

#Windows #kotlin #Для рабочего стола #skia

Вопрос:

Используя Skiko и Kotlin, я хочу создать базовую анимацию: счетчик от 0 до 100, который автоматически обновляет текст каждую секунду. Мне удалось это сделать, но у него есть проблема, он мигает каждый раз, когда окно перерисовывается. Вот код:

 import kotlinx.coroutines.*
import org.jetbrains.skija.*
import org.jetbrains.skiko.*
import javax.swing.*

public fun main() {
    val window = SkiaWindow().apply {
        layer.renderer = CounterRenderer()
        setSize(400, 175)
        isVisible = true
        defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
    }
    GlobalScope.launch {
        for (i in 0..100) {
            delay(1000)
            window.layer.repaint()
        }
    }
}

public class CounterRenderer : SkiaRenderer {
    private lateinit var canvas: Canvas
    private var counter = 0

    override fun onInit() {
    }

    override fun onDispose() {
    }

    override fun onReshape(width: Int, height: Int) {
    }

    override fun onRender(canvas: Canvas, width: Int, height: Int) {
        this.canvas = canvas

        val typeface = Typeface.makeFromName("Roboto", FontStyle.NORMAL)
        val fontSize = 30F
        val font = Font(typeface, fontSize)

        val paint = Paint().setColor(0XFF000000.toInt())
        canvas.drawString("Counter: ${counter  }", 10F, 50F, font, paint)
    }
}
 

Я безуспешно пытался найти примеры анимаций с помощью skija или skiko.
Я был бы очень признателен, если бы вы могли привести мне несколько примеров.

Ответ №1:

После навигации по коду Android Compose, особенно этот класс: ComposeLayer . Я наконец-то заставил его работать с этим кодом:

 import kotlinx.coroutines.*
import org.jetbrains.skija.*
import org.jetbrains.skiko.*
import javax.swing.*

public fun main() {
    val window = SkiaWindow().apply {
        layer.renderer = CounterRenderer()
        setSize(400, 175)
        isVisible = true
        defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE
    }
    GlobalScope.launch(Dispatchers.Main) {
        for (i in 0..100) {
            delay(500)
            window.layer.redrawLayer()
        }
    }
}

public class CounterRenderer : SkiaRenderer {
    private var counter = 0
    private val typeface = Typeface.makeFromName("Roboto", FontStyle.NORMAL)
    private val fontSize = 30F
    private val font = Font(typeface, fontSize)
    private val paint = Paint().setColor(0XFF000000.toInt())

    override fun onInit() {
    }

    override fun onDispose() {
    }

    override fun onReshape(width: Int, height: Int) {
    }

    override fun onRender(canvas: Canvas, width: Int, height: Int) {
        canvas.drawString("Counter: ${counter  }", 10F, 50F, font, paint)
    }
}
 

Для запуска этого кода вам необходимо установить конкретный главный диспетчер, в данном случае путем добавления его в конфигурацию gradle:

 implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.3.9")