Sweep Gradient : What it is and its examples

前端 未结 2 916
挽巷
挽巷 2021-02-02 13:17

I came across Sweep Gradient on Android and was intrigued if it could give me a better control over the Color spacing and transitions. Did a quick search and found almost nothin

2条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-02 13:55

    The word gradient in this context (as in many graphics editors, including Photoshop) refers to a smooth transition between multiple colors, as opposed to using just a single color to fill an area.

    The Android API provides 3 different gradients: LinearGradient, RadialGradient and SweepGradient.

    These are all subclasses of Shader. You can set a Shader on a Paint object, and then draw any shape with that Paint. The shape will be filled with colors and transitions between them, according to the kind of the gradient.

    For example:

    This image can be produced with this code:

    Bitmap test = Bitmap.createBitmap(640, 200, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(test);
    { // draw a dark gray background
        Paint backgroundPaint = new Paint();
        backgroundPaint.setARGB(255, 24, 24, 24);
        c.drawPaint(backgroundPaint);
    }
    Path heart = new Path();
    { // prepare a heart shape
        heart.moveTo(110, 175);
        heart.lineTo(10, 75);
        RectF leftCircle = new RectF(10, 25, 110, 125);
        heart.arcTo(leftCircle, 180, 180);
        RectF rightCircle = new RectF(110, 25, 210, 125);
        heart.arcTo(rightCircle, 180, 180);
        heart.close();
    }
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setTextSize(18f);
    int[] colors = {
            0xFFFFFF88, // yellow
            0xFF0088FF, // blue
            0xFF000000, // black
            0xFFFFFF88  // yellow
    };
    float[] positions = {0.0f, 0.33f, 0.66f, 1.0f};
    { // draw the left heart
        SweepGradient sweepGradient;
        { // initialize the sweep gradient
            sweepGradient = new SweepGradient(50, 50, colors, positions);
            paint.setShader(sweepGradient);
        }
        c.drawPath(heart, paint);
        c.drawText("SweepGradient", 50, 190, paint);
    }
    { // draw the middle heart
        LinearGradient linearGradient;
        { // initialize a linear gradient
            linearGradient = new LinearGradient(250, 0, 350, 150, colors, positions, Shader.TileMode.CLAMP);
            paint.setShader(linearGradient);
        }
        heart.offset(210, 0); // move the heart shape to the middle
        c.drawPath(heart, paint);
        c.drawText("LinearGradient", 260, 190, paint);
    }
    { // draw the right heart
        RadialGradient radialGradient;
        { // initialize a linear gradient
            radialGradient = new RadialGradient(550, 50, 100, colors, positions, Shader.TileMode.CLAMP);
            paint.setShader(radialGradient);
        }
        heart.offset(210, 0); // move the heart shape to the right
        c.drawPath(heart, paint);
        c.drawText("RadialGradient", 470, 190, paint);
    }
    { // save the bitmap
        String filename = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.png";
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(filename);
            test.compress(Bitmap.CompressFormat.PNG, 90, out);
        } catch (Exception e) {
        } finally {
            try {
                out.close();
            } catch (Exception e) {
            }
        }
    }
    
    • So the LinearGradient is Linear Gradient in Photoshop, RadialGradient is Radial Gradient, and SweepGradient is Angular Gradient, as described in your 3rd reference. I recommend trying these in an image editor first (all popular image editors have these tools), and you'll quickly get the idea of how they work.

    • You can use these gradients in an XML drawable too (like in your 4th reference), with a limitation of using 3 colors maximum.

    • In a SweepGradient, when providing positions, the 0.0 point is at 3 o'clock, going clockwise (with 0.25 being at 6 o'clock, 0.5 at 9 o'clock, 0.75 at 12 o'clock, and 1.0 back at 3 o'clock).

    About your conclusions:

    • As you can see, any shape can be drawn with a SweepGradient, not just a ring. Even the labels are drawn with the gradients in the example above.
    • Yes, the clock's hand analogy is spot on.
    • In usage, SweepGradient is very similar to LinearGradient, except you don't need to provide a TileMode, because you cannot run outside of the bounds of your color list.
    • Yes, you need to provide the coordinates of the center point.

    I hope this clears it up.

提交回复
热议问题