Tôi muốn tạo hiệu ứng hình dạng khi nó chuyển từ hình tròn sang hình tam giác góc tròn.Tạo hình tròn CAShapeLayer thành hình tam giác góc tròn
TL; DR: Làm cách nào để tạo ảnh động's path
giữa hai hình CGPath
? Tôi biết rằng họ cần phải có cùng một số điểm kiểm soát, nhưng tôi nghĩ rằng tôi đang làm điều đó - có gì sai với mã này?
Các trạng thái đầu và cuối sẽ giống như thế này: transition http://clrk.it/4vJS+
Đây là những gì tôi đã cố gắng cho đến nay: Tôi đang sử dụng một CAShapeLayer
, và hiệu ứng động một sự thay đổi trong tài sản path
của nó.
Theo (tôi nhấn mạnh) documentation:
Đối tượng con đường có thể được hoạt hình sử dụng bất kỳ lớp con cụ thể của
CAPropertyAnimation
. Đường dẫn sẽ nội suy như một sự pha trộn tuyến tính của các điểm "trên mạng"; Điểm "ngoại tuyến" có thể được nội suy phi tuyến tính (ví dụ: để duy trì tính liên tục của đạo hàm của đường cong). Nếu hai đường dẫn có số điểm hoặc đoạn điều khiển khác nhau thì kết quả sẽ không được xác định.
Để cố gắng thu được hình tròn và hình tam giác có cùng số điểm kiểm soát, tôi đã tạo cho chúng cả hai hình dạng bốn cạnh: hình tròn là hình chữ nhật được làm tròn và tam giác là "ẩn" một điểm kiểm soát thứ tư ở một bên.
Dưới đây là mã của tôi:
self.view.backgroundColor = .blueColor()
//CREATE A CASHAPELAYER
let shape = CAShapeLayer()
shape.frame = CGRect(x: 50, y: 50, width: 200, height: 200)
shape.fillColor = UIColor.redColor().CGColor
self.view.layer.addSublayer(shape)
let bounds = shape.bounds
//CREATE THE SQUIRCLE
let squareRadius: CGFloat = CGRectGetWidth(shape.bounds)/2
let topCorner = CGPointMake(bounds.midX, bounds.minY)
let rightCorner = CGPointMake(bounds.maxX, bounds.midY)
let bottomCorner = CGPointMake(bounds.midX, bounds.maxY)
let leftCorner = CGPointMake(bounds.minX, bounds.midY)
let squarePath = CGPathCreateMutable()
let squareStartingPoint = midPoint(leftCorner, point2: topCorner)
CGPathMoveToPoint(squarePath, nil, squareStartingPoint.x, squareStartingPoint.y)
addArcToPoint(squarePath, aroundPoint: topCorner, onWayToPoint: rightCorner, radius: squareRadius)
addArcToPoint(squarePath, aroundPoint: rightCorner, onWayToPoint: bottomCorner, radius: squareRadius)
addArcToPoint(squarePath, aroundPoint: bottomCorner, onWayToPoint: leftCorner, radius: squareRadius)
addArcToPoint(squarePath, aroundPoint: leftCorner, onWayToPoint: topCorner, radius: squareRadius)
CGPathCloseSubpath(squarePath)
let square = UIBezierPath(CGPath: squarePath)
//CREATE THE (FAKED) TRIANGLE
let triangleRadius: CGFloat = 25.0
let trianglePath = CGPathCreateMutable()
let triangleStartingPoint = midPoint(topCorner, point2: rightCorner)
let startingPoint = midPoint(topCorner, point2: leftCorner)
CGPathMoveToPoint(trianglePath, nil, startingPoint.x, startingPoint.y)
let cheatPoint = midPoint(topCorner, point2:bottomCorner)
addArcToPoint(trianglePath, aroundPoint: topCorner, onWayToPoint: cheatPoint, radius: triangleRadius)
addArcToPoint(trianglePath, aroundPoint: cheatPoint, onWayToPoint: bottomCorner, radius: triangleRadius)
addArcToPoint(trianglePath, aroundPoint: bottomCorner, onWayToPoint: leftCorner, radius: triangleRadius)
addArcToPoint(trianglePath, aroundPoint: leftCorner, onWayToPoint: topCorner, radius: triangleRadius)
CGPathCloseSubpath(trianglePath)
let triangle = UIBezierPath(CGPath: trianglePath)
shape.path = square.CGPath
... và sau này, trong viewDidAppear
:
let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = self.square.CGPath
animation.toValue = self.triangle.CGPath
animation.duration = 3
self.shape.path = self.triangle.CGPath
self.shape.addAnimation(animation, forKey: "animationKey")
Tôi có hai chức năng nhỏ nhanh chóng để làm cho mã dễ đọc hơn:
func addArcToPoint(path: CGMutablePath!, aroundPoint: CGPoint, onWayToPoint: CGPoint, radius: CGFloat) {
CGPathAddArcToPoint(path, nil, aroundPoint.x, aroundPoint.y, onWayToPoint.x, onWayToPoint.y, radius)
}
func midPoint(point1: CGPoint, point2: CGPoint) -> CGPoint {
return CGPointMake((point1.x + point2.x)/2, (point1.y + point2.y)/2)
}
Kết quả hiện tại của tôi trông giống như sau:
LƯU Ý: Tôi đang cố gắng để xây dựng hình tròn ra một hình vuông rất lạ, trong một nỗ lực để có được cùng một số điểm kiểm soát trong hình vector shape. Trong ảnh GIF ở trên, bán kính góc đã được giảm để làm cho phép biến đổi hiển thị rõ hơn.
Bạn nghĩ điều gì đang diễn ra? Làm thế nào tôi có thể đạt được hiệu ứng này?
cố gắng tạo cả hai hình dạng với nhiều đoạn đường thẳng thay thế? – nielsbot
thực sự, bạn có chắc là bạn đang sử dụng addArcToPoint() đúng không? – nielsbot
(Tôi không htink tham số * path * để thêmArcToPoint() thành tùy chọn) – nielsbot