我正在尝试将SpriteKit
中的正方形平滑地动画成圆形。
我正在使用带有圆角的SKShape
创建UIBezierPath
。然后,我改变角半径进行动画处理。
我的问题是动画中似乎有一个 jump ,请参见下面的gif。最好使用圆角技术,如何使其变得光滑?
let shape = SKShapeNode()
let l: CGFloat = 100.0
shape.path = UIBezierPath(roundedRect: CGRect(x: -l/2, y: -l/2, width: l, height: l), byRoundingCorners: [.topLeft, .bottomLeft, .topRight, .bottomRight], cornerRadii: CGSize(width: 0, height: 0)).cgPath
shape.position = CGPoint(x: frame.midX, y: frame.midY)
shape.fillColor = .white
addChild(shape)
let action = SKAction.customAction(withDuration: 1) { (node, t) in
let shapeNode = node as! SKShapeNode
shapeNode.path = UIBezierPath(roundedRect: CGRect(x: -l/2, y: -l/2, width: l, height: l), byRoundingCorners: [.topLeft, .bottomLeft, .topRight, .bottomRight], cornerRadii: CGSize(width: t * l / 2, height: 0)).cgPath
}
shape.run(SKAction.repeatForever(action))
要进行调试,我创建了一些形状,它们的拐角半径逐渐增大,如下所示。数字代表角半径与正方形长度的比率。如您所见,在0.3
和0.35
之间有一个跳跃。我看不到我想念的东西。
let cols = 10
let rows = 1
let l: Double = 30.0
let max: Double = l / 2
let delta: Double = l * 2
for i in 0..<rows * cols {
let s = SKShapeNode()
let c: Double = Double(i % cols)
let r: Double = floor(Double(i) / Double(cols))
let pct: Double = Double(i) / (Double(rows) * Double(cols))
let rad = pct * max
s.path = UIBezierPath(roundedRect: CGRect(x: -l/2, y: -l/2, width: l, height: l), byRoundingCorners: [.topRight, .bottomRight, .topLeft, .bottomLeft], cornerRadii: CGSize(width: pct * max, height: pct * max)).cgPath
s.position = CGPoint(x: c * delta - Double(cols) / 2.0 * delta, y: r * delta - Double(rows) / 2.0 * delta)
s.lineWidth = 1.5
s.strokeColor = .white
addChild(s)
let t = SKLabelNode(text: String(format:"%0.2f", rad / l))
t.verticalAlignmentMode = .center
t.horizontalAlignmentMode = .center
t.fontName = "SanFrancisco-Bold"
t.fontSize = 15
t.position = CGPoint(x: 0, y: -delta * 0.66)
s.addChild(t)
}
答案 0 :(得分:1)
您可能无法使用当前的api找到答案。但是您可以自己绘制。
let duration = 10.0
let action = SKAction.customAction(withDuration: duration) { (node, t) in
let shapeNode = node as! SKShapeNode
let path = CGMutablePath()
let borderRadius = l/2 * t / CGFloat(duration);
path.move(to: CGPoint.init(x: -l/2, y: -l/2 + borderRadius));
path.addLine(to: CGPoint.init(x: -l/2, y: l/2 - borderRadius));
path.addArc(tangent1End: CGPoint(x: -l/2, y: l/2), tangent2End: CGPoint(x: -l/2 + borderRadius, y: l/2), radius: borderRadius)
path.addLine(to: CGPoint.init(x: l/2 - borderRadius, y: l/2 ));
path.addArc(tangent1End: CGPoint(x: l/2, y: l/2), tangent2End: CGPoint(x: l/2, y: l/2 - borderRadius), radius: borderRadius)
path.addLine(to: CGPoint.init(x: l/2, y: -l/2 + borderRadius));
path.addArc(tangent1End: CGPoint(x: l/2, y: -l/2), tangent2End: CGPoint(x: l/2 - borderRadius, y: -l/2), radius: borderRadius)
path.addLine(to: CGPoint.init(x: -l/2 + borderRadius, y: -l/2));
path.addArc(tangent1End: CGPoint(x: -l/2, y: -l/2), tangent2End: CGPoint(x: -l/2, y: -l/2 + borderRadius), radius: borderRadius)
path.closeSubpath()
shapeNode.path = path
}
答案 1 :(得分:0)
UIBezierPath.init(roundedRect:cornerRadius:)
的文档指出:
每个角椭圆的半径。值为0会导致没有圆角的矩形。将大于矩形宽度或高度一半的值适当地钳制为宽度或高度的一半。
但是我对此进行了测试,实际上它确实是精确地发生的,其值大于宽度/高度的 1/3 ,而不是一半它的。我正在填写错误报告,希望它能尽快解决。