【问题标题】:Oval Gradient in AndroidAndroid中的椭圆渐变
【发布时间】:2010-08-20 01:25:03
【问题描述】:

我知道如何设置和显示椭圆形。我知道如何对这个形状应用渐变。我想不通的是如何获得一个椭圆渐变来匹配形状。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval" >
    <gradient
        android:startColor="#66FFFFFF"
        android:endColor="#00FFFFFF"
        android:gradientRadius="100"
        android:type="radial" />
</shape>

如果你能想象,这个渐变在中间有一个半透明的白光,然后在边缘淡化为 alpha 零。我需要让它呈椭圆形,而不仅仅是圆形渐变。我怎样才能做到这一点?

【问题讨论】:

  • 我已经通过调用Canvas#scale 解决了类似的问题,然后在其上绘制GradientDrawable

标签: android graphics gradient shape


【解决方案1】:

我会建议更“直接”的绘图方法。如果您可以逐像素绘制渐变,那么您只需要记住这一点

  • 圆形渐变颜色与r成正比
  • 椭圆(椭圆)渐变颜色与r1+r2成正比

这里:

r - 到圆心的距离

r1,r2 - 到椭圆的两个焦点的距离

编辑: 考虑这个像素着色器代码:

uniform sampler2D tex;

void main()
{
    vec2 center = vec2(0.5,0.5);
    float len = 1.3*(distance(gl_TexCoord[0].xy,center));
    vec2 foc1 = vec2(len,0.);
    vec2 foc2 = vec2(-len,0.);
    float r = distance(center+foc1,gl_TexCoord[0].xy) +
             distance(center+foc2,gl_TexCoord[0].xy);
    float k = pow(r*0.9,1.3);
    vec4 color = vec4(k,k,k,1.);
    gl_FragColor = color;
}

你会得到类似这样的椭圆形:

祝你好运

【讨论】:

  • 这也许可以,但似乎很贵。
  • 这取决于如何执行每像素计算。如果在 GPU 端执行(作为梯度计算 Pixel Shader)——那么它就像闪电一样快:)
【解决方案2】:
<?xml version="1.0" encoding="utf-8"?>

<stroke android:width="1dp" android:color="#ffffffff" />

<size
    android:width="40dp"
    android:height="40dp"/>

<gradient
    android:type="radial"
    android:startColor="#ffff0000"
    android:endColor="#330000ff"
    android:gradientRadius="40dp"
    android:angle="270"
    android:centerX=".5"
    android:centerY=".5"/>

【讨论】:

    【解决方案3】:

    这很困难,因为以这种方式定义的可绘制对象在运行时绘制自己,以适应您放置它们的空间。如果您必须在代码中执行此操作,最好的解决方案是采用您在 XML 中定义的可绘制形状并将其绘制到 Canvas 或 Bitmap 上作为一个完美的圆圈。此时,渐变图案将跟随形状轮廓。一旦将形状绘制到静态上下文中,您就可以将形状添加到视图中(例如作为背景),当它试图适应视图边界时,这会将其扭曲为椭圆形。既然你有一个图像,整个事情就会按比例扭曲。

    希望这种方法不会像素太差。

    【讨论】:

    【解决方案4】:

    执行此操作的“愚蠢但有效”的方法是绘制椭圆轮廓​​,然后绘制多个具有相同“中心”的嵌套椭圆,其大小和颜色会随着椭圆变小而变化,一直到一像素椭圆。 如果您自定义编码渐变,在 HSV 中插入颜色,而不是在 RVB 中!

    【讨论】:

    • 这个建议可行,但请注意,您添加的每一层都是您的 GPU 必须在屏幕上绘制的另一层。我试过一次,整个应用程序都停止了。
    【解决方案5】:

    我发现的另一个解决方法是使用 scaleX="1.x" 或 scaleY="1.x"。但是,这与形状不符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 2012-12-19
      相关资源
      最近更新 更多