SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/span/MisskeyMotionSpan.kt

64 lines
1.8 KiB
Kotlin

package jp.juggler.subwaytooter.span
import android.graphics.Paint
import android.graphics.Typeface
import android.text.TextPaint
import android.text.style.MetricAffectingSpan
import java.lang.ref.WeakReference
import kotlin.math.sin
class MisskeyMotionSpan(
private val typeface: Typeface,
) : MetricAffectingSpan(), AnimatableSpan {
private var invalidateCallback: AnimatableSpanInvalidator? = null
private var refDrawTarget: WeakReference<Any>? = null
override fun setInvalidateCallback(
drawTargetTag: Any,
invalidateCallback: AnimatableSpanInvalidator,
) {
this.refDrawTarget = WeakReference(drawTargetTag)
this.invalidateCallback = invalidateCallback
}
private val textScalingMax = 1.0f
override fun updateMeasureState(paint: TextPaint) {
apply(paint, bDrawing = false)
}
override fun updateDrawState(drawState: TextPaint) {
apply(drawState, bDrawing = true)
}
private fun apply(paint: Paint, bDrawing: Boolean) {
val textScaling = when {
!bDrawing -> textScalingMax
else -> {
invalidateCallback?.delayInvalidate(100L)
val t = (invalidateCallback?.timeFromStart ?: 0L) / 100f
textScalingMax * (sin(t.toDouble()).toFloat() * 0.1f + 0.9f)
}
}
paint.textSize = paint.textSize * textScaling
val oldTypeface = paint.typeface
val oldStyle = oldTypeface?.style ?: 0
val fakeStyle = oldStyle and typeface.style.inv()
if (fakeStyle and Typeface.BOLD != 0) {
paint.isFakeBoldText = true
}
if (fakeStyle and Typeface.ITALIC != 0) {
paint.textSkewX = -0.25f
}
paint.typeface = typeface
}
}