216 lines
6.2 KiB
Kotlin
216 lines
6.2 KiB
Kotlin
package io.xdrm.lebonprix.anim
|
|
|
|
import android.content.Context
|
|
import android.graphics.*
|
|
import android.graphics.drawable.Drawable
|
|
import android.support.v4.content.res.ResourcesCompat
|
|
import android.util.Log
|
|
import android.view.animation.Animation
|
|
import android.view.animation.Transformation
|
|
import android.widget.ImageView
|
|
import android.util.TypedValue
|
|
import io.xdrm.lebonprix.R
|
|
|
|
|
|
class HomeFilterAnimation(
|
|
val ctx: Context,
|
|
val target: ImageView
|
|
) : Animation(){
|
|
|
|
companion object {
|
|
// stage 1 : clean the page
|
|
val STAGE_CLEAN = 0
|
|
// stage 2 : move to center
|
|
val STAGE_CENTER = 1
|
|
// stage 3 : loading animation
|
|
val STAGE_LOAD = 2
|
|
// stage 4 : clean the page for next activity
|
|
val STAGE_END = 3
|
|
val CLEAR_ALL = 4
|
|
}
|
|
|
|
// PARAMS
|
|
private val dpIconSize: Int = 44
|
|
private val dpIconTop: Int = 8
|
|
private val dpIconRight: Int = 8
|
|
|
|
// FIXED/PROCESSED VALUES
|
|
private val iconSize: Float = dptopx(dpIconSize)
|
|
private val iconTop: Float = dptopx(dpIconTop)
|
|
private val iconRight: Float = dptopx(dpIconRight)
|
|
|
|
|
|
// VARIABLES
|
|
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 icon: Drawable?
|
|
|
|
// ANIMATION
|
|
private var stage: Int = HomeFilterAnimation.STAGE_CLEAN
|
|
private var progress: Float = 0F
|
|
|
|
init {
|
|
icon = ResourcesCompat.getDrawable(ctx.resources, R.drawable.ic_search, 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)
|
|
}
|
|
}
|
|
|
|
|
|
// Convert dp to pixels
|
|
private fun dptopx(dp: Int) : Float{
|
|
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), ctx.resources.displayMetrics)
|
|
}
|
|
|
|
fun stage(s: Int) : HomeFilterAnimation{
|
|
stage = s
|
|
return this
|
|
}
|
|
|
|
fun during(d: Long) : HomeFilterAnimation {
|
|
super.setDuration(d)
|
|
return this
|
|
}
|
|
|
|
override fun start() {
|
|
target.startAnimation(this)
|
|
}
|
|
|
|
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
|
|
super.applyTransformation(interpolatedTime, t)
|
|
progress = interpolatedTime
|
|
draw()
|
|
}
|
|
|
|
private fun draw(){
|
|
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
|
|
|
|
// Clean the page
|
|
if( stage == HomeFilterAnimation.STAGE_CLEAN ) {
|
|
|
|
drawPageCleaner(progress)
|
|
drawCenterIconBackground(0F)
|
|
drawCenterIcon(0F)
|
|
|
|
} else if( stage == HomeFilterAnimation.STAGE_CENTER ){
|
|
|
|
drawPageCleaner(1F)
|
|
drawCenterIconBackground(progress)
|
|
drawCenterIcon(progress)
|
|
|
|
} else if( stage == HomeFilterAnimation.STAGE_LOAD ){
|
|
|
|
drawPageCleaner(1F)
|
|
drawLoadingIconBackground(progress)
|
|
drawCenterIcon(1F)
|
|
|
|
} else if( stage == HomeFilterAnimation.STAGE_END ){
|
|
|
|
drawPageCleaner(1F)
|
|
drawClearingIconBackground(progress)
|
|
drawCenterIcon(1F)
|
|
|
|
}
|
|
|
|
target.setImageBitmap(bitmap)
|
|
}
|
|
|
|
private fun drawPageCleaner(prog: Float){
|
|
val bg = Paint()
|
|
bg.color = Color.WHITE
|
|
|
|
// max radius to hide the whole screen
|
|
val maxRad = Math.sqrt( Math.pow(width.toDouble(),2.toDouble()) + Math.pow(height.toDouble(), 2.toDouble())) * 1.5F // security of 1.5x the max radius
|
|
val rad = prog * maxRad
|
|
val x = width - iconRight - iconSize/2F
|
|
val y = iconTop + iconSize/2F
|
|
canvas.drawCircle(x, y, rad.toFloat(), bg)
|
|
}
|
|
private fun drawClearingIconBackground(prog: Float){
|
|
val bg = Paint()
|
|
bg.color = ResourcesCompat.getColor(ctx.resources, R.color.colorBackground, null)
|
|
|
|
// max radius to hide the whole screen
|
|
val maxRad = Math.sqrt( Math.pow(width.toDouble(),2.toDouble()) + Math.pow(height.toDouble(), 2.toDouble())) * 1.5F // security of 1.5x the max radius
|
|
val rad = prog * maxRad
|
|
|
|
val x = width.toFloat() / 2F
|
|
val y = height.toFloat() / 2F
|
|
|
|
canvas.drawCircle(x, y, rad.toFloat(), bg)
|
|
}
|
|
|
|
private fun drawCenterIconBackground(prog: Float){
|
|
val bg = Paint()
|
|
bg.color = ResourcesCompat.getColor(ctx.resources, R.color.colorBackground, null)
|
|
|
|
val rad = iconSize/2F
|
|
|
|
// get start / end position (end = centered)
|
|
val startx = width - iconRight - rad
|
|
val starty = iconTop + rad
|
|
|
|
val endx = width.toFloat() / 2F
|
|
val endy = height.toFloat() / 2F
|
|
|
|
val x = startx + prog * (endx - startx)
|
|
val y = starty + prog * (endy - starty)
|
|
|
|
canvas.drawCircle(x, y, rad, bg)
|
|
}
|
|
|
|
|
|
private fun drawCenterIcon(prog: Float) {
|
|
if( icon == null )
|
|
return
|
|
|
|
// get start / end position (end = centered)
|
|
val startx = width - iconRight - iconSize
|
|
val starty = iconTop
|
|
|
|
val endx = width.toFloat() / 2F - iconSize/2F
|
|
val endy = height.toFloat() / 2F - iconSize/2F
|
|
|
|
|
|
// get x,y from start position to center
|
|
val x = (startx + prog * (endx - startx)).toInt()
|
|
val y = (starty + prog * (endy - starty)).toInt()
|
|
|
|
icon!!.setBounds(x, y, x + iconSize.toInt(), y + iconSize.toInt())
|
|
icon!!.draw(canvas)
|
|
|
|
}
|
|
|
|
private fun drawLoadingIconBackground(prog: Float){
|
|
val bg = Paint()
|
|
bg.color = ResourcesCompat.getColor(ctx.resources, R.color.colorBackground, null)
|
|
|
|
var rad = iconSize/2F
|
|
// evoluting size
|
|
rad *= ( 1F + (0.5F + 0.5F * Math.sin((0.5+prog)*2*Math.PI).toFloat()) )
|
|
|
|
// centered
|
|
val x = width.toFloat() / 2F
|
|
val y = height.toFloat() / 2F
|
|
|
|
canvas.drawCircle(x, y, rad, bg)
|
|
}
|
|
|
|
|
|
} |