2015-10-05 21 views
8

Tôi quản lý để tạo hoạt ảnh cho một CALayer cùng với UIBezierPath.Làm cách nào để tạo hiệu ứng chỉ một phần trăm hoạt ảnh CALayer đầy đủ dọc theo UIBezierPath?

Điều tôi đang cố gắng hoàn thành là chỉ hoạt ảnh một phần trăm đường dẫn, ví dụ, chỉ 25% đường dẫn, với lớp ở vị trí đó (ở mức 25%).

Cách để thực hiện việc này là gì? Đây là mã của tôi, nó luôn luôn animate đường dẫn đầy đủ.

let aPath = UIBizierPath(CGPath: somePath) 
let anim = CAKeyframeAnimation(keyPath: "position") 
anim.path = aPath.CGPath 
anim.rotationMode = kCAAnimationRotateAuto 
anim.repeatCount = 1 
anim.fillMode = kCAFillModeForwards 
anim.removedOnCompletion = false 
anim.duration = 3.0 
anim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 

ticker.addAnimation(anim, forKey: "animate_ticker") 

Trả lời

2

đơn giản thay đổi một tài sản:

anim.repeatCount = 0.25  

Dưới đây là một excellent article on animation timing, bạn có thể học làm thế nào để có nhiều hơn nữa kiểm soát hạt mịn trên hình ảnh động của bạn.

Nối:
1. Để đạt được những gì bạn muốn, cách gần nhất là có subPath 25%, dưới đây là một số helper method.

2.Nếu bạn có thể chịu được sự khác biệt tốc độ, Sử dụng phương pháp trên, và thiết lập trở lại vị trí khi kết thúc hoạt hình:

ticker.position = ticker.presentationLayer().position 
+1

Vấn đề với điều này là hoạt ảnh sẽ không dừng lại 1/4 theo cách thông qua * đường dẫn *, chỉ có 1/4 đường đi qua * hoạt ảnh *. Do đó với hàm thời gian 'kCAMediaTimingFunctionEaseInEaseOut' và 0,25 cho' repeatCount', hoạt ảnh sẽ ngừng sớm hơn mong đợi. Hơn nữa, chức năng định thời sẽ vẫn được áp dụng cho toàn bộ thời gian hoạt ảnh - và do đó nó sẽ xuất hiện để tăng tốc và sau đó đột nhiên dừng lại, có thể hoặc không thể là những gì OP muốn. – Hamish

+0

@ originaluser2, bạn là chính xác. Tôi thấy các hình ảnh động dừng lại không hoàn hảo, nơi tôi nghĩ rằng nó sẽ, vì vậy điều này giải thích nó! Cảm ơn! Tôi đang tìm 1/4 đường đi, không phải là hoạt hình. –

0

Bạn đã cố gắng thiết lập fromValuetoValue tính? Nó sẽ làm việc nếu bạn thiết lập fromValue để 0.0toValue để 0,25

+1

'fromValue' và' toValue' được giới thiệu trong 'CABasicAnimation' mà không phải là siêu lớp đối với' CAKeyframeAnimation' –

0

Không chỉ CGPath là đục, mà còn CAAnimation không hỗ trợ bất kỳ cập nhật hoặc thông báo cho hình ảnh động liên tục (tức là sau khi bắt đầu nhưng trước khi hoàn thành). Các thực thể duy nhất có liên quan là hoạt ảnh và CALayer -s nó được áp dụng cho.

Vì vậy, tùy chọn là:

(một số tùy chọn có vẻ quá đáng sợ nhưng chúng không phải, vì vậy tôi đã thực hiện một dự án ví dụ, xem dưới đây)

repeatCount

Như wj2061 đề cập là his answer bạn có thể tinh chỉnh hoạt ảnh của repeatCount. Nhược điểm là nó sẽ animate 0,25 thời gian hoạt hình, chứ không phải 0,25 của con đường

CAShapeLayer

Nếu, bởi bất kỳ cơ hội, bạn có thể đại diện cho phân khúc ticker với CAShapeLayer của bạn thì bạn có thể làm động strokeStartstrokeEnd vì vậy nó sẽ trông giống như phân khúc đang chuyển động dọc theo đường

Clever repeatCount

Bạn tính toán như vậy repeatCount thể giá trị mà hoạt hình sẽ ngừng tại 0.25 của con đường.

  • lấy một số bezier lib
  • chiết xuất Bút chì từ chức năng thời gian với getControlPointAtIndex:
  • giải quyết Bút chì để có được "giá trị tiến bộ" của nó (thường là tên t) mà giá trị 'y' Bút chì sẽ phù hợp để bạn "cần thiết tiến bộ" 'x' giá trị (0,25)
  • tính toán Bút chì cho t rằng - đây là giá trị chính xác của repeatCount bạn cần

Anim ating với CAAnimation, tất cả một mình

loại tiên tiến

  • lấy một số bezier lib
  • tạo tùy chỉnh CALayer lớp con với bất động sản năng động, chúng ta hãy nói rideProgress
  • add thuộc tính tổng hợp cho con đường bezier (từ Bút chì lib, không phải CGPath) và lớp con (ví dụ: rideLayer) để tạo ảnh động
  • ghi đè needsDisplayForKey: cho rideProgressinitWithLayer: cho tất cả các thuộc tính được giới thiệu NHƯNG sử dụng self.rideLayer?.presentationLayer() thay vì sao chép rideLayer
  • ghi đè một trong các cách sau: drawInContext: và vẽ những gì bạn cần trong đó; hoặc (tốt hơn) display, trong display truy xuất giá trị rideProgress hiện tại từ presentationLayer và cập nhật lớp con, sau đó gọi siêu. Dù bằng cách nào, sử dụng Bút chì lib để tính toán vị trí và luân chuyển cho lớp con phù hợp với giá trị hiện tại rideProgress
  • đừng quên CATransaction.setDisableActions(true) trước khi thiết lập bất cứ tài sản animatable của bất kỳ lớp
  • cuối cùng, sử dụng bất kỳ loại CAAnimation hoặc hình ảnh động ngầm trên rideProgress tài sản

Chia đường

Một lần nữa, được đề xuất bởi wj2061. Bạn có thể chia con đường để một trong nửa sẽ đại diện cho 0,25 của gốc


Here là ví dụ thực hiện tất cả mọi thứ trên TRỪ "Split path". Tôi đã không chạy bất kỳ bài kiểm tra thực địa trên mã này, nó chỉ là một khái niệm làm việc. XCode 7.3.1, Swift.


Vật liệu sử dụng: Wiki on Cubic function, Great article about operations on beziers, Cubic equations solving method line-by-line

0

tôi đã chạy vào cùng một vấn đề, và tôi muốn animate bản vẽ của một con đường nhưng chỉ có một tỷ lệ phần trăm của nó.

Điều tôi đã làm là đặt strokeStart và stroke của lớp thành các giá trị điểm động giống như hình động.

Vì vậy, trong ví dụ của bạn, hãy thử đặt anim.fromValue = 0.0f, anim.toValue = 0.6f và cũng ticker.strokeStart=0.0fticker.strokeEnd = 0.6f.

Thành công này chỉ vẽ 60% đường dẫn và hoạt ảnh!

+0

Tôi không nhớ lý do chính xác, nhưng điều này không hiệu quả. (Tôi không phải là người downvoted) –

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