任何人都可以帮助我通过Core Graphics实现这种动画转换。看看草图:
这是一个简单的图表图形,我需要将直方图样式栏(左侧形状)转换为饼图(右侧形状)。 从字面上看,任务是将矩形滚动到具有平滑动画的环。我几乎找到了用一个棘手的绘图队列,掩盖剪辑和仿射变换来做到这一点的方法,但这看起来并不完全是我想要的样子。
答案 0 :(得分:1)
这是一个有趣的挑战,特别是当您想要维护不同的细分时。我不会给你一个完整的答案(即实现这个目的的完整示例代码),但我会解释我认为需要做些什么才能达到你想要的效果。
首先,我将这两个图表视为一条被抚摸的单行(让我们暂时忽略这些段),因此挑战是从一条直线到一个封闭的圆圈。
我建议使用以下两个路径,您可以在它们之间设置动画以实现良好的包装效果。
// As we render a circle as a chain of straight line segments
// changing the count of said segments makes the circle more or less smooth
// Try this with other values, such as 8 or 32
let segments = 72
// With this segment count, the angle of each segment in the circle is
let angle = (2 * CGFloat(M_PI)) / CGFloat(segments)
// First path (straight)
let length = CGFloat(300.0)
let segmentLength = length / CGFloat(segments)
let straightPath = CGPathCreateMutable()
CGPathMoveToPoint(straightPath, nil, 0.0, 0.0)
for i in 0...segments {
CGPathAddLineToPoint(straightPath, nil, 0.0, CGFloat(i) * segmentLength)
}
// Second path (circle)
let radius = CGFloat(100.0)
let center = CGPoint(x: 104.0, y: 104.0)
let space = (x: 2.0, y: 2.0)
var circlePath = CGPathCreateMutable()
CGPathMoveToPoint(circlePath, nil, center.x + radius, center.y)
for i in 0...segments {
let x = cos(-CGFloat(i) * angle)
let y = sin(-CGFloat(i) * angle)
CGPathAddLineToPoint(circlePath, nil, center.x + radius * x, center.y + radius * y)
}
我还上传了一个Swift plaground供你试验,你可以找到here
现在,处理这些段可能有点棘手,但是我提出了一个相对天真的实现可能会起作用。主要是,CAShapeLayer
具有以下两个属性 - strokeStart
和strokeEnd
,它们允许控制实际描边的路径部分。
考虑到这一点,您可以创建与细分一样多的图层,为它们分配所有相同的路径,并调整各自的strokeStart
和strokeEnd
属性,使其看起来像这样你期待。与他们在this post中所做的有些相似。
假设你已经征服了前两个方面,动画方面应该相对简单,使用你拥有的两种类型的路径,你可以创建一个从一个到另一个的简单CABasicAnimation
。我将假设您熟悉CoreAnimation及其用法(即如何正确更改模型值以匹配呈现的那些等。)
我将以快速动画结束我的答案,显示最终结果的样子(减去片段),我已经冻结动画并操纵图层的timeOffset
属性以手动擦除它。
我希望我的回答可以帮助您更接近您想要的解决方案。同样重要的是要强调我的代码示例只是一个开始,你可能需要调整相当多的值来实现令人满意的动画(例如,行的长度应该类似于圆周的长度)圆圈)。
答案 1 :(得分:0)
歪斜,扭曲和弯曲对身体来说都不是微不足道的变形
这些不能完成Core Graphics
。
使用CGContextAddArcToPoint
中的core graphic
更好地绘制图表并屏蔽内圈。
另一种(硬核)方式是使用3D引擎 - 即场景工具包 - 并将图表作为纹理应用于它。