Овальный градиент в Android
Я знаю, как настроить и отобразить овальную форму. Я знаю, как применить градиент к этой форме. Я не могу понять, как я могу получить овальный градиент, чтобы соответствовать форме.
<?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>
Если вы можете себе представить, этот градиент имеет полупрозрачное белое свечение посередине, а затем исчезает до Альфа-нуля по краям. Мне нужно, чтобы он вышел в овальной форме, а не только в круговом градиенте. Как я могу достичь этого?
4 ответов
Это сложно, так как drawables, определенные таким образом, рисуют себя во время выполнения, адаптируясь к пространству, в которое вы их помещаете. Лучшим решением, если вы должны сделать это в коде, было бы взять форму, которую вы определили в XML, и нарисовать ее на холсте или в растровом изображении как идеальный круг. В этот момент градиентный рисунок будет следовать контуру фигуры. После того, как фигура была нарисована в статическом контексте, вы можете добавить фигуру в представление( например, в качестве фона), которое будет искажать его в овал, когда он пытается соответствовать границам вида. Поскольку у вас есть образ, все будет искажаться пропорционально.
надеюсь, это не пиксель слишком плохо с этим методом.
Я бы предложил более "прямой" подход рисования. Если вы можете рисовать градиент пиксель за пикселем, то вам нужно просто помнить, что для
-
круг цвет градиента пропорционален
r
-
эллипс (овал) цвет градиента пропорционален
r1+r2
здесь:
r - расстояние до центра окружности
r1, r2-расстояния до двух фокусов эллипс
EDIT: Рассмотрим этот пиксельный шейдерный код:
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;
}
вы получите овальный что-то вроде этого:
удачи
<?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"/>
"тупой, но рабочий" способ сделать это-нарисовать контур эллипса, затем множество вложенных эллипсов с тем же "центром", размеры и цвета которого меняются по мере того, как эллипсы становятся меньше, вплоть до эллипса с одним пикселем. Если вы настраиваете свой градиент, интерполируйте цвета в HSV, а не в RVB !