Une imitation vue personnalisée éclipse

I, les mots EDITORIAL

Effet comme indiqué ci-dessus, l'auteur au moment de la pause déjeuner, re-chase à nouveau détective Di Renjie II, conspiré utiliser Eclipse esprit de serpent, cité eau Luo Wu Zhou subvertir le bateau. éclipse solaire est, monde sombre, après l'éclipse de toutes les choses de réponse claire. Après avoir lu une pensée, ou je n'ai pas voir un effet d'éclipse solaire, puis, il y a cet article.

En second lieu, l'analyse d'animation

Tout d'abord, il y a un cercle, un nom, appelé le Soleil (Sun), Moon (Lune) glisser lentement du Soleil, et que les deux cercles se chevauchent, l'arrière-plan devient sombre, lorsque la coïncidence complète de la profondeur maximale, Sun Moon lentement, puis séparés, séparés quand la couleur de fond fanée, et enfin la restitution, le logo apparaît. Il y a deux points techniques, le premier contrôle est la couleur de fond, seul le second tour est la partie chevauchée Lune et du Soleil est visible, le reste n'est pas visible, de sorte que l'éclipse est réaliste.

En troisième lieu, la peinture (onDraw)

//draw太阳
        canvas?.drawCircle(centerX.toFloat(), centerY.toFloat(), mSunR.toFloat(), mSunPaint)

Tout d'abord, dessiner un cercle que le soleil. Donc, la lune ne dessine pas un petit cercle de la même manière? Eh bien, pas exactement, si la même façon, un cercle dessiné sur la couverture arrière dans la lune, l'éclipse réelle car une grande luminosité du soleil, pour voir la lune sur le soleil à l'œil nu, donc nous utilisons ce genre de choses à PorterDuffXfermode comme suit:

        xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)

Ce mode a une grande variété, ce n'est pas l'objet de cet article, ne sera pas discuté, probablement des moyens qui ne se chevauchent partiellement visibles. Vidéos section de lune comme illustré ci-dessous


        //draw月亮
        mSunPaint.color = mMoonColor

        mSunPaint.xfermode = xfermode
        canvas?.drawCircle(mMoonX.toFloat(), centerY.toFloat(), mMoonR.toFloat(), mSunPaint)
        mSunPaint.xfermode = null

Prochain tirage logo, pour être le premier coup après le tirage dans le Soleil et la Lune, et avant la lune dans la peinture. La partie de code complet afin onDraw

override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        mSunPaint.color = mSunColor
        //draw太阳
        canvas?.drawCircle(centerX.toFloat(), centerY.toFloat(), mSunR.toFloat(), mSunPaint)

        if (isLogoShow) {
            mLogoPaint.xfermode = xfermode
            canvas?.drawBitmap(mLogoBitmap, mLogoBitmapSrcRect, mLogoBitmapDesRect, mLogoPaint)
            mLogoPaint.xfermode = null
        }
        //draw月亮
        mSunPaint.color = mMoonColor

        mSunPaint.xfermode = xfermode
        canvas?.drawCircle(mMoonX.toFloat(), centerY.toFloat(), mMoonR.toFloat(), mSunPaint)
        mSunPaint.xfermode = null

    }

Les éléments sont bien dessinés, il est de les laisser prendre le relais de se déplacer, j'utilise une implémentation de gestionnaire. La première est d'entrer dans l'animation, chaque changement de la coordonnée X Lune

 MSG_IN -> {
                if (mMoonX < centerX) {
                    mMoonX += mMoonXOffset
                    invalidate()
                    it.target.sendEmptyMessageDelayed(MSG_IN, mAnimationSpeed)
                } else if (kotlin.math.abs(mMoonX - centerX) <= mMoonXOffset) {
                    isLogoShow = true
                    invalidate()
                    it.target.sendEmptyMessageDelayed(MSG_OUT, 500)
                }
                progressOffset = txfloat((mMoonX - mMoonStartX), (4 * mSunR))

            }

Sortie et animation d'animation d'entrée également à faire, mais pour dessiner le logo, l'opacité de la brosse progressivement augmente, ne figurent pas dans le logo trop importune.

MSG_OUT -> {
                if (mMoonX - centerX < 2 * mSunR) {
                    mMoonX += mMoonXOffset
                    var tempAlpha = 255 * (mMoonX - centerX) / (2 * mSunR)
                    if (tempAlpha > mLogoPaint.alpha) {
                        if (tempAlpha > 255) {
                            tempAlpha = 255
                        }
                        mLogoPaint.alpha = tempAlpha
                    }
                    invalidate()
                    it.target.sendEmptyMessageDelayed(MSG_OUT, mAnimationSpeed)
                }
                progressOffset = txfloat((mMoonX - mMoonStartX), (4 * mSunR))

            }

Ensuite, il y a la couleur de fond change ici, je vais vous donner une méthode de calcul de couleur.

/**
     * 根据fraction值来计算当前的颜色。
     */
    private fun getCurrentColor(fraction: Float, startColor: Int, endColor: Int): Int {
        val redCurrent: Int
        val blueCurrent: Int
        val greenCurrent: Int
        val alphaCurrent: Int
        val redStart = Color.red(startColor)
        val blueStart = Color.blue(startColor)
        val greenStart = Color.green(startColor)
        val alphaStart = Color.alpha(startColor)
        val redEnd = Color.red(endColor)
        val blueEnd = Color.blue(endColor)
        val greenEnd = Color.green(endColor)
        val alphaEnd = Color.alpha(endColor)
        val redDifference = redEnd - redStart
        val blueDifference = blueEnd - blueStart
        val greenDifference = greenEnd - greenStart
        val alphaDifference = alphaEnd - alphaStart
        redCurrent = (redStart + fraction * redDifference).toInt()
        blueCurrent = (blueStart + fraction * blueDifference).toInt()
        greenCurrent = (greenStart + fraction * greenDifference).toInt()
        alphaCurrent = (alphaStart + fraction * alphaDifference).toInt()
        return Color.argb(alphaCurrent, redCurrent, greenCurrent, blueCurrent)
    }

Nous avons besoin d'un fond de rappel à travers l'auditeur, de sorte que le point de vue de la mise en page de parent d'atteindre. Pourquoi? Parce que si nous avons établi un fond dans le contrôle interne, la méthode de peinture par xfermode Lune en arrière-plan sur l'ensemble visible (nous avons demandé éclipse la Lune était visible que dans le chevauchement partiel avec Sun)

   if (it.what == MSG_IN || it.what == MSG_OUT) {
            val color = if (progressOffset * 2 > 1) {
                getCurrentColor(2 - progressOffset * 2, mBgStartColor, mBgEndColor)
            } else {
                getCurrentColor(progressOffset * 2, mBgStartColor, mBgEndColor)
            }
            eclipseListener?.onColor(color)
        }

De cette façon, nous éclipse est terminée.

Quatrièmement, l'utilisation

Ajoutez dans votre build.gradle racine à la fin des dépôts:

	allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}

Ajouter la dépendance

	dependencies {
	        implementation 'com.github.cqcby1994:MyView:1.2.1'
	}
<com.chen.eclipseview.EclipseLogo
        android:id="@+id/eclipse_view"
        app:logoSize="large"
        app:speed="middle"
        app:sunColor="@android:color/white"
        app:moonColor="#279536"
        app:endBackgroundColor="#279536"
        app:startBackgroundColor="@android:color/white"
        app:logoSrc="@mipmap/wechat"
        android:layout_width="200dp"
        android:layout_height="200dp"
 />

 Vous pouvez définir leurs propres paramètres de vitesse (vitesse), le logo, la taille du logo, la couleur et ainsi de suite.

github: Point de me voir

Si vous vous sentez bien, les petites mains Dodo, encourager l'encouragement à l'auteur une star, si vous aviez voulu atteindre et moi-même sommes prêts à le contrôle des changes, vous pouvez laisser un commentaire ci-dessous, je vous remercie.

Publié 15 articles originaux · louange gagné 10 · vues 10000 +

Je suppose que tu aimes

Origine blog.csdn.net/qwe749082787/article/details/105372683
conseillé
Classement