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

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

The newest version!
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 solidShadow;

    private final Paint glancePaint;
    private final Bitmap glance;
    private final Rect glanceFrom;
    private final Rect glanceTo;

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

        this.glance = glance;
        glancePaint = new Paint();
        glancePaint.setDither(true);
        glancePaint.setFilterBitmap(true);
        glanceFrom = new Rect();
        glanceTo = new Rect();
    }

    /**
     * @deprecated Use {@link #GlanceFoldShading(Bitmap)} instead.
     */
    @SuppressWarnings({ "UnusedParameters", "unused" }) // Public API
    @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 > 0f) {
            int alpha = (int) (SHADOW_MAX_ALPHA * intensity);
            solidShadow.setAlpha(alpha);
            canvas.drawRect(bounds, solidShadow);
        }

        boolean isDrawGlance = computeGlance(bounds, rotation, gravity);
        if (isDrawGlance) {
            canvas.drawBitmap(glance, glanceFrom, glanceTo, glancePaint);
        }
    }

    private float getShadowIntensity(float rotation, int gravity) {
        float intensity = 0f;
        if (gravity == Gravity.TOP) {
            if (rotation > -90f && rotation < 0f) { // (-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 > 0f && rotation < 90f) { // (0; 90) - Rotation is applied
                final float aspect = (float) glance.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) (glance.getHeight() / aspect);
                glanceTo.set(bounds.left, bounds.top + distance,
                        bounds.right, bounds.top + distance + scaledGlanceHeight);

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

                // Computing "from" bounds
                int scaledBoundsHeight = (int) (bounds.height() * aspect);
                glanceFrom.set(0, -distanceOnGlance, glance.getWidth(),
                        -distanceOnGlance + scaledBoundsHeight);

                return glanceFrom.intersect(0, 0, glance.getWidth(), glance.getHeight());
            }
        }

        return false;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy