アニメーターをパスにアタッチできますか?キャンバスにアニメーション化された線を描く他の方法はありますか?私が投稿する前にこれを検索しましたが、これについては何もありません。他の2つの投稿 here と here には解決策があり、私には合いません。
OnDrawメソッド内にコードを投稿して、必要なものを正確に指定します。
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);
何か案は????
時間によってキャンバスを変換できます。
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);
}
}
これを試して:
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();
}
}
テストするには、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);
パスにPathMeasure
を作成し、その長さを決定できます。
private PathMeasure pathMeasure; // field
// After you've created your path
pathMeasure = new PathMeasure(path, false);
pathLength = pathMeasure.getLength();
次に、たとえばValueAnimatorの更新リスナー内でgetPosTan()を使用して、パス上の特定のポイントを取得できます。
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();
その後、onDraw(またはその他)の位置を利用できます。
canvas.drawCircle(position[0], position[1], radius, Paint);
このアプローチの利点は、簡単であり、分厚い計算を必要とせず、すべてのAPIで機能することです。
API 21+を使用している場合、ValueAnimatorを使用し、Pathを渡してその位置を使用できます。これはより簡単です。 例SO質問 。