Android: impl text color with gradient
This commit is contained in:
parent
4a0c8bd171
commit
a1240cfa2e
@ -15,9 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package pub.doric.shader;
|
package pub.doric.shader;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.LinearGradient;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.Shader;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
|
import android.text.Layout;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
@ -71,7 +77,7 @@ public class TextNode extends ViewNode<TextView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void blend(TextView view, String name, JSValue prop) {
|
protected void blend(final TextView view, String name, final JSValue prop) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case "text":
|
case "text":
|
||||||
if (!prop.isString()) {
|
if (!prop.isString()) {
|
||||||
@ -86,10 +92,83 @@ public class TextNode extends ViewNode<TextView> {
|
|||||||
view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, prop.asNumber().toFloat());
|
view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, prop.asNumber().toFloat());
|
||||||
break;
|
break;
|
||||||
case "textColor":
|
case "textColor":
|
||||||
if (!prop.isNumber()) {
|
if (prop.isNumber()) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
view.setTextColor(prop.asNumber().toInt());
|
view.setTextColor(prop.asNumber().toInt());
|
||||||
|
} else if (prop.isObject()) {
|
||||||
|
view.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final JSObject dict = prop.asObject();
|
||||||
|
|
||||||
|
LinearGradient linearGradient = null;
|
||||||
|
|
||||||
|
int[] colors = null;
|
||||||
|
float[] locations = null;
|
||||||
|
|
||||||
|
if (dict.propertySet().contains("colors")) {
|
||||||
|
JSValue colorsValue = dict.getProperty("colors");
|
||||||
|
if (colorsValue.isArray()) {
|
||||||
|
colors = colorsValue.asArray().toIntArray();
|
||||||
|
}
|
||||||
|
if (dict.propertySet().contains("locations")) {
|
||||||
|
JSValue locationsValue = dict.getProperty("locations");
|
||||||
|
if (locationsValue.isArray()) {
|
||||||
|
locations = locationsValue.asArray().toFloatArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (dict.propertySet().contains("start") && dict.propertySet().contains("end")) {
|
||||||
|
JSValue start = dict.getProperty("start");
|
||||||
|
JSValue end = dict.getProperty("end");
|
||||||
|
if (start.isNumber() && end.isNumber()) {
|
||||||
|
colors = new int[]{start.asNumber().toInt(), end.asNumber().toInt()};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (colors == null) {
|
||||||
|
colors = new int[]{Color.TRANSPARENT, Color.TRANSPARENT};
|
||||||
|
}
|
||||||
|
|
||||||
|
JSValue orientation = dict.getProperty("orientation");
|
||||||
|
|
||||||
|
float width = view.getMeasuredWidth();
|
||||||
|
float height = view.getMeasuredHeight();
|
||||||
|
|
||||||
|
float angle = 0;
|
||||||
|
|
||||||
|
if (orientation.isNumber()) {
|
||||||
|
switch (orientation.asNumber().toInt()) {
|
||||||
|
case 0:
|
||||||
|
angle = 270;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
angle = (float) Math.toDegrees(Math.atan2(-width, -height));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
angle = 180;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
angle = (float) Math.toDegrees(Math.atan2(width, -height));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
angle = 90;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
angle = (float) Math.toDegrees(Math.atan2(width, height));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
angle = 0;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
angle = (float) Math.toDegrees(Math.atan2(-width, height));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setGradientTextColor(view, angle, colors, locations);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "textAlignment":
|
case "textAlignment":
|
||||||
if (!prop.isNumber()) {
|
if (!prop.isNumber()) {
|
||||||
@ -239,4 +318,44 @@ public class TextNode extends ViewNode<TextView> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setGradientTextColor(final TextView textView, final float angle, final int[] colors, final float[] positions) {
|
||||||
|
final Rect textBound = new Rect(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||||
|
|
||||||
|
final Layout layout = textView.getLayout();
|
||||||
|
for (int i = 0; i < textView.getLineCount(); i++) {
|
||||||
|
float left = layout.getLineLeft(i);
|
||||||
|
float right = layout.getLineRight(i);
|
||||||
|
if (left < textBound.left) textBound.left = (int) left;
|
||||||
|
if (right > textBound.right) textBound.right = (int) right;
|
||||||
|
}
|
||||||
|
textBound.top = layout.getLineTop(0);
|
||||||
|
textBound.bottom = layout.getLineBottom(textView.getLineCount() - 1);
|
||||||
|
if (textView.getIncludeFontPadding()) {
|
||||||
|
Paint.FontMetrics fontMetrics = textView.getPaint().getFontMetrics();
|
||||||
|
textBound.top += (fontMetrics.ascent - fontMetrics.top);
|
||||||
|
textBound.bottom -= (fontMetrics.bottom - fontMetrics.descent);
|
||||||
|
}
|
||||||
|
|
||||||
|
double angleInRadians = Math.toRadians(angle);
|
||||||
|
|
||||||
|
double r = Math.sqrt(Math.pow(textBound.bottom - textBound.top, 2) +
|
||||||
|
Math.pow(textBound.right - textBound.left, 2)) / 2;
|
||||||
|
|
||||||
|
float centerX = textBound.left + (textBound.right - textBound.left) / 2.f;
|
||||||
|
float centerY = textBound.top + (textBound.bottom - textBound.top) / 2.f;
|
||||||
|
|
||||||
|
float startX = (float) (centerX - r * Math.cos(angleInRadians));
|
||||||
|
float startY = (float) (centerY + r * Math.sin(angleInRadians));
|
||||||
|
|
||||||
|
float endX = (float) (centerX + r * Math.cos(angleInRadians));
|
||||||
|
float endY = (float) (centerY - r * Math.sin(angleInRadians));
|
||||||
|
|
||||||
|
Shader textShader = new LinearGradient(startX, startY, endX, endY, colors, positions,
|
||||||
|
Shader.TileMode.CLAMP);
|
||||||
|
|
||||||
|
textView.setTextColor(Color.WHITE);
|
||||||
|
textView.getPaint().setShader(textShader);
|
||||||
|
textView.invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user