2013-08-22 19 views
26

Tôi có một CAShapeLayer có chứa một CGPath. Sử dụng hoạt ảnh tích hợp sẵn trên iOS Tôi có thể dễ dàng biến đường dẫn này thành đường dẫn khác bằng hoạt ảnh:Tweening/Interpolating giữa hai CGPath/UIBeziers

CABasicAnimation *morph = [CABasicAnimation animationWithKeyPath:@"path"]; 
    morph.fromValue = (id)myLayer.path; 
    mayLayer.path = [self getNewPath]; 
    morph.toValue = (id)myLayer.path; 
    morph.duration = 0.3; 
    [myLayer addAnimation:morph forKey:nil]; 

Điều đó hoạt động hoàn hảo.

Tuy nhiên, bây giờ tôi muốn biến đổi dần giữa các đường dẫn này trong quá trình kéo. Để làm được điều này, tôi cần có thể truy xuất đường dẫn nội suy tại bất kỳ thời điểm nào trong quá trình kéo. Có cách nào để yêu cầu iOS cho việc này không?

+0

Trong trường hợp không tầm thường, được xây dựng trong morphing các đường dẫn trở nên vô dụng khá nhanh chóng. Xem vấn đề và giải thích được mô tả ở đây: http://stackoverflow.com/a/17864445/438982 – ipmcc

+0

Đó là sự thật, nhưng trong trường hợp của tôi hình thái có vẻ tốt ... – tarmes

Trả lời

77

Điều này thực sự đơn giản hơn rất nhiều, sau đó bạn sẽ suy nghĩ và sử dụng hoạt ảnh đầu tiên với tốc độ "không" (bị tạm dừng). Bây giờ với hoạt ảnh tạm dừng được thêm vào lớp, bạn có thể thay đổi thời gian bù đắp để chuyển đến một thời điểm cụ thể trong hoạt ảnh.

Nếu bạn không có ý định tự chạy hình động (nghĩa là chỉ điều khiển bằng tay) Tôi khuyên bạn nên thay đổi thời lượng của hoạt ảnh thành 1. Điều này có nghĩa là bạn thay đổi khoảng thời gian từ 0 đến 1 khi di chuyển từ 0% đến 100%. Nếu thời gian của bạn là 0,3 (như trong ví dụ của bạn) thì bạn sẽ đặt thời gian bù đắp cho một giá trị từ 0 đến 0,3.

Triển khai

Như tôi đã nói ở trên, có rất ít mã liên quan đến mẹo nhỏ này.

  1. (Tùy chọn) Đặt thời gian đến 1.0
  2. Đặt speed của lớp (có họ phù hợp với CAMediaTiming) hoặc các hình ảnh động để 0.0
  3. Trong cử chỉ kéo hoặc trượt (như trong ví dụ của tôi) đặt timeOffset của lớp hoặc hoạt ảnh (tùy thuộc vào những gì bạn đã làm trong bước 2).

Đây là cách tôi cấu hình hoạt hình + hình dạng của tôi lớp

CABasicAnimation *morph = [CABasicAnimation animationWithKeyPath:@"path"]; 
morph.duration = 1.; // Step 1 
morph.fromValue = (__bridge id)fromPath; 
morph.toValue = (__bridge id)toPath; 
[self.shapeLayer addAnimation:morph forKey:@"morph shape back and forth"]; 

self.shapeLayer.speed = 0.0; // Step 2 

Và hành động trượt:

- (IBAction)sliderChanged:(UISlider *)sender { 
    self.shapeLayer.timeOffset = sender.value; // Step 3 
} 

Bạn có thể xem kết quả cuối cùng bên dưới. Chúc mừng mã hóa!

enter image description here

+0

Tuyệt vời, cảm ơn bạn. Tôi không có ý tưởng về sự tồn tại của timeOffset. Bạn sẽ làm gì nếu bạn định tự mình sử dụng hoạt hình? – tarmes

+0

@tarmes Tùy thuộc vào chi tiết cụ thể của tương tác. Bạn vẫn có thể tạm dừng hoạt ảnh và thay đổi thời gian bù đắp (trong trường hợp đó từ 0 đến 0,3). Bạn có thể tiếp tục hoạt ảnh bằng cách đặt tốc độ quay lại 1 lần nữa. Nếu hoạt ảnh đang chạy khi bạn muốn tương tác với nó thì bạn có thể lấy giá trị hiện tại bằng cách sử dụng '[layer convertTime: CACurrentMediaTime() fromLayer: nil]'. Xem [câu trả lời này] (http://stackoverflow.com/a/3003922/608157) để biết thêm thông tin. –

+6

Kỹ thuật tuyệt vời này đã truyền cảm hứng cho tôi thực hiện một nút với biểu tượng ► (phát) hoặc ❚❚ (tạm dừng) có hình thái độc đáo giữa hai người. Xem nó trong hành động: http://instagram.com/p/l6a8uDHDk7 Và đây là nguồn: http://gist.github.com/raphaelschaad/9734463 –