My Class extends Renderer(org.rajawali3d.renderer.Renderer)
Following function in the class is called from activity :
public void makeText(float[] openGLPpoint, int color, String text,float depth)
{
double adjust_angle_o = 0;
Material mSphereMaterial = new Material();
Bitmap bitmap= setTextInImage(text);
Texture t = new Texture("text",bitmap);
mSphereMaterial.addTexture(t);
Object3D object3D = new Plane(0.3f,0.1f,100,100);
object3D.setMaterial(mSphereMaterial);
object3D.setDoubleSided(true);
object3D.setColor(color);
if(!depth >= 1)
{
adjust_angle_o = 0.2;
}
object3D.setPosition(openGLPpoint[0],
openGLPpoint[1],
openGLPpoint[2]-adjust_angle_o);
getCurrentScene().addChild(object3D);
}
public Bitmap setTextInImage(String text){
Bitmap src =
BitmapFactory.decodeResource(mContext.getResources(),R.drawable.label_bg_sm);
Bitmap dest =
Bitmap.createBitmap(src.getWidth(),
src.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas cs = new Canvas(dest);
Paint tPaint = new Paint();
tPaint.setTextSize(50 * mContext.getResources().getDisplayMetrics().density);
tPaint.setColor(Color.GREEN);
tPaint.setStyle(Paint.Style.FILL_AND_STROKE);
tPaint.setFakeBoldText(true);
cs.drawBitmap(src, 0f, 0f, null);
float height = tPaint.measureText("yY");
float width_o = tPaint.measureText(text+" m");
float x_coord = (src.getWidth() - width_o)/2;
// 15f is to put space between top edge and the text
cs.drawText(text+" m", x_coord, height+15f, tPaint);
return dest;
}
I need the factor object3D.setDoubleSided(true); , which is working fine .
The text is correct when seen from front view but when the object is seen from the rear side , the text naturally mirrors .
Following is a snap :
Mirrored text observed from rear view
How can the text be corrected , as it should be readable from both front and rear views ? Any articles to fix text-mirroring ?
I figured it out , object3D.setDoubleSided(false) created a duplicate object and rotated it 180 at y axis . It worked fine now .
Edit : The rotated side is showing dark then the original . Increasing alpha isnt working. Can anyone guide futher ?
Related
Here the link of GitHub Code https://github.com/thanhniencung/LuckyWheel
I try to change the rotation of canvas using this piece of code
private void drawText(Canvas canvas, float tmpAngle, float sweepAngle, String mStr) {
Path path = new Path();
path.addArc(mRange,tmpAngle,sweepAngle);
float textWidth = mTextPaint.measureText(mStr);
int hOffset = (int) (mRadius * Math.PI / mLuckyItemList.size()/2-textWidth/2);
int vOffset = mRadius/2/4;
canvas.drawTextOnPath(mStr, path, hOffset, vOffset, mTextPaint);
}
I want to change orientation of text like picture shown below
In the latest version of the LuckyWheel, when initialising LuckyItems data, you can set the values for luckyItem.secondaryText instead of luckyItem.topText, and you will have the wanted text orientation.
Like this:
List<LuckyItem> data = new ArrayList<>();
for (int i = 0; i < sectorsTitles.length; i++) {
LuckyItem luckyItem = new LuckyItem();
// luckyItem.topText = sectorsTitles[i]; // Don't use this
luckyItem.secondaryText = sectorsTitles[i]; // Use this instead
luckyItem.color = Color.parseColor(ROULETTE_COLORS[i]);
data.add(luckyItem);
}
luckyWheelView.setData(data);
In XML code you can change the rotation by using
android:rotation="120" (Then any angle you want positive or negative)
But, you may need to rotate this image when it is in the bottom and then rotate it again when it is in the top. So you can rotate it programatically whenever you want.
TextView textView = findViewById(R.id.textView);
ImageView imageView = findViewById(R.id.imageView);
textView.setRotation(120);
imageView.setRotation(120);
And then if you want to comeback it latter to the position it was in the beginning. You just add the negative sign.
textView.setRotation(-120);
imageView.setRotation(-120);
Of course, the angle is up to you.
I've got a problem with a custom view i use. It draws a grid that i use to represent a floorplan, with a start and current position on it (colored rectangles).
(Code here: https://pastebin.com/8SExmtAp).
In short, i initialize different paints like this:
private void initPaints()
{
waypointPaint = new Paint(Color.parseColor("#800080"));
currentCoordinatePaint = new Paint(Color.RED);
linePaint = new Paint(Color.BLACK);
startCoordinatePaint = new Paint(Color.BLUE);
}
and use them in onDraw() like this:
// color the current coordinates
Coordinates currentCoords = Model.getCurrentCoordinates();
if (currentCoords != null)
{
canvas.drawRect((float) currentCoords.getX() * cellWidth, (float) currentCoords.getY() * cellHeight,
(float) (currentCoords.getX() + 1) * cellWidth, (float) (currentCoords.getY() + 1) * cellHeight,
currentCoordinatePaint);
}
Coordinates startCoordinate = Model.startCoordinate;
if (startCoordinate != null && startCoordinate != currentCoords)
{
canvas.drawRect((float) startCoordinate.getX() * cellWidth, (float) startCoordinate.getY() * cellHeight,
(float) (startCoordinate.getX() + 1) * cellWidth, (float) (startCoordinate.getY() + 1) * cellHeight,
startCoordinatePaint);
}
However, instead of getting a blue one for the startposition and a red one for the current position, both of them are black, see:
Screenshot of app
The documentation on the drawRect(...) Method i use just states the following:
Draw the specified Rect using the specified paint. The rectangle will be filled or framed based on the Style in the paint.
So..i don't really see where the code is wrong and why i am getting the result i get. Maybe someone of you knows why?
Paint constructor you are using expects int flags as a parameter, not the fill color.
Try:
currentCoordinatePaint = new Paint();
currentCoordinatePaint.setStyle(Paint.Style.FILL);
currentCoordinatePaint.setColor(Color.RED);
Like josef.adamcik statet, i was wrong about the constructors i used for the paint objects. Changing the code to
private void initPaints()
{
waypointPaint = new Paint();
waypointPaint.setColor(Color.GREEN);
waypointPaint.setStyle(Paint.Style.FILL);
currentCoordinatePaint = new Paint();
currentCoordinatePaint.setColor(Color.RED);
currentCoordinatePaint.setStyle(Paint.Style.FILL);
linePaint = new Paint();
linePaint.setColor(Color.BLACK);
linePaint.setStyle(Paint.Style.STROKE);
startCoordinatePaint = new Paint();
startCoordinatePaint.setColor(Color.BLUE);
startCoordinatePaint.setStyle(Paint.Style.FILL);
}
did the trick.
I'm working on an Android app utilizing xamarin and the oxyplot library. I ran into a problem where I cannot add multiple lines of text in TextAnnotation.
I tried the following options:
var sb = new StringBuilder();
sb.Append("Line1");
sb.AppendLine(); // which is equal to Append(Environment.NewLine);
sb.Append("\n");
sb.Append("\r\n");
sb.Append(System.Environment.NewLine);
sb.Append("Line2");
and added it like so to the TextAnnotation text object:
var textAnnotation1 = new TextAnnotation();
textAnnotation1.Text = sb.ToString();
textAnnotation1.Background = OxyColors.White;
textAnnotation1.TextColor = OxyColors.Black;
textAnnotation1.FontSize = 18;
textAnnotation1.TextPosition = new DataPoint(4,_vericalLineYaxis);
plotModel.Annotations.Add(textAnnotation1);
but all to avail.
My goal is to have the text appear like so:
Line 1
Line 2
Currently it's appearing as:
Line 1 Line2
Any help would be much appreciated.
Multi-line Annotations is not currently supported on the Android platform.
OxyPlot is invoking Android.Canvas.DrawText and that function does not support text wrapping, it is a fairly low-level primitive drawing routine.
Google's Doc: public void drawText (String text, float x, float y, Paint paint)
If you feel like mod'ing the source, this could be done by using a static layout vs. the current canvas.DrawText.
Something like this would get you started (but is untested):
public void DrawText (string text, float x, float y, Paint paint)
{
TextPaint textPaint = new TextPaint();
StaticLayout textLayout = new StaticLayout(text, textPaint, canvas.getWidth(), Alignment.ALIGN_NORMAL, 1.0f, 0.0f, False);
canvas.Save();
canvas.Translate(x, y);
textLayout.Draw(canvas);
canvas.Restore();
}
FYI: Oxyplot's SVG renderer manually handles multi-line text by string splitting on "\r\n" and rendering a separate element for each line so the same thing could be done for the Android instead of using a StaticLayout (slower performance wise, but easy to mod/test):
var lines = Regex.Split(text, "\r\n");
if (valign == VerticalAlignment.Bottom)
{
for (var i = lines.Length - 1; i >= 0; i--)
{
var line = lines[i];
var size = this.MeasureText(line, fontFamily, fontSize, fontWeight);
this.w.WriteText(p, line, c, fontFamily, fontSize, fontWeight, rotate, halign, valign);
p += new ScreenVector(Math.Sin(rotate / 180.0 * Math.PI) * size.Height, Math.Cos(rotate / 180.0 * Math.PI) * size.Height);
}
}
I have an image e.g. the image shown below:
This image has two parts part 1 of size width W and height L and part 2 (smaller part) of width w and height h (call part one as source and part 2 as destination). Let the coordinates of the 1st rectangle be (measured from top left corner): top:100 left: 10 right: 200 bottom: 300 and the coordinates of the 2nd rectangle be (as measured from top left corner): top 50 left: 500 bottom: 100 right: 700
I want to animate from source to destination such that the image translates and zooms in from source to destination.
So my first screen would look like:
and my second image would look like:
How do I tween between these two ?
My code (without animation) looks like as follows:
public class SuperGame extends View implements OnGestureListener
{
int sreenHeight, screenWidth;
int drawCount = 0;
Bitmap bg;
public SuperGame(Context context, Bitmap bmp)
{
this.screenWidth = getContext().getResources().getDisplayMetrics().widthPixels;
this.screenHeight = getContext().getResources().getDisplayMetrics().heightPixels;
bg = BitmapFactory.decodeResource(getResources(),R.drawable.bg_img);
}
#Override
/* this function triggers the image change
*/
public boolean onDown(MotionEvent e) {
invalidate(0,0,screenWidth, screenHeight);
return true;
}
#Override
public void onDraw(Canvas canvas)
{
Rect dest = new Rect(0,0,screenWidth, screenHeight);
if (count==0) //draw the first image part
{
count=1;
Rect src = new Rect(100,10,200,300);//coordinates of rectangle 1
canvas.drawBitmap(bg, src, dest, new Paint());
}
else //draw the second image part - (I'd like to show movement/ transition between these)
{
Rect src = new Rect(50,500,100,700);//coordinates of rectangle 2
count=0;
canvas.drawBitmap(bg, src, dest, new Paint());
}
}
}
How to I animate the transition (which involves zoomin as well as translation)?
You might need to create a custom valueAnimator of type Rect/RectF.
Code example given below:
public class RectFEvaluator
implements TypeEvaluator<RectF>
{
#Override
public RectF evaluate(float fraction, RectF srcRect, RectF destRect) {
RectF betweenRect = new RectF();
betweenRect.bottom = srcRect.bottom + fraction*(destRect.bottom-srcRect.bottom);
betweenRect.top = srcRect.top + fraction*(destRect.top-srcRect.top);
betweenRect.left = srcRect.left + fraction*(destRect.left-srcRect.left);
betweenRect.right = srcRect.right + fraction*(destRect.right-srcRect.right);
return betweenRect;
}
}
The value animator will give you the intermediate values between src Rect and dest Rect.
Once you have these values, updated them using an animation
I'm painting text over a background image on a canvas. I move the image interactively (like a Ouija board pointer). I've set the canvas to black, the pointer is red and I want to write white text over it so that the pointer has a player's name on it.
In Android 2.3.4 it appears as solid white text on top of the red pointer which is pretty clear, but I'd like to use any color. In Android 4.1.2 I can barely see the white text. Here's my code:
public Pointer(Context context) {
super(context);
paintBg = new Paint();
paintBg.setColor(Color.BLACK);
paintName = new Paint();
paintName.setColor(Color.WHITE);
paintName.setTextSize(50); // set text size
paintName.setStrokeWidth(5);
paintName.setTextAlign(Paint.Align.CENTER);
this.setImageResource(res); // pointer.png in res/drawable folder
Drawable d = getResources().getDrawable(res);
h = d.getIntrinsicHeight();
w = d.getIntrinsicWidth();
canvas = new Canvas();
canvas.drawPaint(paintBg);//make background black
// float imageScale = width / w; // how image size scales with screen
}
#Override
public void onDraw(Canvas canvas) {
y = this.getHeight() / 2; // center of screen
x = this.getWidth() / 2;
int left = Math.round(x - 0.8f * w);
int right = Math.round(x + 0.8f * w);
canvas.save();
canvas.rotate((direction + 180) % 360, x, y); // rotate to normal
canvas.drawText(s, x, y + 20, paintName); // draw name
canvas.restore();
canvas.rotate(direction, x, y); // rotate back
super.onDraw(canvas);
}
What changed in 4.1.2 that would affect this, or am I doning something incorrectly? Thanks for your help with this as it's driving me crazy.
Edit to include screen shots:
Android 2.3.4
Android 4.1.2
Note how the white text appears to be on top in 2.3.4 while it appears below or muddy in 4.1.2.
As free3dom pointes out it is related to alpha. I do change alpha because if I don't, the text does not appear on top of the arrow. It appears that the ImageView having the pointer image is always on top - could this be what's going on?
Here is how I handle setting alpha:
public static void setAlpha(View view, float alpha, int duration) {
if (Build.VERSION.SDK_INT < 11) {
final AlphaAnimation animation = new AlphaAnimation(alpha, alpha);
animation.setDuration(duration);
animation.setFillAfter(true);
view.startAnimation(animation);
} else //for 11 and above
view.setAlpha(alpha);
}
Maybe it has something to do with using this.setImageResource(res) to set the image resource? According to android developer guide, I can only set alpha to the single view and everything in the view is changed. Yet if I lower the alpha, the arrow image seems to become transparent enough to allow me to see the text.
You set a stroke width, but never indicate that stroke should be used for the Paint.
Try adding
paintName.setStyle( FILL_AND_STROKE );