lebonprix.apk/java/io/xdrm/lebonprix/anim/GooeySplashAnimation.kt

158 lines
4.7 KiB
Kotlin

package io.xdrm.lebonprix.anim
import android.content.res.Resources
import android.graphics.*
import android.graphics.drawable.Drawable
import android.support.v4.content.res.ResourcesCompat
import android.util.Log
import android.view.animation.*
import android.widget.ImageView
import io.xdrm.lebonprix.R
class GooeySplashAnimation(val res: Resources, val target: ImageView) : Animation() {
private var width: Int = 1000
private var height: Int = 1000
private var bitmap : Bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
private var canvas : Canvas = Canvas(bitmap)
private var progress: Float = 0F;
private var icon: Drawable?
data class wave(var relrad: Float, var clockWise: Boolean)
private var waves: MutableList<wave> = mutableListOf()
init {
icon = ResourcesCompat.getDrawable(res, R.mipmap.ic_splash_icon, null)
target.addOnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
width = right-left
height = bottom-top
// unregister previous
target.setImageBitmap(null)
canvas.setBitmap(null)
bitmap.recycle()
// build new
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
canvas = Canvas(bitmap)
target.setImageBitmap(bitmap)
generateWaves()
}
}
override fun start() {
target.startAnimation(this)
}
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
super.applyTransformation(interpolatedTime, t)
progress = interpolatedTime
draw()
}
fun draw(){
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
drawWave()
drawIcon()
target.setImageBitmap(bitmap)
}
private fun drawIcon(){
if( icon == null )
return
val bgSize = 280 + (20 + 20 * Math.sin(2*progress*Math.PI)).toInt()
val bgOffsetX = (width-bgSize)/2
val bgOffsetY = (height-bgSize)/2
icon!!.setBounds( bgOffsetX, bgOffsetY , bgOffsetX+bgSize, bgOffsetY+bgSize)
icon!!.draw(canvas)
}
private fun drawWave(){
val easeProgress = DecelerateInterpolator().getInterpolation(progress)
// -- PARAMETERS
// the wave will have a radius between 2% and -2% of the radius
val relativeRadiusVariation = 0.02F
val wavePerRevolution = 15
val revolutions = 20
val samples = 200
val relativeExpansionStartRadius = 1F // radius to expand from (relative to radius)
// -- PREPROCESSED VALUES
val slice = 2*Math.PI.toFloat() / samples;
val centerx = width * 0.5F
val centery = height * 0.5F
// val gradient: Shader = RadialGradient(x, y, width*0.5F, 0x554e5dff, Color.TRANSPARENT, Shader.TileMode.CLAMP)
// val paint = Paint()
// paint.shader = gradient
val paint = Paint()
paint.style = Paint.Style.STROKE
paint.color = 0x3de0e5
paint.alpha = 127 - (127*Math.sin(Math.PI*(2*progress + 0.5))).toInt()
paint.strokeWidth = width*0.003F * progress
// paint.flags = Paint.ANTI_ALIAS_FLAG
for( w in waves ){
val p = Path()
for( i in 0..samples ) {
val angle = slice * i.toDouble()
var rotation = wavePerRevolution*angle + easeProgress*revolutions*Math.PI
if( w.clockWise ) rotation = wavePerRevolution*angle - easeProgress*revolutions*Math.PI
// calculate proportional progress between minimum radius & end radius
val shiftedProgress = (progress + relativeExpansionStartRadius) / (1F+relativeExpansionStartRadius)
var rad = width*w.relrad * ( 1 + relativeRadiusVariation * (.2+progress*.8).toFloat() * Math.sin(rotation).toFloat() )
val x = centerx + rad*shiftedProgress * Math.cos(angle).toFloat()
val y = centery + rad*shiftedProgress * Math.sin(angle).toFloat()
if( i == 0 ) p.moveTo(x, y)
else p.lineTo(x, y)
}
canvas.drawPath(p, paint)
}
// val offset = ( width * progress ).toInt()
//
// wave1.setBounds(-(width-offset), (height*0.8).toInt(), width+offset, height)
// wave1.draw(canvas)
//
// wave2.setBounds(-offset, (height*0.7).toInt(), 2*width-offset, height)
// wave2.draw(canvas)
}
private fun generateWaves(count: Int = 1){
for( i in 0..count )
waves.add( wave(0.3F, true) )
waves.add( wave(0.5F, false) )
waves.add( wave(0.7F, true) )
}
}