Est-il possible d'attacher un animateur à un chemin? Existe-t-il un autre moyen de dessiner sur des lignes animées sur toile? J'ai cherché avant de poster, mais il n'y a rien à ce sujet. Dans deux autres articles ici et ici il existe des solutions de contournement et ne me conviennent pas.
Je poste mon code dans la méthode onDraw pour spécifier exactement ce que je veux.
Paint.setStyle(Paint.Style.STROKE);
Paint.setStrokeWidth(2);
Paint.setColor(Color.BLACK);
Path path = new Path();
path.moveTo(10, 50); // THIS TRANSFORMATIONS TO BE ANIMATED!!!!!!!!
path.lineTo(40, 50);
path.moveTo(40, 50);
path.lineTo(50, 40);
// and so on...
canvas.drawPath(path, Paint);
Des idées????
Vous pouvez transformer votre toile par le temps, à savoir:
class MyView extends View {
int framesPerSecond = 60;
long animationDuration = 10000; // 10 seconds
Matrix matrix = new Matrix(); // transformation matrix
Path path = new Path(); // your path
Paint paint = new Paint(); // your Paint
long startTime;
public MyView(Context context) {
super(context);
// start the animation:
this.startTime = System.currentTimeMillis();
this.postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
long elapsedTime = System.currentTimeMillis() - startTime;
matrix.postRotate(30 * elapsedTime/1000); // rotate 30° every second
matrix.postTranslate(100 * elapsedTime/1000, 0); // move 100 pixels to the right
// other transformations...
canvas.concat(matrix); // call this before drawing on the canvas!!
canvas.drawPath(path, Paint); // draw on canvas
if(elapsedTime < animationDuration)
this.postInvalidateDelayed( 1000 / framesPerSecond);
}
}
essaye ça:
class PathDrawable extends Drawable implements AnimatorUpdateListener {
private Path mPath;
private Paint mPaint;
private ValueAnimator mAnimator;
public PathDrawable() {
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(0xffffffff);
mPaint.setStrokeWidth(5);
mPaint.setStyle(Style.STROKE);
}
public void startAnimating() {
Rect b = getBounds();
mAnimator = ValueAnimator.ofInt(-b.bottom, b.bottom);
mAnimator.setDuration(1000);
mAnimator.addUpdateListener(this);
mAnimator.start();
}
@Override
public void draw(Canvas canvas) {
canvas.drawPath(mPath, mPaint);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void onAnimationUpdate(ValueAnimator animator) {
mPath.reset();
Rect b = getBounds();
mPath.moveTo(b.left, b.bottom);
mPath.quadTo((b.right-b.left)/2, (Integer) animator.getAnimatedValue(), b.right, b.bottom);
invalidateSelf();
}
}
pour le tester, ajoutez votre méthode onCreate:
TextView view = new TextView(this);
view.setText("click me");
view.setTextColor(0xffcccccc);
view.setGravity(Gravity.CENTER);
view.setTextSize(48);
final PathDrawable d = new PathDrawable();
view.setBackgroundDrawable(d);
OnClickListener l = new OnClickListener() {
@Override
public void onClick(View v) {
d.startAnimating();
}
};
view.setOnClickListener(l);
setContentView(view);
Vous pouvez créer un PathMeasure
pour votre chemin et déterminer sa longueur:
private PathMeasure pathMeasure; // field
// After you've created your path
pathMeasure = new PathMeasure(path, false);
pathLength = pathMeasure.getLength();
Vous pouvez ensuite obtenir un point spécifique sur le chemin en utilisant getPosTan () à l'intérieur, par exemple, l'écouteur de mise à jour de ValueAnimator:
final float[] position = new float[2]; // field
// Inside your animation's update method, where dt is your 0..1 animated fraction
final float distance = dt * pathLength;
pathMeasure.getPosTan(distance, position, null);
// If using onDraw you'll need to tell the view to redraw using the new position
invalidate();
Vous pouvez ensuite utiliser la position dans onDraw (ou autre).
canvas.drawCircle(position[0], position[1], radius, Paint);
Les avantages de cette approche sont qu'elle est simple, ne nécessite pas de calculs volumineux et fonctionne sur toutes les API.
Si vous utilisez l'API 21+, vous pouvez utiliser un ValueAnimator et passer un chemin pour utiliser ses positions, ce qui est plus simple. Exemple SO question .