All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alexvasilkov.foldablelayout.shading.GlanceFoldShading Maven / Gradle / Ivy

package com.alexvasilkov.foldablelayout.shading;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.Gravity;

public class GlanceFoldShading implements FoldShading {

    private static final int SHADOW_COLOR = Color.BLACK;
    private static final int SHADOW_MAX_ALPHA = 192;

    private final Paint mSolidShadow;

    private final Paint mGlancePaint;
    private final Bitmap mGlance;
    private final Rect mGlanceFrom;
    private final Rect mGlanceTo;

    public GlanceFoldShading(Bitmap glance) {
        mSolidShadow = new Paint();
        mSolidShadow.setColor(SHADOW_COLOR);

        mGlance = glance;
        mGlancePaint = new Paint();
        mGlancePaint.setDither(true);
        mGlancePaint.setFilterBitmap(true);
        mGlanceFrom = new Rect();
        mGlanceTo = new Rect();
    }

    @SuppressWarnings("UnusedParameters")
    @Deprecated
    public GlanceFoldShading(Context context, Bitmap glance) {
        this(glance);
    }

    @Override
    public void onPreDraw(Canvas canvas, Rect bounds, float rotation, int gravity) {
        // NO-OP
    }

    @Override
    public void onPostDraw(Canvas canvas, Rect bounds, float rotation, int gravity) {
        float intensity = getShadowIntensity(rotation, gravity);

        if (intensity > 0) {
            int alpha = (int) (SHADOW_MAX_ALPHA * intensity);
            mSolidShadow.setAlpha(alpha);
            canvas.drawRect(bounds, mSolidShadow);
        }

        boolean isDrawGlance = computeGlance(bounds, rotation, gravity);
        if (isDrawGlance) {
            canvas.drawBitmap(mGlance, mGlanceFrom, mGlanceTo, mGlancePaint);
        }
    }

    private float getShadowIntensity(float rotation, int gravity) {
        float intensity = 0;
        if (gravity == Gravity.TOP) {
            if (rotation > -90 && rotation < 0) { // (-90; 0) - rotation is applied
                intensity = -rotation / 90f;
            }
        }
        return intensity;
    }

    private boolean computeGlance(Rect bounds, float rotation, int gravity) {
        if (gravity == Gravity.BOTTOM) {
            if (rotation > 0 && rotation < 90) { // (0; 90) - rotation is applied
                final float aspect = (float) mGlance.getWidth() / (float) bounds.width();

                // computing glance offset
                final int distance = (int) (bounds.height() * ((rotation - 60f) / 15f));
                final int distanceOnGlance = (int) (distance * aspect);

                // computing "to" bounds
                int scaledGlanceHeight = (int) (mGlance.getHeight() / aspect);
                mGlanceTo.set(bounds.left, bounds.top + distance,
                        bounds.right, bounds.top + distance + scaledGlanceHeight);

                if (!mGlanceTo.intersect(bounds)) {
                    // glance is not visible
                    return false;
                }

                // computing "from" bounds
                int scaledBoundsHeight = (int) (bounds.height() * aspect);
                mGlanceFrom.set(0, -distanceOnGlance, mGlance.getWidth(),
                        -distanceOnGlance + scaledBoundsHeight);

                return mGlanceFrom.intersect(0, 0, mGlance.getWidth(), mGlance.getHeight());
            }
        }

        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy