2011-07-27 26 views
5

thể trùng lặp:
Android, move bitmap along a path?Vấn đề để đạt được hoạt hình cong

tôi muốn di chuyển một hình ảnh thông qua một path.Is cong Có thể trong android? Tôi đã tìm kiếm rất nhiều nhưng tôi chỉ có thể tìm thấy về quy mô, xoay và dịch hoạt hình. Bất kỳ ai có bất kỳ ý tưởng xin vui lòng help.Is nó có thể trong Android?

+0

Xem câu trả lời này: [Chuẩn bị đường cong dịch hoạt hình trong Android] (http://stackoverflow.com/questions/8354441/how-to-prepare-curve-translate-animation-for- android/27948353 # 27948353) – Sheharyar

Trả lời

1

Bạn có thể thực hiện Hoạt ảnh theo khung. Bạn có thể định vị đối tượng từng bước để tạo đường cong. Điều đó sẽ được tái sử dụng hạn chế, nhưng bạn có thể làm điều đó.

Hoặc bạn có thể viết hoạt ảnh của riêng mình để tạo một lớp con của TweenAnimation có thể tạo hình động dọc theo một đường cong. Nếu bạn tốt với toán học và có thể hiểu được đường cong bezier thì đó có thể là một lựa chọn thẳng về phía trước. Một khi bạn có lớp đó, bạn có thể dễ dàng tạo hiệu ứng động trên bất kỳ đường cong nào, nhưng nó hoạt động nhiều hơn.

http://en.wikipedia.org/wiki/B%C3%A9zier_curve

Dưới đây là một số mã Java:

http://www.math.ubc.ca/~cass/gfx/bezier.html

+0

Thanks.Bạn có bất kỳ ví dụ hoặc liên kết nào của bất kỳ bài đăng nào không? –

+0

Bạn có thể cho tôi biết làm cách nào tôi có thể tạo lớp hoạt hình của riêng mình làm lớp con của tweenanimation. –

9

Dưới đây là mã đầy đủ chức năng mà sẽ động dọc theo một con đường cong được xác định bởi ba điểm. Một điểm chỉ là một lớp giữ một giá trị x và một giá trị y (mặc dù bạn có thể dễ dàng mở rộng nó cho nhiều thứ nguyên hơn).

Tất cả các biến m được lấy từ TranslateAnimation và được sử dụng theo cách tương tự, vì vậy bạn có thể so sánh nó với mã TranslateAnimation tương đối không hài lòng nếu có điều gì đó không hợp lý.

Các cuộc gọi để giải quyếtSize in initialize có nghĩa là bạn có thể chỉ định bắt đầu, kết thúc và bán kính của vòng cung bằng bất kỳ loại hoạt ảnh nào (ABSOLUTE, RELATIVE_TO_SELF, RELATIVE_TO_PARENT) giống như bạn làm cho một TranslateAnimation bình thường.

calcBezier tính đường cong bezier bậc hai được lấy trực tiếp từ Wikipedia. Đường cong Bezier được cho là cho phép mở rộng quy mô trơn tru và phổ biến trong đồ họa (và cũng được sử dụng trong lớp Đường dẫn của Android).

Chuyển động thực tế xảy ra trong applyTransformation. interpolatedTime cho một giá trị từ 0 đến 1, làm tăng phi tuyến tùy thuộc vào nội suy cung cấp. dx và dy là các điểm x và y thực tế dọc theo đường cong trong một thời gian nhất định.

Hạn chế duy nhất của lớp này là thay đổi lớn nhất trong y luôn xảy ra ở trung tâm của đường cong (xem tính toán cho trungX trong khởi tạo). Tuy nhiên, nó sẽ dễ dàng sửa đổi, ví dụ, để cung cấp cho một điểm cụ thể dọc theo đường cong mà tại đó điểm cao sẽ xảy ra nếu bạn muốn có một đường cong không đối xứng.

Nhìn vào mã Android cho TranslateAnimation đặc biệt hữu ích.Xem: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.5_r1/android/view/animation/TranslateAnimation.java#TranslateAnimation

public class ArcTranslate extends Animation { 

private Point start; 
private Point end; 
private Point middle; 
private final float mFromXValue; 
private final float mToXValue; 
private final float mYValue; 
private final int mFromXType; 
private final int mToXType; 
private final int mYType; 

/** 
* A translation along an arc defined by three points and a Bezier Curve 
* 
* @param duration - the time in ms it will take for the translation to complete 
* @param fromXType - One of Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT. 
* @param fromXValue - Change in X coordinate to apply at the start of the animation 
* @param toXType - One of Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT. 
* @param toXValue - Change in X coordinate to apply at the end of the animation 
* @param yType - One of Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT. 
* @param yValue - Change in Y coordinate to apply at the middle of the animation (the radius of the arc) 
*/ 
public ArcTranslate(long duration, int fromXType, float fromXValue, 
     int toXType, float toXValue, int yType, float yValue){ 
    setDuration(duration); 

    mFromXValue = fromXValue; 
    mToXValue = toXValue; 
    mYValue = yValue; 

    mFromXType = fromXType; 
    mToXType = toXType; 
    mYType = yType; 

} 

/** Calculate the position on a quadratic bezier curve given three points 
* and the percentage of time passed. 
* from http://en.wikipedia.org/wiki/B%C3%A9zier_curve 
* @param interpolatedTime - the fraction of the duration that has passed where 0<=time<=1 
* @param p0 - a single dimension of the starting point 
* @param p1 - a single dimension of the middle point 
* @param p2 - a single dimension of the ending point 
*/ 
private long calcBezier(float interpolatedTime, float p0, float p1, float p2){ 
    return Math.round((Math.pow((1 - interpolatedTime), 2) * p0) 
      + (2 * (1 - interpolatedTime) * interpolatedTime * p1) 
      + (Math.pow(interpolatedTime, 2) * p2)); 
} 

@Override 
protected void applyTransformation(float interpolatedTime, Transformation t) { 
    float dx = calcBezier(interpolatedTime, start.x, middle.x, end.x); 
    float dy = calcBezier(interpolatedTime, start.y, middle.y, end.y); 

    t.getMatrix().setTranslate(dx, dy); 
} 

@Override 
public void initialize(int width, int height, int parentWidth, int parentHeight) { 
    super.initialize(width, height, parentWidth, parentHeight); 
    float startX = resolveSize(mFromXType, mFromXValue, width, parentWidth); 
    float endX = resolveSize(mToXType, mToXValue, width, parentWidth); 
    float middleY = resolveSize(mYType, mYValue, width, parentWidth); 
    float middleX = startX + ((endX-startX)/2); 
    start = new Point(startX, 0); 
    end = new Point(endX, 0); 
    middle = new Point(middleX, middleY); 
} 
} 
+0

@Monkeyless Cảm ơn bạn rất nhiều vì mã. Tôi đã quản lý hoạt ảnh ảo bằng cách sử dụng mã này. Nhưng tôi đang gặp sự cố khi đặt onClickListener thành một lần xem hình ảnh trong khi nó đang hoạt ảnh. Tôi đã đăng câu hỏi [ở đây] (http://stackoverflow.com/questions/23947114/onclicklistener-not-triggered-during-animation). Hãy giúp tôi. –

0

Bạn có thể tạo lớp riêng của bạn như thế này:

public class BezierTranslateAnimation extends TranslateAnimation { 

private int mFromXType = ABSOLUTE; 
private int mToXType  = ABSOLUTE; 
private int mFromYType = ABSOLUTE; 
private int mToYType  = ABSOLUTE; 
private float mFromXValue = 0.0f; 
private float mToXValue = 0.0f; 
private float mFromYValue = 0.0f; 
private float mToYValue = 0.0f; 
private float mFromXDelta; 
private float mToXDelta; 
private float mFromYDelta; 
private float mToYDelta; 
private float mBezierXDelta; 
private float mBezierYDelta; 

public BezierTranslateAnimation(float fromXDelta, float toXDelta,float fromYDelta, float toYDelta, float bezierXDelta, float bezierYDelta) { 
    super(fromXDelta, toXDelta, fromYDelta, toYDelta); 

     mFromXValue = fromXDelta; 
     mToXValue = toXDelta; 
     mFromYValue = fromYDelta; 
     mToYValue = toYDelta; 
     mFromXType = ABSOLUTE; 
     mToXType = ABSOLUTE; 
     mFromYType = ABSOLUTE; 
     mToYType = ABSOLUTE; 
     mBezierXDelta = bezierXDelta; 
     mBezierYDelta = bezierYDelta; 

} 



@Override 
protected void applyTransformation(float interpolatedTime, Transformation t) { 

    float dx=0,dy=0; 

    if (mFromXValue != mToXValue) { 

     dx = (float) ((1.0-interpolatedTime)*(1.0-interpolatedTime)*mFromXValue + 2.0*interpolatedTime*(1.0-interpolatedTime)*mBezierXDelta + interpolatedTime*interpolatedTime*mToXValue); 
    } 

    if (mFromYValue != mToYValue) { 

     dy = (float) ((1.0-interpolatedTime)*(1.0-interpolatedTime)*mFromYValue + 2.0*interpolatedTime*(1.0-interpolatedTime)*mBezierYDelta + interpolatedTime*interpolatedTime*mToYValue); 
    } 

    t.getMatrix().setTranslate(dx, dy); 

    } 

} 

Sau đó, sử dụng nó với chữ ký này:

BezierTranslateAnimation(float fromXDelta, float toXDelta,float fromYDelta, float toYDelta, float bezierXDelta, float bezierYDelta); 
+0

bạn không sử dụng các loại hình động ... –

5

Nó được lấy cảm hứng từ câu trả lời của Monkeyless. Tôi đã tạo một lớp con của Hoạt ảnh, sử dụng PathMeasure để tính toán bản dịch. Bạn chỉ có thể tạo PathAnimation mới với Đường dẫn và sử dụng nó như bất kỳ Ảnh động nào khác.

https://github.com/coocood/PathAnimation

public class PathAnimation extends Animation { 
private PathMeasure measure; 
private float[] pos = new float[2]; 
public PathAnimation(Path path) { 
    measure = new PathMeasure(path, false); 
} 

@Override 
protected void applyTransformation(float interpolatedTime, Transformation t){ 
    measure.getPosTan(measure.getLength() * interpolatedTime, pos,null); 
    t.getMatrix().setTranslate(pos[0], pos[1]); 
} 
} 
+0

Tôi đã sử dụng Path.addArc() để tạo vòng cung mà tôi muốn Chế độ xem của tôi di chuyển và sau đó là giải pháp này làm hoạt ảnh. Tốt đẹp! – Vaiden

+0

@vaiden, Bạn có thể đăng ví dụ ở đây không? – Geetha

+1

Chỉ cần tạo đối tượng Path và nạp nó vào hàm tạo. Không thực sự là một ví dụ. – Vaiden

Các vấn đề liên quan