2013-09-04 160 views
26

Có thể đính kèm trình hoạt ảnh vào đường dẫn không? Có cách nào khác để vẽ trên dòng hoạt hình vải không? Tôi đã tìm kiếm điều này trước khi tôi đăng bài, nhưng không có gì về điều này. Trong hai bài đăng khác, herehere có các giải pháp đi bộ xung quanh và không phù hợp với tôi. Cảm ơn bạn!Cách tạo hoạt ảnh cho đường dẫn trên canvas - android

Tôi đăng mã của mình bên trong phương thức onDraw để chỉ định chính xác tôi muốn gì.

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); 

Bất kỳ ý tưởng nào ????

+0

Đồng thời thêm một số mã của bạn. Điều này sẽ giúp giải thích cách bạn muốn. – Nizam

Trả lời

40

Bạn có thể chuyển đổi canvas của bạn theo thời gian, ví dụ:

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); 
    } 

} 
+1

giải pháp này làm việc cho tôi sau khi một số điều chỉnh .. Cảm ơn bạn – karvoynistas

+0

Điều gì về vòng tròn? Tôi có nghĩa là, làm thế nào tôi có thể animate vẽ vòng cung hoặc hình bầu dục? – user3111850

+0

Thực hiện 2 thay đổi. 1: thêm invalidate(); 2. matrix.postRotate (30.0f); Dòng ma trận.postRotate (30 * elapsedTime/1000); sẽ khiến hoạt ảnh của bạn quá nhanh. –

17

thử điều này:

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(); 
    } 
} 

để kiểm tra nó thêm vào phương pháp onCreate của bạn:

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); 
+1

Vẽ dòng ngay lập tức, không có hoạt ảnh – azizbekian

+0

mã hoạt động .. nhưng tôi muốn đặt nền tròn của bất kỳ màu nào cùng với đột quỵ như bạn đã đề cập. Có ý tưởng nào không? –

+0

không chắc chắn những gì bạn cần ... hình ảnh có thể? – pskink

1

Bạn có thể tạo số PathMeasure cho đường dẫn của bạn và xác định độ dài của đường dẫn:

private PathMeasure pathMeasure; // field 

// After you've created your path 
pathMeasure = new PathMeasure(path, false); 
pathLength = pathMeasure.getLength(); 

Sau đó bạn có thể nhận được một điểm cụ thể trên con đường sử dụng getPosTan() bên trong, chẳng hạn, một ValueAnimator update nghe:

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(); 

Sau đó bạn có thể tận dụng các vị trí trong OnDraw (hoặc bất kỳ).

canvas.drawCircle(position[0], position[1], radius, paint); 

Ưu điểm của phương pháp này là đơn giản, không yêu cầu toán học chunky và hoạt động trên tất cả các API.

Nếu sử dụng API 21+, bạn có thể sử dụng ValueAnimator và chuyển vào Đường dẫn để sử dụng vị trí của nó, đơn giản hơn. Example SO question.