In order to get the position and angle of the animated bitmap in a distance along a path, we use the code:
pathMeasure = new PathMeasure(animPath, false);
pathLength = pathMeasure.getLength();
...
pathMeasure.getPosTan(distance, pos, tan);
where pos, and tan are float[2] passed to retrieve the resulting position and tangent.
MainActivity.java.
package com.example.androidanimationalongpath;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
/res/layout/activity_main.xml, simple include our custom view in layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidanimationalongpath.MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<com.example.androidanimationalongpath.AnimationView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
AnimationView.java, custom view.
package com.example.androidanimationalongpath;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Toast;
public class AnimationView extends View {
Paint paint;
Bitmap bm;
int bm_offsetX, bm_offsetY;
Path animPath;
PathMeasure pathMeasure;
float pathLength;
float step; //distance each step
float distance; //distance moved
float[] pos;
float[] tan;
Matrix matrix;
public AnimationView(Context context) {
super(context);
initMyView();
}
public AnimationView(Context context, AttributeSet attrs) {
super(context, attrs);
initMyView();
}
public AnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initMyView();
}
public void initMyView(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
bm_offsetX = bm.getWidth()/2;
bm_offsetY = bm.getHeight()/2;
animPath = new Path();
animPath.moveTo(100, 100);
animPath.lineTo(200, 100);
animPath.lineTo(300, 50);
animPath.lineTo(400, 150);
animPath.lineTo(100, 300);
animPath.lineTo(600, 300);
animPath.lineTo(100, 100);
animPath.close();
pathMeasure = new PathMeasure(animPath, false);
pathLength = pathMeasure.getLength();
Toast.makeText(getContext(), "pathLength: " + pathLength, Toast.LENGTH_LONG).show();
step = 1;
distance = 0;
pos = new float[2];
tan = new float[2];
matrix = new Matrix();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(animPath, paint);
if(distance < pathLength){
pathMeasure.getPosTan(distance, pos, tan);
matrix.reset();
float degrees = (float)(Math.atan2(tan[1], tan[0])*180.0/Math.PI);
matrix.postRotate(degrees, bm_offsetX, bm_offsetY);
matrix.postTranslate(pos[0]-bm_offsetX, pos[1]-bm_offsetY);
canvas.drawBitmap(bm, matrix, null);
distance += step;
}else{
distance = 0;
}
invalidate();
}
}
Download the files.
Next:
- Smooth turning along path
More example of Drawing Path on canvas of custom View.
Updated@2016-08-09:
- Custom view to draw bitmap along path, in separate object
Thanks a lot!
ReplyDeleteHi
ReplyDeleteThanks a lot for this code. this is what i am looking for, one question in that i just create a Image move path randomly and it will working fine, but how can i move multiple images on that path can u please help me to solve this issue...?
thanks.
hello Gaurav Mandlik,
ReplyDeletePlease check update version.
Hi Android Eric
ReplyDeleteThanks a lot for Excellent coding, i try your updated code and my work is almost complete. once again thanks.
i just change in your code as per my requirement, but i want a little help from u,i just send u prepareThings() for what i have changes done in this method.
private void prepareThings() {
Paint paint;
Path animPath;
float step;
Bitmap bm;
paint = new Paint();
paint.setColor(Color.TRANSPARENT);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);
bm = BitmapFactory.decodeResource(getResources(), R.drawable.icon_small);
int width = getWindowManager().getDefaultDisplay().getWidth();
int height = getWindowManager().getDefaultDisplay().getHeight();
for (int k=0; k<50; k++){
animPath = new Path();
for (int j = 0; j < 15; j++) {
Random random = new Random();
int fromX = random.nextInt(width);
int fromY = random.nextInt(height);
if (j == 0) {
int toX = random.nextInt(width);
int toY = random.nextInt(height);
animPath.moveTo(toX, toY);
animPath.lineTo(fromX, fromY);
tempX = fromX;
tempY = fromY;
} else {
animPath.lineTo(tempX, tempY);
animPath.lineTo(fromX, fromY);
tempX = fromX;
tempY = fromY;
}
}
step = 10;
animPath.close();
AnimationThing thing = new AnimationThing(paint, animPath, bm, step);
myAnimationView.insertThing(thing);
}
}
as u can see in above code, i just create path randomly and move image is it OK? but when i increase a size of bitmap more then 50 then the move animation is getting slow, can u please tell me why this is happening..?
Once again thanks a lot....
hello Gaurav Mandlik,
ReplyDeleteIt seem that the code canvas.drawPath(thing.animPath, thing.paint) inside onDraw() run slow, remove it if not need.
Hi Andr.oid Eric
ReplyDeleteas per your suggestion i just comment the line which is u notify me, but the result is there is no any image and path not draw and move on canvas.
just more brief explanation, i want to create something like that http://emojisandearthporn.com, is it possible in android if it is then how, please guide me..
Thanks.
???
ReplyDeleteOnly comment the code:
canvas.drawPath(thing.animPath, thing.paint);
as shown here:
http://android-er.blogspot.com/2016/08/custom-view-to-draw-bitmap-along-path_10.html
THANKS A LOT!!!!
ReplyDeleteFantastic job!
Very clear and useful code!
This is exactly what beginners like me -:) must understood in onDraw()