Creating a shadow around a canvas drawn shape?
Asked Answered
B

3

26

What steps are required to create a shape e.g. rectangle with a shadow from scratch using a Canvas?

Adding a shadow layer to the paint used to draw the rectangle yielded no success.

Bulimia answered 7/8, 2013 at 9:19 Comment(0)
B
57

No need for a Bitmap, just needed to set the layer type to LAYER_TYPE_SOFTWARE the original approach worked.

public class TestShapeShadow extends View
{
    Paint paint;

    public TestShapeShadow(Context context)
    {
       super(context);  

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setShadowLayer(12, 0, 0, Color.YELLOW);

        // Important for certain APIs 
        setLayerType(LAYER_TYPE_SOFTWARE, paint);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {   
        canvas.drawRect(20, 20, 100, 100, paint);
    }
}
Bulimia answered 7/8, 2013 at 11:9 Comment(4)
Good but had issues using it in xml. Had to change the constructor to TestShapeShadow(Context context, AttributeSet attrs)Weld
LAYER_TYPE_SOFTWARE degrades the performance. It's visible while doing any animation. Without LAYER_TYPE_SOFTWARE it doesn't work.Illyria
setLayerType(LAYER_TYPE_SOFTWARE, paint) this line causes onDraw to be called recursively. Any idea how to solve this?Edwardedwardian
In kotlin necessary line is: paint.setShadowLayer(12f, 0f, 0f, Color. YELLOW)Ironwork
K
14

I followed the ideas in @pskink's answer and found a solution. I put the code snippet here for anyone in need.

public class MyViewWithShadow extends View {

    Paint paint;
    int mainColor;
    int shadowColor;

    // shadow properties
    int offsetX = -25;
    int offsetY = 30;
    int blurRadius = 5;

    public MyViewWithShadow(Context context)
    {
        super(context);

        mainColor = Color.RED;
        shadowColor = Color.BLACK; // this color can also have alpha

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {   
        // Create paint for shadow
        paint.setColor(shadowColor);
        paint.setMaskFilter(new BlurMaskFilter(
            blurRadius /* shadowRadius */,
            BlurMaskFilter.Blur.NORMAL));

        // Draw shadow before drawing object
        canvas.drawRect(20 + offsetX, 20 + offsetY, 100 + offsetX, 100 + offsetY, paint);

        // Create paint for main object
        paint.setColor(mainColor);
        paint.setMaskFilter(null);

        // Draw main object 
        canvas.drawRect(20, 20, 100, 100, paint);
    }
}

[Link is now broken:]

If you wonder what shadow properties are, you can refer to this tester: https://okawa-h.github.io/box-shadow_tester/~

Kaleidoscope answered 19/5, 2020 at 1:56 Comment(0)
A
7
  1. create. a Path, add some elements to it

  2. set BlurMaskFilter to a Paint

  3. draw a path with dx, dy shadow offset

  4. unset mask filter

  5. draw a path again with no. offset

Aeroplane answered 7/8, 2013 at 9:33 Comment(2)
Do you have any example for this?Azole
We would really appreciate you could provide example or some code snippet.Pinwheel

© 2022 - 2024 — McMap. All rights reserved.